Как добавить задержку на 30 секунд и выключить светодиод в следующем коде

const int buttonPin =  2;
boolean currentState = LOW;
boolean lastState    = LOW;
boolean stateChange  = false;

int currentButton = 0;
int lastButton    = 4;
int ledArray[]    = {9, 10, 11, 12};
long previousMillis = 0;
long interval = 1000 ;

void setup() {
        pinMode(buttonPin, INPUT);
        for (int i=0; i<5; i++){
            pinMode(ledArray[i],OUTPUT);
        }
        Serial.begin(9600);
}


void loop(){
            currentState = debounceButton();
            stateChange = checkForChange(currentState, lastState);
            currentButton = getButtonNumber(lastButton, currentState, stateChange);
            indicatorLight(currentButton);
            lastState  = currentState;
            lastButton = currentButton;
}


boolean debounceButton()
            {
            boolean firstCheck   = LOW;
            boolean secondCheck  = LOW;
            boolean current = LOW;  
            firstCheck  = digitalRead(buttonPin);
            delay(50);
            secondCheck = digitalRead(buttonPin);  
                    if (firstCheck == secondCheck){
                        current = firstCheck;
                    }
            return current;
}


boolean checkForChange(boolean current, boolean last)
        {
        boolean change;  
                if (current != last){
                    change = true;
                }
                        else {
                        change = false;
                        }  
                return change;
}

int getButtonNumber(int button, boolean state, boolean change)
            { 
            if (change == true && state == LOW){
                button++;
                        if (button > 3){
                        button = 0;
                        }
                        Serial.println("g");
            
            }
            return button;
}



void indicatorLight(int button)
         {
                for (int i=0; i<4; i++) {
                            digitalWrite(ledArray[i], LOW);
                        }
                        digitalWrite(ledArray[button], HIGH);
  }

, 👍1

Обсуждение

Используйте " миллис ()", чтобы зафиксировать отметку времени, когда вы включаете светодиод, затем используйте ее в " цикле ()", чтобы проверить, прошло ли более 30 секунд. В этом заявлении if выключите все светодиоды. Обратитесь к примеру BlinkWithoutDelay, который поставляется с Arduino IDE, @chrisl


1 ответ


1

У вас есть правильная идея отказаться от кнопок, но существует задержка в 50 мс на кнопку, которая блокирует цикл в общей сложности на 200 мс с четырьмя кнопками.

Поэтому подумайте об использовании неблокирующего деблокера, примеров которого в Интернете много, но вот простой деблокер, который я разместил на GitHub. Это может быть реализовано примерно так, как показано в следующем примере:

#include "debouncer.h"

const uint16_t LED_OFF_TIME_DELAY_ms = 2000;  // milliseconds. For testing.
//const uint16_t LED_OFF_TIME_DELAY_ms = 30000;  // milliseconds.

struct ButtonLed
{
  Debouncer button;
  byte button_pin;
  byte led_pin;
};

const ButtonLed BUTTONS_LEDS[] = 
{
  { Debouncer(5, 50, LED_OFF_TIME_DELAY_ms), 5, 11 },
  { Debouncer(4, 50, LED_OFF_TIME_DELAY_ms), 4, 10 },
  { Debouncer(3, 50, LED_OFF_TIME_DELAY_ms), 3, 9 },
  { Debouncer(2, 50, LED_OFF_TIME_DELAY_ms), 2, 8 }
};

void setup()
{
  for (const auto& button_led : BUTTONS_LEDS)
  {
    pinMode(button_led.button_pin, INPUT_PULLUP);
    pinMode(button_led.led_pin, OUTPUT);
    digitalWrite(button_led.led_pin, LOW);
  }
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  uint16_t timestamp = millis();

  //
  // TASK 1: Read the buttons and set their corresponding LEDs.
  //

  for (const auto& button_led : BUTTONS_LEDS)
  {
    button_led.button.Update();
    if (button_led.button.Fall())
    {
      digitalWrite(button_led.led_pin, HIGH);
    }
    else if (button_led.button.RepeatCount() == 1)
    {
      digitalWrite(button_led.led_pin, LOW);
    }
  }

  //
  // TASK 2: Blink the inbuilt LED.
  //

  const uint16_t LED_BLINK_INTERVAL = 100;
  static uint16_t led_blink_previous_timestamp = timestamp;
  static bool led_state = false;
  if (timestamp - led_blink_previous_timestamp >= LED_BLINK_INTERVAL)
  {
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    led_blink_previous_timestamp += LED_BLINK_INTERVAL;
  }
}

И вот он в действии в симуляторе Wokwi:

,