Your code can be structured into parts where each parts is one senseful sub-unit
You have
- switching LEDs off
- switching LEDs ON
- blink LEDs which does repeat switching LEDs off´/switching LEDs ON
You increment a value from 0 until 2 and then set it back to 0
0,1,2,0,1,2,0,1,2,0,1,2...
if the button is pressed. Which shall change the LED-mode
beeing OFF or On or Blinking
So here are the parts of your code
void switchLEDsOff() {
for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
digitalWrite(myLEDPin[Idx], LOW);
}
}
.
void switchLEDsOn() {
for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
digitalWrite(myLEDPin[Idx], HIGH);
}
}
.
void blinkLEDs() {
// check if more time than specified in "myIntervall has passed by
if (TimePeriodIsOver(myBlinkTimer, myIntervall) ) {
// when REALLY more time has passed by
// check if LEDs are OFF by reading IO-state first LED
if (digitalRead(myLEDPin[0]) == LOW) {
switchLEDsOn();
}
else {
switchLEDsOff();
}
}
}
.
// function that gives back values starting from Min
// incrementing to Max and if Max is reached set back to Min
// example IncrementCircular(myVar,0,2)
// results 0,1,2 0,1,2 0,1,2
byte IncrementCircular(byte actualValue, byte Min, byte Max) {
byte Value = actualValue;
if (Value < Min) {
Value = Min;
}
Value = actualValue + 1;
if (Value > Max) {
Value = Min;
}
return Value;
}
.
byte readButton(byte IO_PinNr) {
byte firstButtonRead = digitalRead(IO_PinNr);
delay(50);
byte secondButtonRead = digitalRead(IO_PinNr);
// both readings are the same the bouncing is over
if (firstButtonRead == secondButtonRead) {
return buttonPressed;
}
else {
return buttonReleased;
}
}
here is the complete code
const byte ButtonPin = 2;
const byte myLEDPin[] = {8, 9, 10, 11, 12};
// myLEDPin[0] gives a "8"
// myLEDPin[1] gives a "9"
// myLEDPin[2] gives a "10"
// myLEDPin[3] gives a "11"
// myLEDPin[4] gives a "12"
// calculate No of bytes of complete array / number of bytes of one array-element
const byte NumberOfLEDs = sizeof(myLEDPin) / sizeof(myLEDPin[0]);
const byte buttonPressed = LOW;
const byte buttonReleased = HIGH;
byte buttonState;
byte lastButtonState;
byte mode = 0;
unsigned long myBlinkTimer;
const unsigned long myIntervall = 400;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
pinMode(ButtonPin, INPUT_PULLUP);
for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
pinMode(myLEDPin[Idx], OUTPUT);
Serial.print("configure myLEDPin[");
Serial.print(Idx);
Serial.println("] as OUTPUT");
Serial.print("in fact pinMode(");
Serial.print(myLEDPin[Idx]);
Serial.println(",OUTPUT);");
}
}
void loop() {
buttonState = readButton(ButtonPin);
// check if there is a stateCHANGE
if (lastButtonState != buttonState) {
// when there is REALLY a statechange
lastButtonState = buttonState;
if (buttonState == buttonPressed) {
mode = IncrementCircular(mode, 0, 2);
}
}
switch (mode) {
case 0:
switchLEDsOff();
break; // IMMIDIATEALY jump down to END-OF-SWITCH
case 1:
switchLEDsOn();
break; // IMMIDIATEALY jump down to END-OF-SWITCH
case 2:
blinkLEDs();
break; // IMMIDIATEALY jump down to END-OF-SWITCH
} // END-OF-SWITCH
lastButtonState = buttonState;
}
byte readButton(byte IO_PinNr) {
byte firstButtonRead = digitalRead(IO_PinNr);
delay(50);
byte secondButtonRead = digitalRead(IO_PinNr);
// both readings are the same the bouncing is over
if (firstButtonRead == secondButtonRead) {
return buttonPressed;
}
else {
return buttonReleased;
}
}
// function that gives back values starting from Min
// incrementing to Max and if Max is reached set back to Min
// example IncrementCircular(myVar,0,2)
// results 0,1,2 0,1,2 0,1,2
byte IncrementCircular(byte actualValue, byte Min, byte Max) {
byte Value = actualValue;
if (Value < Min) {
Value = Min;
}
Value = actualValue + 1;
if (Value > Max) {
Value = Min;
}
return Value;
}
void switchLEDsOff() {
for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
digitalWrite(myLEDPin[Idx], LOW);
}
}
void switchLEDsOn() {
for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
digitalWrite(myLEDPin[Idx], HIGH);
}
}
void blinkLEDs() {
// check if more time than specified in "myIntervall has passed by
if (TimePeriodIsOver(myBlinkTimer, myIntervall) ) {
// when REALLY more time has passed by
// check if LEDs are OFF by reading IO-state first LED
if (digitalRead(myLEDPin[0]) == LOW) {
switchLEDsOn();
}
else {
switchLEDsOff();
}
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
best regards Stefan