Непрерывно запускайте функцию световой последовательности в операторе if

Моя цель - запустить функцию последовательного освещения при кратковременном нажатии кнопки (кнопка 2) до тех пор, пока не будет нажата другая из 3 мгновенных кнопок.

 /* переключатель
*
* Каждый раз, когда входной контакт переходит из LOW в HIGH (например, из-за нажатия кнопки
* нажмите), выходной контакт переключается с LOW на HIGH или HIGH на LOW. есть
* минимальная задержка между переключениями для устранения дребезга цепи (т.е. для игнорирования
* шум).
*
* Дэвид А. Меллис
* 21 ноября 2006 г.
*/
 #include "FastLED.h"

int inPin = 8;         // номер входного контакта
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13;       // номер выходного контакта

int state = HIGH;      // текущее состояние выходного вывода
int reading;           // текущее чтение с входного вывода
int readingTwo;
int readingThree;
int previous = LOW;    // предыдущее чтение с входного вывода

int pixelNumber;

// следующие переменные длинные, потому что время, измеряемое в миллисекундах,
// быстро станет большим числом, чем может быть сохранено в int.
long time = 0;         // последний раз, когда выходной пин был переключен
long debounce = 200;   // время устранения дребезга, увеличиваем, если вывод мерцает

//НЕОПИКСЕЛЬ
#define LED_PIN     7
#define LEDPIN 7
#define LED_TYPE     NEOPIXEL
#define NUM_LEDS    2
#define BRIGHTNESS 10
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET     WS2811

bool gReverseDirection = false;
CRGBPalette16 gPal;

void setup()
{


  pinMode(inPin, INPUT);
  pinMode(inPinTwo,INPUT);
  pinMode(inPinThree,INPUT);
  pinMode(outPin, OUTPUT);

  Serial.begin(9600);

  // устанавливаем информацию о светодиодной ленте
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{


// КНОПКА 1 - НЕПРЕРЫВНЫЙ СВЕТ
  reading = digitalRead(inPin);

  // если ввод только что прошел от НИЗКОГО до ВЫСОКОГО, и мы ждали достаточно долго
  // чтобы игнорировать любой шум в цепи, переключите выходной контакт и запомните
  // время
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      fill_solid(leds,NUM_LEDS,CRGB::Black);
      FastLED.show();
    }
    else{
      state = HIGH;
      fill_solid(leds,NUM_LEDS,0xFAF6D1);
      FastLED.show();
      }

    time = millis();    

  }
    digitalWrite(outPin, state);
    previous = reading;

// КНОПКА 2 - БЛЕСТЯЩИЙ СВЕТ
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previous == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
      fadeToBlackBy( leds, NUM_LEDS, 10);
      addGlitter(30);
      FastLED.show();
      }
    else{
      state = HIGH;
      fill_solid(leds,NUM_LEDS,CRGB::Black);
      FastLED.show();
    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previous = readingTwo;


// КНОПКА 3 - СВЕТ ДАТЧИКА ДВИЖЕНИЯ
       readingThree = digitalRead(inPinThree);
  if (readingThree == HIGH && previous == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
       fill_solid(leds,NUM_LEDS,CRGB::Black);
        FastLED.show();
      }
    else{
      state = HIGH;

    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previous = readingThree;
}

//эффект блеска
void addGlitter( fract8 chanceOfGlitter) {
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;}
}

Проблема в том, что функция запускалась только один раз (см. кнопку 2), что не дает нужного эффекта. Я понимаю, что было бы полезно изменить этот оператор if на оператор while, но я не могу понять, как выйти из этого цикла while при нажатии кнопки. Я знаю, что установка state = LOW разорвет цикл while, но если я оставлю его включенным, функция последовательности световых сигналов никогда не запустится.

// КНОПКА 2
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
    while(state == HIGH){
// состояние = НИЗКИЙ;
      fadeToBlackBy( leds, NUM_LEDS, 10);
      addGlitter(30);
      FastLED.show();
  }


    while(state == LOW){
      state = HIGH;

      fill_solid(leds,NUM_LEDS,CRGB::Black);
        FastLED.show();    

    }

Мы будем очень признательны за любую помощь!

, 👍2

Обсуждение

выполнять все операции чтения, устранения дребезга и обработки кнопок в начале блока loop() .... отслеживать текущее состояние и предыдущее состояние (используйте нажатия кнопок для изменения состояния переменные .... запускать блоки управления светодиодами в зависимости от переменных state, @jsotola

Я уже использую нажатия кнопок для изменения переменных состояния и светодиодов в зависимости от них. Может я неправильно понял ваш комментарий?, @MorningStar

читайте комментарий до первого...., @jsotola

в этой грубой идее используется только одна кнопка... кнопка чтения только в начале цикла ()... расширьте ее по своему вкусу, добавив больше кнопок... используйте переменную состояния с 6 состояниями... в настройке state = 1 ... в начале цикла() прочитать кнопку... если она нажата, то увеличить состояние... теперь светодиоды... если состояние==1, запустить код кнопки1... если состояние==2 , запустить код button1.else и установить состояние = 3 ... если состояние == 3, запустить код кнопки 2 ... если состояние == 4, запустить код button2.else и установить состояние = 5 .... аналогично для остальных кодекса, @jsotola

спасибо за расширение вашего комментария jsotola. Буду тестировать и отписываться о прогрессе., @MorningStar


1 ответ


Лучший ответ:

2

Я добавил int btnPress, который устанавливается при каждом нажатии кнопки. Затем оператор if запускается в соответствии с номером btnPress. Спасибо, jsotola, за указание в правильном направлении!

#include "FastLED.h"


int inPin = 8;         // номер входного контакта
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13;       // номер выходного контакта

int state = HIGH;      // текущее состояние выходного вывода

int reading;           // текущее чтение с входного вывода
int readingTwo;
int readingThree;
int previous = LOW;    // предыдущее чтение с входного вывода
int previousTwo = LOW;
int previousThree = LOW;
volatile int change;
int btnPress;

int pixelNumber;  

long time = 0;         // последний раз, когда выходной пин был переключен
long debounce = 200;   // время устранения дребезга, увеличиваем, если вывод мерцает

//НЕОПИКСЕЛЬ
#define LED_PIN     7
#define LEDPIN 7
#define LED_TYPE     NEOPIXEL
#define NUM_LEDS    2
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET     WS2812B


void setup()
{


//КНОПКА
  pinMode(inPin, INPUT);
  pinMode(inPinTwo,INPUT);
  pinMode(inPinThree,INPUT);
  pinMode(outPin, OUTPUT);

  Serial.begin(9600);

  // устанавливаем информацию о светодиодной ленте
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
btnPress = 1;

}

void loop()
{
// КНОПКА 1 - НЕПРЕРЫВНЫЙ СВЕТ
  reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      btnPress = 1;
    }
    else{
      state = HIGH;
      btnPress = 2;
      }

    time = millis();   

  }
    digitalWrite(outPin, state);
    previous = reading;

// КНОПКА 2 - БЛЕСТЯЩИЙ СВЕТ
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
      btnPress = 3;
      }
    else{
      state = HIGH;
      btnPress = 4;
    }
    time = millis();
    }
    digitalWrite(outPin,state);
    previousTwo = readingTwo;


// КНОПКА 3 - СВЕТ ДАТЧИКА ДВИЖЕНИЯ
       readingThree = digitalRead(inPinThree);
  if (readingThree == HIGH && previousThree == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
       btnPress = 5;
      }
    else{
      state = HIGH;
      btnPress = 6;
    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previousThree = readingThree;



    //КНОПКА 1 - НЕПРЕРЫВНЫЙ СВЕТ
     if (btnPress == 1){
          fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();Serial.println("pressed1");
      }

    if (btnPress == 2){
          fill_solid(leds,NUM_LEDS,0xFfffff);
          FastLED.show();Serial.println("pressed2");

      } 

    // КНОПКА 2 - БЛЕСТЯЩИЙ СВЕТ
    if (btnPress == 3){
            fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();Serial.println("pressed3");

      }
    if (btnPress == 4){
         fadeToBlackBy( leds, NUM_LEDS, 10);
          addGlitter(30);Serial.println("pressed4");
          FastLED.show();
      }

    // КНОПКА 3 - СВЕТ ДАТЧИКА ДВИЖЕНИЯ
    if (btnPress == 5){
            fill_solid(leds,NUM_LEDS,CRGB::Black);Serial.println("pressed5");
          FastLED.show();

      }
    if (btnPress == 6){
        Serial.println("pressed6");
      }
  }


//эффект блеска
void addGlitter( fract8 chanceOfGlitter) {
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;}
}
,