Hi Arduino folks,
I wrote a sketch that makes two (or more) LEDs blink a set number of times independantly. I need help cleaning it up, or making it more elegant / less clustered, since I know for a fact that my approach is very immature - especially the part with the state variable.
What I’m trying to do:
For example, for a puzzle in an Escape Room Game I need LED1 to blink 3 times, then 6 times and then 4 times. The gap (800) inbetween these “digits” is twice as long as the interval between the blinks (400). At the end there should be a longer pause (3000), and then it starts from the beginning.
What I was aiming for:
A function that I could use like this.
blink(pin, 3, 6, 4, blinkGap, pauseGap);
Ideally it would work for multiple LEDs, that each blink independantly with their own pattern.
Here’s what I have so far:
(For better readability I deleted the second function for the second LED - it’s just a copy of the first one with different variables ugh)
#define LED1 7
int state1 = 1; // Used to control the steps
unsigned long previousMillis1 = 0;
unsigned long counter1 = 0; // Used to count the number of blinks
void setup() {
Serial.begin(9600);
pinMode(LED1, OUTPUT);
}
void loop() {
blink1(LED1, 3, 6, 4, 400, 800);
}
void blink1(int pin, int num1, int num2, int num3, const long blinkGap, const long pauseGap) {
if (state1 == 1) { // Number 1
if (counter1 < num1 * 2) { // *2 because I'm counting on and off blinks
for (int i = 0; i < num1 * 2; i++) {
if (millis() - previousMillis1 >= blinkGap) {
previousMillis1 = millis();
digitalWrite(pin, !digitalRead(pin));
counter1 += 1;
}
}
} else {
counter1 = 0;
state1 = 2; // Go to pause section
}
}
if (state1 == 2) { // Pause 1
if (millis() - previousMillis1 >= pauseGap) {
previousMillis1 = millis();
state1 = 3; // Go to second "digit"
}
}
if (state1 == 3) { // Number 2
if (counter1 < num2 * 2) {
for (int i = 0; i < num2 * 2; i++) {
if (millis() - previousMillis1 >= blinkGap) {
previousMillis1 = millis();
digitalWrite(pin, !digitalRead(pin));
counter1 += 1;
}
}
} else {
counter1 = 0;
state1 = 4;
}
}
if (state1 == 4) { // Pause 2
if (millis() - previousMillis1 >= pauseGap) {
previousMillis1 = millis();
state1 = 5;
}
}
if (state1 == 5) { // Number 3
if (counter1 < num3 * 2) {
for (int i = 0; i < num3 * 2; i++) {
if (millis() - previousMillis1 >= blinkGap) {
previousMillis1 = millis();
digitalWrite(pin, !digitalRead(pin));
counter1 += 1;
}
}
} else {
counter1 = 0;
state1 = 6;
}
}
if (state1 == 6) { // Pause 3 (long)
if (millis() - previousMillis1 >= 3000) {
previousMillis1 = millis();
state1 = 1;
}
}
}
PROBLEMS
- Right now it only works for one LED, since I need different state, previousMillis and counter variables. I know that just copying and renaming the function would not be the smartest way. What else could I do?
- Is there a way around the if state - structure? I tried a switch too, but essentially it does the same thing.
What I can’t wrap my head around:
How can I control the flow “1st digit, pause, 2nd digit, pause, 3rd digit, long pause” in a non-blocking way? I cannot use while-loops or delay() since I need multiple LEDs blinking independantly.
I appriciate any input or push in the right direction. Please excuse my noob coding, I’ve just started out and am eager to learn how to write better code.