Hi everybody!
I am facing a problem regarding how to blink two leds using the millis() function. I have understood how the function works, but not how to apply it in this case.
The sketch itself has to do something very simple, but I can't wrap my head around this thing.
Essentially,the sketch has to:
-Turn one led on for 5 seconds
-Turn that same led off and wait 3 seconds
-Turn the other led on for 5 seconds
-Turn it off and wait 3 seconds
The cycle then repeats. Think of it as a motor that first rotates in one direction, then pauses for a little, turns in the other direction, pauses again and repeats the cycle over and over again.
The two leds NEVER have to blink together.
If anybody could help me to solve this problem I'd be extremely glad.
Yes I have, but I really don't know where to start.
Could you give me some advice?
Modify the simple "blink without delay" sketch to have a different on and off time for one led.
Declare two new variables --timeOn and timeOff. Then, at the end of the timed interval when the code enters the section to turn the led on or off, set the interval equal to the time you want. The value of interval will be alternating between the timeOff an the timeOn.
Once you get this far, adding the second led will be easy.
The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique, and it blinks 3 LEDs.
Mattia9914:
Yes I have, but I really don't know where to start.
Could you give me some advice?
Here is some code for switching through a 16-second-cycle:
const byte ledPins[] = {2, 3};//declare pin numbers for two LEDs
unsigned long sequenceStartTime;
void setLeds()
{
long time = millis() - sequenceStartTime;
if (time < 5000)
{
digitalWrite(ledPins[0], HIGH); //first LED ON during first 5 seconds in a sequence
digitalWrite(ledPins[1], LOW);
}
else if(time < 8000)
{
digitalWrite(ledPins[0], LOW); //both LEDs OFF until half-time
digitalWrite(ledPins[1], LOW);
}
else if(time < 13000) // second LED ON
{
digitalWrite(ledPins[0], LOW);
digitalWrite(ledPins[1], HIGH);
}
else if(time < 16000) // both LEDs off until end of sequence
{
digitalWrite(ledPins[0], LOW);
digitalWrite(ledPins[1], LOW);
}
else sequenceStartTime = millis(); // each 16 seconds we start a new sequence
}
void setup()
{
Serial.begin(9600);
pinMode(ledPins[0], OUTPUT);
pinMode(ledPins[1], OUTPUT);
}
void loop()
{
setLeds();
}
Thanks jurs for the code! It worked perfectly. However, I am wondering if it is possible to just do a 8 second function and just tell the code to alternate the leds during the pause.
Mattia9914:
Thanks jurs for the code! It worked perfectly. However, I am wondering if it is possible to just do a 8 second function and just tell the code to alternate the leds during the pause.
OK, I'll give it another try, here is the code for using 8-second sequences:
const byte ledPins[] = {2, 3};
unsigned long sequenceStartTime;
byte cycleCount;
void setup()
{
Serial.begin(9600);
pinMode(ledPins[0], OUTPUT);
pinMode(ledPins[1], OUTPUT);
}
void loop()
{
long time = millis() - sequenceStartTime;
if (time < 5000)
digitalWrite(ledPins[bitRead(cycleCount,0)], HIGH); //one of the LEDs ON during first 5 seconds in sequence
else if(time < 8000)
digitalWrite(ledPins[bitRead(cycleCount,0)], LOW); //same LED OFF in the same cycle
else // count up the cycleCount
{
cycleCount++;
sequenceStartTime = millis(); // each 8 seconds we start a new sequence
}
}
That's the way how it should work:
I have a byte counter named cycleCount, which will count up by 1 each 8 seconds.
As it is a byte only, the counter will roll over from 255 to 0 after 256*8=2048 seconds.
The low-bit (0-bit) of the counter will decide which LED is to be switched in this 8-second-cycle.
If the 0-bit "bitRead(cycleCount,0)" is 0 then ledPins[0] will be switched in this cycle.
And if the 0-bit "bitRead(cycleCount,0)" is 1 then ledPins[1] will be switched in this cycle.