Первый светодиод WS2812B начинает светиться, когда код входит в цикл for - PullRequest
0 голосов
/ 11 апреля 2020

Я работаю над этим проектом, это должно быть освещение для навеса для машины. Есть два способа включить свет, через датчик движения или через выключатель. Светодиодная полоска начинает включаться один светодиод за другим. Он будет оставаться включенным в течение некоторого времени, а затем начнется обратная анимация, и все светодиоды станут черными. Я использую для l oop для этой анимации (это то же самое, что FastLed использует в первом легком примере). Ошибка только в том случае, если датчик движения активирован, и в то время как for l oop работает. Я прошу прощения за плохие целые имена, может быть запутанным. Большое спасибо!

Вот код: (Если вы не понимаете по-немецки, - Bewegungsmelder = Датчик движения - Schalter = Переключатель


// für die Leds
#define NUMfront_LEDS 150 //150 Leds
#define NUMinner_LEDS 35 //35 Leds
#define rightPIN 6 //Pin 6
#define leftPIN 5
#define innerrightPIN 8
#define innerleftPIN 7

#define CLOCK_PIN 13

// für die Schalter
#define schalter 2 //Pin 2
#define Bewegungsmelder 4 //Pin 4

int schalterval = 0;
int Bewegungsval = 0;
long Time = 0;
long Wait = 900000;
int On = 0;

CRGB leftLeds[NUMfront_LEDS];
CRGB rightLeds[NUMfront_LEDS];
CRGB innerleftLeds[NUMinner_LEDS];
CRGB innerrightLeds[NUMinner_LEDS];


void setup() {
  // sanity check delay - allows reprogramming if accidently blowing power w/leds
  Serial.begin(115200);
  delay(2000);
  FastLED.addLeds<WS2812B, rightPIN, RGB>(rightLeds, NUMfront_LEDS);  // GRB ordering is typical
  FastLED.addLeds<WS2812B, leftPIN, RGB>(leftLeds, NUMfront_LEDS);
  FastLED.addLeds<WS2812B, innerrightPIN, RGB>(innerrightLeds, NUMinner_LEDS);
  FastLED.addLeds<WS2812B, innerleftPIN, RGB>(innerleftLeds, NUMinner_LEDS);
Time = millis();
}

void loop() {
  Serial.println("----------------------------------------------");
  Serial.print(Wait);
  Serial.print("----");
  Serial.print(millis());
  Bewegungsval = digitalRead(Bewegungsmelder);
  schalterval = digitalRead(schalter);
  Serial.println(Bewegungsval);
  Serial.println(schalterval);
  Serial.println("Space");
Schalter:

  if (digitalRead(schalter) == 1) {
    On = 0;
for (int blackLed = NUMfront_LEDS; blackLed > -1; blackLed = blackLed - 1) {
      leftLeds[blackLed] = CRGB::White;
      rightLeds[blackLed] = CRGB::White;
      delay(19);
      FastLED.show();
    }
    // Carport innen
    fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::White);
    fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::White);
    //Leds aus
    //Carport aussen



    while (digitalRead(schalter) == 1) {
    }
    for (int whiteLed = 0; whiteLed < NUMfront_LEDS; whiteLed = whiteLed + 1) {
      leftLeds[whiteLed] = CRGB::Black;
      rightLeds[whiteLed] = CRGB::Black;
      delay(19);
      FastLED.show();
    }
    // Carport innen
    fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::Black);
    fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::Black);
    FastLED.show();
  }



  else if (Bewegungsval == 1) {
    //Carport aussen
    if (On == 1) {
      goto Skip;
    }
    for (int blackLed = NUMfront_LEDS; blackLed > -1; blackLed = blackLed - 1) {
      leftLeds[blackLed] = CRGB::White;
      rightLeds[blackLed] = CRGB::White;
      delay(19);
      FastLED.show();
    }
    // Carport innen
    fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::White);
    fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::White);
     FastLED.show();
    //Leds aus
    On = 1;
Skip:
    Time = millis();
    Wait = Time + 10000; // + 5min. 300000
    Bewegungsval = digitalRead(Bewegungsmelder);
    goto Schalter;
  }

   Time = millis();
  if (Time  >=  Wait) {

    On = 0;
    for (int whiteLed = 0; whiteLed < NUMfront_LEDS; whiteLed = whiteLed + 1) {
      leftLeds[whiteLed] = CRGB::Black;
      rightLeds[whiteLed] = CRGB::Black;
      delay(19);
      FastLED.show();
    }
    // Carport innen
    fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::Black);
    fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::Black);
  }

}```

1 Ответ

0 голосов
/ 11 апреля 2020

Несмотря на свободное владение немецким языком, структура программы немного хаотична c. Поскольку мы находимся в C ++

  • , вы не должны использовать goto
  • Поскольку, насколько я понимаю, процедуры освещения для коммутатора и IR одинаковы, этот код должен существовать только один раз
  • Ваша процедура измерения времени не является безопасной при опрокидывании, см. Пример blinkwithoutdelay, как сделать

Так что очистите код, используя следующую структуру:

 unsigned long startTime = 0;
 unsigned long myTimer = 10000;// 10 sec
 bool lightIsOn = false;

setup(){....}

loop(){
....
// We check wether switch or IR are triggerd AND we are not already in a light sequence
 if ((digitalRead(schalter) == 1 || Bewegungsval == 1) && lightIsOn == false) { 
    lightIsOn = true;   // change state so we know that a light sequence is running
    startTime = millis(); // reset the timer
 }
  // this part runs as long lighIsOn == true and time is not up
 if(millis() - startTime <= myTimer && lighIsOn == true){
// Carport aussen
your light sequence .....
}
// Here we run the time is up sequence 
if(millis() - startTime > myTimer && lighIsOn == true) {   // rollover safe
  light sequence for time is up
 ........
  lightIsOn = false;   // change state so we know that a light sequence is over
 }
}

Этот метод называется конечным состоянием машины нет, "прыгаю" через гото. Если вам нужно больше состояний, вы просто расширяете последовательность
- другого больше нет, потому что, например, в последних двух объединенных операторах if мы проверяем lightIsON == true ==> else будет означать lightIsON == false во втором, что здесь не имеет смысла, поскольку мы дифференцируем их только по состояниям по времени.
Пожалуйста, никогда не используйте goto в объектно-ориентированном программировании, это делает ваш код нечитаемым и недоступным для отслеживания. Перепишите программу и, если появятся «новые» проблемы, отредактируйте здесь или откройте новый вопрос

...