Hello
I surfed in my sketch box and I´ve found a similar sketch. Below you will find a modified sketch to your needs. I´m using logical groups for a timer, leds and for the button. All in all I´m using a switch/case based FSM too. Check it out and make the neccessay changes for your project.
/* BLOCK COMMENT
ATTENTION: This Sketch contains elements of C++.
https://www.learncpp.com/cpp-tutorial/
https://forum.arduino.cc/t/two-leds-blink-with-one-button/923427
*/
#define ProjectName "Two leds blink with one button"
// HARDWARE AND TIMER SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr byte ButtonPin {A0}; // portPin o---|button|---GND
constexpr byte LedRedPin {3}; // portPin o---|220|---|LED|---GND
constexpr byte LedGreenPin {5}; // portPin o---|220|---|LED|---GND
unsigned long BlinkDuration {200}; // time in msec
//#define OutPutTest
// CONSTANT DEFINITION
enum {Button_};
enum {LedRed, LedGreen};
constexpr byte Input_[] {ButtonPin};
constexpr byte Output_[] {LedRedPin, LedGreenPin};
constexpr unsigned long OutPutTestTime {1000};
constexpr unsigned long DebounceTime {20};
enum {Idle, Blink, RedLed, GreenLed, MaxState};
bool switchCase = false;
String CaseText[] = {"Idle", "Blink", "RedLed", "GreenLed"};
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct TIMER { // has the following members
unsigned long duration; // memory for interval time
unsigned long stamp; // memory for actual time
bool control_; // control for start/stop
bool repeat_; // control for blinking
};
TIMER blink_{BlinkDuration, 0, true, true};
struct BUTTON {
byte pin;
bool statusQuo;
int counter;
TIMER timer;
} buttons[] {
{Input_[Button_], false, 0, DebounceTime, 0, true, true},
};
// USER FUNCTIONS
void startTimer(TIMER &timer) {
timer.control_ = true;
timer.stamp = currentTime;
}
bool checkTimer(TIMER & time_) { // generic time handler using TIME struct
if (currentTime - time_.stamp >= time_.duration && time_.control_) {
if (time_.repeat_) time_.stamp = currentTime;
else time_.control_ = false;
return true;
} else return false;
}
// -------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println(F("."));
Serial.print(F("File : ")), Serial.println(__FILE__);
Serial.print(F("Date : ")), Serial.println(__DATE__);
Serial.print(F("Project: ")), Serial.println(ProjectName);
pinMode (LED_BUILTIN, OUTPUT); // used as heartbeat indicator
// https://www.learncpp.com/cpp-tutorial/for-each-loops/
for (auto Input : Input_) pinMode(Input, INPUT_PULLUP);
for (auto Output : Output_) pinMode(Output, OUTPUT);
#ifdef OutPutTest
// check outputs
for (auto Output : Output_) digitalWrite(Output, HIGH), delay(OutPutTestTime);
for (auto Output : Output_) digitalWrite(Output, LOW), delay(OutPutTestTime);
#endif
}
void loop () {
currentTime = millis();
digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
if (checkTimer(buttons[Button_].timer)) {
bool stateNew = !digitalRead(buttons[Button_].pin);
if (buttons[Button_].statusQuo != stateNew) {
buttons[Button_].statusQuo = stateNew;
buttons[Button_].counter++;
buttons[Button_].counter = buttons[Button_].counter % MaxState;
if ( buttons[Button_].counter == Blink) {
startTimer(blink_);
digitalWrite(Output_[LedRed], HIGH);
}
Serial.println(CaseText[buttons[Button_].counter]);
}
}
switch (buttons[Button_].counter) {
case Idle:
for (auto LED : Output_) digitalWrite(LED, LOW);
break;
case Blink:
if (checkTimer(blink_)) {
digitalWrite(Output_[LedRed], !digitalRead(Output_[LedRed]));
digitalWrite(Output_[LedGreen], !digitalRead(Output_[LedGreen]));
}
break;
case RedLed:
digitalWrite(Output_[LedRed], HIGH);
digitalWrite(Output_[LedGreen], LOW);
break;
case GreenLed:
digitalWrite(Output_[LedRed], LOW);
digitalWrite(Output_[LedGreen], HIGH);
break;
}
}
Have a nice day and enjoy coding in C++.