Hi, I'm trying to program a sequence where LEDs come on and off separately (sometimes they are on, well appear to be on, at the same time) for different lengths of time. I have found a sketch using Millis but I would like to have more than one time value for each LED, can I do this using an array? I've tried redefining const unsigned long greenLEDinterval = 500 as const unsigned greenLEDinterval[3] = {500,1000,2000} but it's not working... I would also like to be able to adjust the time that the LED is off, could this also be programmed using an array in the unsigned long greenLEDtimer value?
Thanks
study blink without delay so that you understand how this works.
then it's just a matter of duplicating this for multiple LEDs. and you could of course use an array, but you have to use it the right way
➜ https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
struct LEDType {
unsigned long LastMillis = 0;
unsigned long interval = 500;
boolean isOn = false;
boolean lastState = false;
int Pin;
};
const int NoOfLEDs = 5;
LEDType LED[NoOfLEDs];
boolean StateHasChanged = false;
void BlinkLedNo(int No){
if (millis() - LED[No].LastMillis > LED[No].interval){
LED[No].LastMillis = millis();
LED[No].isOn = !LED[No].isOn;
digitalWrite(LED[No].Pin,LED[No].isOn);
StateHasChanged = true;
}
}
void BlinkLEDs(){
for (int i = 0; i < NoOfLEDs; i++){BlinkLedNo(i);}
}
void PrintSerial(){
for (int i = 0; i < NoOfLEDs; i++){
if (LED[i].isOn) Serial.print("1");
else Serial.print("0");
}
Serial.println();
StateHasChanged = false;
}
void setup() {
Serial.begin(115200);
// Just a quick initialization
for (int i = 0; i <NoOfLEDs;i++ ) {
LED[i].interval = 300*(i+1);
LED[i].Pin = 9+i; // Do this only in this case as 9 + 4 = 13 !!!
pinMode(LED[i].Pin,OUTPUT);
}
}
void loop() {
BlinkLEDs();
if (StateHasChanged) PrintSerial();
}
There is some "overhead" in thies sketch e.g. to print the LED states to Serial; you can leave this away. I also initialize the Leds by a for-loop() which should be solved differently in a real application. There is another additional concept too, which I will post a little bit later
Do you always want to control the sequences so they run the same?
Then good news, you can store loads of sequence values as binary data in flash (program memory space also stores constant data).
I simplify the job, for 1 led on at a time I can run delays unless I want a start/stop button as well. So don't block/delay to leave that open.
For each led I need data; pin, ontime, offtime.
For the sequence, an array of led numbers to blink and an index to the array will do.
I need 1 start time unsigned long.
My state machine only needs to
case 0: read the next-or-first led number to blink, turn the pin on, start time = millis, set state to 1.
case 1: if (now - start time >= ontime) then turn the pin off, start time = millis, set state to 2.
case 2: if (now - start time >= offtime) then if the sequence is over... start over? if not, set state to 0.
To learn more, write your own small sketch and use it a bit, see what it does and
write a better version knowing what the first try showed you.
Arduino void loop() runs again and again. Functions inside of that main loop start again and again, mostly just to see no change and return but sometimes a step of work is done at 10's of 1000's of steps per second.
When you treat inputs as unpredictable, you code may handle unexpected events.
Millis code lets you sense and set up over-time events. Serial IO deals with communication events and you have pin status change events as well as times.
Play with the idea of event-driven code in a main loop as an approach to automation.