Science 7 - LAND and SEA BREEZE and its Characteristics
Arduino
1. Arduino - multiple LEDs with differentdelays
muteprint Mar 4, 2013 1:56 AM
Hi all
I'm tryingto write code to get 3 LEDs flashing independently, each with a different ON and OFF
period.
For example:
LED1: ON for 25 ms, OFF for 500 ms
LED2: ON for 50 ms, OFF for 800 ms
LED3: ON fo 100 ms, OFF for 300 ms
So far I have set up the hardware: 3 LEDs on digital pins6, 7 and 8 using myArduino UNOboard and
a breadboard.
Code-wise I understand that I can't use the "delay" function because it causes the whole system to
delayi.e. causes 'blocking'. At the moment I'm using the millis() function. My problem is that at the
moment my code causes LED1 to turn ON for 25 ms and off for 25 ms, LED2 turnsON for 50 ms and
off for 50 ms etc. So I need to somehow alter the OFF period independently.
In summary: I need a new approach or an alteration to my code to be able to independentlychange
the ON and OFF periods for each of myLEDs independently.
Here is my code so far:
[code]
// Which pins are connected to which LED
const byte LED1 = 6;
const byte LED2 = 7;
const byte LED3 = 8;
// Assigningdelays.
const unsigned long LED1_interval = 25;
const unsigned long LED2_interval = 50;
const unsigned long LED3_interval = 100;
// Declaringthe variablesholdingthe timer values for each LED.
unsigned long LED1_timer;
unsigned long LED2_timer;
unsigned long LED3_timer;
// Setting3 digital pinsas output pins and resettingtimer
void setup ()
{
pinMode (LED1, OUTPUT);
pinMode (LED2, OUTPUT);
2. pinMode (LED3, OUTPUT);
LED1_timer = millis();
LED2_timer = millis();
LED3_timer = millis();
} // end of setup
//LED1 loop that turnsit ON if it is OFF and vice versa
void toggle_LED1 ()
{
if (digitalRead (LED1) == LOW)
digitalWrite (LED1, HIGH);
else
digitalWrite (LED1, LOW);
// remember when we toggled it
LED1_timer = millis();
} // end of toggleLED_1
//LED2 loop
void toggle_LED2 ()
{
if (digitalRead (LED2) == LOW)
digitalWrite (LED2, HIGH);
else
digitalWrite (LED2, LOW);
// remember when we toggled it
LED2_timer = millis();
} // end of toggle_LED2
//LED 3 loop
void toggle_LED3 ()
{
if (digitalRead (LED3) == LOW)
digitalWrite (LED3, HIGH);
else
digitalWrite (LED3, LOW);
// remember when we toggled it
LED3_timer = millis();
} // end of toggle_LED3
void loop ()
{
// Handlingthe blink of LED1.
if ( (millis() - LED1_timer)>= LED1_interval)
toggle_LED1 ();
3. // Handlingthe blink of LED2.
if ( (millis() - LED2_timer)>= LED2_interval)
toggle_LED2 ();
// Handlingthe blinkof LED3.
if ( (millis() - LED3_timer)>= LED3_interval)
toggle_LED3 ();
/* Other code that needsto execute goes here.
It will be called manythousand timesper second because the above code
does not wait for the LED blinkinterval to finish. */
} // end of loop
[/code]
Any help would be greatlyappreciated because I'm [b]very[/b]new to this!
Thanks!
I have the same question (0)
24908 Views
Tags:
Reply
Re: Arduino - multiple LEDs with different delays
billabott Mar 4, 2013 7:29 AM (inresponseto muteprint)
Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3).
Official Arduino.cc Example
int pin = 13;
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE); //0 is digtal pin 2
}
void loop()
{
digitalWrite(pin, state);
}
void blink()
{
state = !state;
}
4. Observing that all your time factors are multiples of 25 ms, I would suggest
that you usea digital pin on your UNOto initiate a self generated external
interrupt.
Addingcode: const byte iSignal =9;
Addingphysical wire/resister+LED/cap. between pins 9 and 2.
Here is the guts of it: pin 9 is pulsed every 25 msby your loop(), the
iHandler() bumps a counter, the main loop() has a case statement that
allows the required LED transistion actions to take place dependingon the
counter valueonly when old_counter is not equal to counter.
0 <= counter <= 32 (because 800/25=32), resetcounter to 0 after 32
interrupts have occurred. (I am not sureif you want to countto 32 or 31.)
To make the implementation easier(reliable) change
LED1: ON for 25 ms,OFF for 500 ms
LED2: ON for 50 ms,OFF for 800 ms
to
LED1: ON for 25 ms,OFF for 450 ms
LED2: ON for 50 ms,OFF for 750 ms
FYI: http://arduino.cc/en/Reference/AttachInterrupt
Then again, you could just call the iHandler directly withoutthe external
interrupt - but what fun would that be?
o Like (0)
o Reply
o Actions
o Re: Arduino - multiple LEDs with different delays
muteprint Mar 4, 2013 7:00 AM (inresponseto billabott)
Thank you very much for replyingso quicklybillabot. Unfortunately there will be times when I need
to LED to flash 3 timesa second i.e. with an interval of 333ms, so not everythingwill be divisble by
25. Is your method adaptable to any value?
I've been working on thistonight and made a few alterationsto my code. I thinkI'm going in the
right direction with the method I've chosen.
• Defined seperate ON and OFF intervalsfor each LED
• Adapted my loops to use both the OFF and ON intervals.
5. Unfortunately I've ended gettingmyself reallyconfused and now myLEDs seem to sometimesflash
the OFF interval, sometimeswith the ON and sometimeswith a combination of the both.
Any idea how I've gone so badlywrong?
I hope I'm slowly moving in the right direction. If not I might have to try a different approach like
usingthe interupt function. I am very new to the Arduino and writingcode of any sort, so that
approach seems quite dauntingto me.
Below is myaltered code.
[code]
//DEFINING CONSTANTS& VARIABLES
// Which pinsare connected to which LED
const byte LED1 = 6;
const byte LED2 = 7;
const byte LED3 = 8;
// AssigningON and OFF interval constants.
const unsigned long LED1_ON_interval = 3000; //
const unsigned long LED1_OFF_interval = 6000;
const unsigned long LED2_ON_interval = 500; //
const unsigned long LED2_OFF_interval = 1000;
const unsigned long LED3_ON_interval = 100; //
const unsigned long LED3_OFF_interval = 3000;
// Declaringthe variablesholdingthe timer value, i.e. time of last state change.
unsigned long LED1_statechange_Timei;
unsigned long LED2_statechange_Timei;
unsigned long LED3_statechange_Timei;
unsigned long LED1_statechange_Timeii;
unsigned long LED2_statechange_Timeii;
unsigned long LED3_statechange_Timeii;
//SETUP
// Setting3 digital pinsas LED output pins and startingmillisecond timer
void setup ()
{
pinMode (LED1, OUTPUT);
pinMode (LED2, OUTPUT);
pinMode (LED3, OUTPUT);
LED1_statechange_Timei= millis();
LED2_statechange_Timei= millis();
LED3_statechange_Timei= millis();
} // end of setup
6. //LOOPS 1
// LED1 loop that turns LEDON if it is OFF
void toggle_LED1i ()
{
if (digitalRead (LED1) == LOW)
digitalWrite (LED1, HIGH);
LED1_statechange_Timei= millis(); // Remember when LED1'sstate waschanged from ON to
OFF
} // End of toggle_LED1i
// LED1 loop that turns LEDOFF if it is ON
void toggle_LED1ii ()
{
if (digitalRead (LED1)== HIGH);
digitalWrite (LED1, LOW);
LED1_statechange_Timei= millis(); // Remember when LED1'sstate waschanged from OFF to
ON
} // End of toggle_LED1ii
// LED2 loop that turns LEDON if it is OFF
void toggle_LED2i ()
{
if (digitalRead (LED2) == LOW)
digitalWrite (LED2, HIGH);
LED2_statechange_Timeii= millis(); // Remember when LED2'sstate was changed from ON to
OFF
} // End of toggle_LED2i
// LED2 loop that turns LEDOFF if it is ON
void toggle_LED2ii ()
{
if (digitalRead (LED2)== HIGH);
digitalWrite (LED2, LOW);
LED2_statechange_Timeii= millis(); // Remember when LED2'sstate waschanged from OFF to
ON
} // End of toggle_LED2ii
7. // LED3 loop that turns LEDON if it is OFF
void toggle_LED3i ()
{
if (digitalRead (LED3) == LOW)
digitalWrite (LED3, HIGH);
LED3_statechange_Timei= millis(); // Remember when LED3'sstate waschanged from ON to
OFF
} // End of toggle_LED2i
// LED3 loop that turns LEDOFF if it is ON
void toggle_LED3ii ()
{
if (digitalRead (LED3)== HIGH);
digitalWrite (LED3, LOW);
LED3_statechange_Timeii= millis(); // Remember when LED3'sstate waschanged from OFF to
ON
} // End of toggle_LED3ii
//LOOPS 2
void loop () // Start of loop
{
//LED 1
// If the time since the last change in state from OFF to ON is equal or greater than the ON
interval
//then run the loop toggle_LED1i
if ( (millis() - LED1_statechange_Timei)>= LED1_ON_interval)
toggle_LED1i ();
// If the time since the last change in state from ON to OFF is equal or greater than the OFF
interval
//then run the loop toggle_LED1ii
if ( (millis() - LED1_statechange_Timeii)>= LED1_OFF_interval)
toggle_LED1ii ();
//LED 2
// If the time since the last change in state from OFF to ON is equal or greater than the ON
interval
//then run the loop toggle_LED2i
if ( (millis() - LED2_statechange_Timei)>= LED2_ON_interval)
toggle_LED2i ();
// If the time since the last change in state from ON to OFF is equal or greater than the OFF
interval
//then run the loop toggle_LED2ii
8. if ( (millis() - LED2_statechange_Timeii)>= LED2_OFF_interval)
toggle_LED2ii ();
//LED 3
// If the time since the last change in state from OFF to ON is equal or greater than the ON
interval
//then run the loop toggle_LED3i
if ( (millis() - LED3_statechange_Timei)>= LED3_ON_interval)
toggle_LED3i ();
// If the time since the last change in state from ON to OFF is equal or greater than the OFF
interval
//then run the loop toggle_LED2ii
if ( (millis() - LED3_statechange_Timeii)>= LED3_OFF_interval)
toggle_LED3ii ();
} // End of loop
[/code]
Thanks!
Like (0)
Reply
Actions
Re: Arduino - multiple LEDs with different delays
billabott Mar 7, 2013 1:15 PM (in responseto muteprint)
Sorry, no, I am out of ideas. I will, however, share with you that there are other uC that have multiple
timerson board that can be configured to generate interruptsat anypredetermined interval.
Q: Just out of curiosity, what exactlycontrols the periodicityof your LEDs?
Or in other words; "What isyour application, eh?"
You might simplify your program by adoptinga more conventional approach by using
boolean LED1_state = false; // place these very near the top of script so their scopes are GLOBAL
boolean LED2_state = false;
boolean LED3_state = false;
If time to turn off LED1
Set LED1_on_timer to milles()+800; // turningoff; so it is known when to turn it on again.
toggle_LED(&LED1, &LED1_state); // call function to toggle LED between 1 and 0
Set LED1_off_timer to milles() +2048; // presumeablywill be reset to a correct value
// after turningLED1 on prior to the expiration of this value
else if time to turn on LED1
Set LED1_off_timer to milles() +50; // turningon; so it is known when to turn it off again.
toggle_LED(&LED1, &LED1_state);; // call function to toggle LED between 0 and 1
Set LED1_on_timer to milles()+2048; // presumeablywill be reset to a correct value
// after turningLED1 off prior to the expiration of this value
9. void toggle_LED(int *LEDxP, boolean *LEDxP_state) // will need ONLY this one function to toggle ANY LED
since pointers are used
{
digitalWrite (*LEDxP, (*LEDxP_state = !(*LEDxP_state))); // see note below
} // End of toggle_LED
note: According to http://arduino.cc/en/Reference/BooleanVariables
digitalWrite does accept boolean arg of true/false in lieu of HIGH/LOW arg.
Message was edited by: William Bottger
Like (0)
Reply
Actions
Re: Arduino - multiple LEDs with different delays
coder27 Mar 5, 2013 12:47 AM (inresponse to billabott)
Even with using only one timer, you may be able to do somethinglike this:
You have 6 eventsto schedule (turningeach of 3 LED's On and Off).
For each event, you need to store 4 fields: which LED, On vs. Off,
the time-of-daythe event should be taken next, and the amount of time
between events. For LED1, the time between eventswould be 525 ms.
You can store these 6 events in an array. (They don't have to be sorted
in any particular order.) It may help to thinkof thisarray as the "delay-queue"
of a task scheduler.
Then you can write a function that will scan this arrayand find the event with the
soonest next time-of-day. Set an interrupt timer for that time-of-day. While
waitingfor the timer, any work can be going on. When the timer goes off,
turn the specified LED On or Off, and update the next time-of-dayfield by adding
the specified time between eventsfor that LED. Loop back and scan the array
again to find the next soonest event.
Like (0)
Reply
Actions
Re: Arduino - multiple LEDs with different delays
coder27 Mar 12, 2013 3:04 PM (inresponseto muteprint)
Hi muteprint,
I looked a little closer at your code, and see a few problems:
In toggle_LED1ii()
you have:
LED1_statechange_Timei= millis (); // Remember when LED1'sstate was changed from OFF to
ON
but that should be Timeii (two i's).
Similarly, in toggle_LED2i ()
you have:
10. LED2_statechange_Timeii= millis(); // Remember when LED2'sstate was changed from ON to
OFF
but that should be Timei (one i).
Also, in setup(), I think you need to initialize the Timeii statechange variables, in order to prevent
referring
to random valuesin the loops.
Billabott is probablyright that by usingpointers you can condense the code, but I haven't
looked at that closely, and I thinkyou probablywant to get it working first, and then improve it later.
Like (0)
Reply
Actions
Re: Arduino - multiple LEDs with different delays
billabott Mar 7, 2013 12:47 PM (in responseto muteprint)
unsigned long Timer // "ALWAYSuse unsigned long for timers, not int"
// (variable declaration outside setup and loop, of course)
// makes the Timer var GLOBAL in scope
That is good advice from http://playground.arduino.cc/Code/AvoidDelay
Please check out mymodified code above for pointer ref. & deref. usage!
Code in previouspost updated based on the following experiment which does compile and run
correctly!
boolean ON = HIGH;
boolean OFF = LOW;
boolean led1 = ON;
void setup()
{ //led1 = OFF;
pinMode(13, OUTPUT);
}
void loop()
{ test(&led1);
digitalWrite(13, led1);
delay(1500);
}
void test(boolean *varLED)
{ *varLED= !(*varLED);
}
This Arduinosketch was programmed byWilliam A T Bottger.
Message was edited by: William A T Bottger