Function for multiple blinking led

I need help, i'm trying to blink multiple leds with one simple function within the .pde. Timer only, no delay.
I want two states for each led, millis ON and millis OFF. The code i did is not working like it suppose to.

void flashled(int ledpin, int ledON, int ledOFF)

I tried with an array and it did not work well either. Must be a simple way to get this works.

Thanks.

long time = 0;
long timeON = 0;
long timeOFF = 0;
int state = LOW;

void setup()
{
Serial.begin(38400);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
}

void loop()
{
flashled(10, 1000, 500);
flashled(11, 500, 1000);
flashled(12, 500, 500);
}

void flashled(int ledpin, int ledON, int ledOFF) {
time = millis();
if (state == HIGH) {
if (time >= timeOFF) {
state = LOW;
//Serial.print(state);
digitalWrite(ledpin, state);
timeON = timeOFF + ledOFF;
}
}
else {
if (state == LOW){
if (time >= timeON) {
timeON = millis();
state = HIGH;
//Serial.print(state);
digitalWrite(ledpin, state);
timeOFF = timeON + ledON;
}
}
}
}

You haven't said what it is you expect it to do.
If you want the LEDs to blink at the same time, but at different rates, this approach isn't going to work, because "flashled" is being called sequentially.

It should be fairly easy to get what you want by combining two of AlphaBeta's libraries...

http://www.arduino.cc/playground/Code/LED
http://www.arduino.cc/playground/Code/TimedAction

  • Brian

The leds will start at different time in the program.
My loop() should look like this :

void loop()
{
flashled(10, 1000, 500);
{some code here...}
flashled(11, 500, 1000);
{some other code here...}
{some other code here...}
flashled(12, 500, 500);
{some other code here...}
}

Brian,
I tried already earlier but i should look again into it now.

The code i first wrote for this example is this. You see the leds blinks with each states correctly. But my code is bad for a better overall program, i wish i could use only one function call instead.

long time = 0;
long timeON1 = 0; long timeOFF1 = 0; int state1 = LOW;
long timeON2 = 0; long timeOFF2 = 0; int state2 = LOW;
long timeON3 = 0; long timeOFF3 = 0;int state3 = LOW;

void setup()
{
Serial.begin(38400);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
}

void loop()
{
flashled1(10, 15, 400);
flashled2(11, 150, 600);
flashled3(12, 400, 1000);
}

void flashled1(int ledpin, int ledON, int ledOFF) {
time = millis();
if (state1 == HIGH) {
if (time >= timeOFF1) {
state1 = LOW;
Serial.print(state1);
digitalWrite(ledpin, state1);
timeON1 = timeOFF1 + ledOFF;
}
}
else {
if (state1 == LOW){
if (time >= timeON1) {
timeON1 = millis();
state1 = HIGH;
Serial.print(state1);
digitalWrite(ledpin, state1);
timeOFF1 = timeON1 + ledON;
}
}
}
}

void flashled2(int ledpin, int ledON, int ledOFF) {
time = millis();
if (state2 == HIGH) {
if (time >= timeOFF2) {
state2 = LOW;
Serial.print(state2);
digitalWrite(ledpin, state2);
timeON2 = timeOFF2 + ledOFF;
}
}
else {
if (state2 == LOW){
if (time >= timeON2) {
timeON2 = millis();
state2 = HIGH;
Serial.print(state2);
digitalWrite(ledpin, state2);
timeOFF2 = timeON2 + ledON;
}
}
}
}

void flashled3(int ledpin, int ledON, int ledOFF) {
time = millis();
if (state3 == HIGH) {
if (time >= timeOFF3) {
state3 = LOW;
Serial.print(state3);
digitalWrite(ledpin, state3);
timeON3 = timeOFF3 + ledOFF;
}
}
else {
if (state3 == LOW){
if (time >= timeON3) {
timeON3 = millis();
state3 = HIGH;
Serial.print(state3);
digitalWrite(ledpin, state3);
timeOFF3 = timeON3 + ledON;
}
}
}
}

It should be fairly easy to get what you want by combining two of AlphaBeta's libraries...

Arduino Playground - LED Library
Arduino Playground - TimedAction Library

  • Brian

Without knowing what you want, I threw some code togehter. Might be helpful, might not. But I thing you could get an idea of how one way to implement this could look.

#include <LED.h>
#include <TimedAction.h>

//setup
const byte LEAST_AMOUNT_OF_DELAY = 500;
const byte MAXIMUM_AMOUNT_OF_TICKS = 3; //we need a 'tick resolution' of three because (1000 + 500) / 500 = 3

LED led1 = LED(10);
LED led2 = LED(11);
LED led3 = LED(12);

TimedAction blinkAction = TimedAction(LEAST_AMOUNT_OF_DELAY,blinkTick); //triggers every 500 milliseconds
byte tick = 0;

void setup(){
led1.on();
led2.on();
led3.on();
}

void loop(){
blinkAction.check();
//do other stuff
}

void blinkTick(){
tick = ++tick % MAXIMUM_AMOUNT_OF_TICKS; //increment and constrain tick [0,2]
switch (tick){
case 0:
led1.on();
led2.on();
break;
case 1:
led2.off();
break;
case 2:
led1.off();
break;
}
led3.toggle();
}

Without knowing what you want, I threw some code togehter. Might be helpful, might not. But I thing you could get an idea of how one way to implement this could look.

Alexander,

Thanks for the idea but i don't think i could do what i want with it. I may try indeed and i will. ::slight_smile:
Here's exactly my need:

1- The number of led can be more than 3 and i can deal with this code myself.

2- The blinking is the most important behaviour in the program and this is where i'm looking for help. Some led will lite up for 10 millis and snuff out for 800 millis or lite up for 200 millis and snuff out for 254 millis etc... anytime in the program. Values are between 15 millis and 5000 millis. It is purely for visual purpose monitoring.

3- I thought that a simple function would be enough for that multiple blinking behaviour.

1- The number of led can be more than 3 and i can deal with this code myself.

2- The blinking is the most important behaviour in the program and this is where i'm looking for help. Some led will lite up for 10 millis and snuff out for 800 millis or lite up for 200 millis and snuff out for 254 millis etc... anytime in the program. Values are between 15 millis and 5000 millis. It is purely for visual purpose monitoring.

3- I thought that a simple function would be enough for that multiple blinking behaviour.

I maybe think you should create a struct like this:

typedef struct {
  byte pin;
  unsigned int onTime;
  unsigned int offTime;
  unsigned long previousOnTime;
} BlinkPin;

BlinkPin led1 = {10,500,1000,0};//pin 10, onTime=500, offTime=1000, previousOnTime=0

Then you can have a function with a body similar to, with led1 being the argument:

if ((millis()-led1.previousOnTime)>led1.onTime){
  digitalWrite(led1.pin,LOW);
}else if ((millis()-led1.previousOnTime)>(led1.onTime+led1.offTime)){
  led1.previousOnTime = millis();
  digitalWrite(led1.pin,HIGH);
}

The code I posted before should blink the leds as the code you posted in your original post indicated. (What an aweful sentance!)

I'm using struct now but i still unable to use only one function flashled(led_id) to pass argument of the led id i want to blink !!

I should never stop programming 22 years ago :-[

long time = 0;
typedef struct BlinkPin{
byte ledpin;
unsigned int ledON;
unsigned int ledOFF;
unsigned long timeON;
unsigned long timeOFF;
boolean state;
};

BlinkPin led1 = {10,25,1000,0,0,0};
BlinkPin led2 = {11,800,500,0,0,0};
BlinkPin led3 = {12,25,250,0,0,0};

void setup(){
Serial.begin(38400);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
}

void loop(){
flashled1();
flashled2();
flashled3();
}

void flashled1() {
time = millis();
if (led1.state == HIGH) {
if (time >= led1.timeOFF) {
led1.state = LOW;
Serial.print(led1.state);
digitalWrite(led1.ledpin, led1.state);
led1.timeON = led1.timeOFF + led1.ledOFF;
}
}
else {
if (led1.state == LOW){
if (time >= led1.timeON) {
led1.timeON = millis();
led1.state = HIGH;
Serial.print(led1.state);
digitalWrite(led1.ledpin, led1.state);
led1.timeOFF = led1.timeON + led1.ledON;
}
}
}
}

void flashled2() {
time = millis();
if (led2.state == HIGH) {
if (time >= led2.timeOFF) {
led2.state = LOW;
Serial.print(led2.state);
digitalWrite(led2.ledpin, led2.state);
led2.timeON = led2.timeOFF + led2.ledOFF;
}
}
else {
if (led2.state == LOW){
if (time >= led2.timeON) {
led2.timeON = millis();
led2.state = HIGH;
Serial.print(led2.state);
digitalWrite(led2.ledpin, led2.state);
led2.timeOFF = led2.timeON + led2.ledON;
}
}
}
}

void flashled3() {
time = millis();
if (led3.state == HIGH) {
if (time >= led3.timeOFF) {
led3.state = LOW;
Serial.print(led3.state);
digitalWrite(led3.ledpin, led3.state);
led3.timeON = led3.timeOFF + led3.ledOFF;
}
}
else {
if (led3.state == LOW){
if (time >= led3.timeON) {
led3.timeON = millis();
led3.state = HIGH;
Serial.print(led3.state);
digitalWrite(led3.ledpin, led3.state);
led3.timeOFF = led3.timeON + led3.ledON;
}
}
}
}

This should look like this :

flashled(led1);
flashled(led2);
flashled(led3);

void flashled(led_id) {
time = millis();
if (led_id.state == HIGH) {
if (time >= led_id.timeOFF) {
led_id.state = LOW;
Serial.print(led_id.state);
digitalWrite(led_id.ledpin, led_id.state);
led_id.timeON = led_id.timeOFF + led_id.ledOFF;
}
}
else {
if (led_id.state == LOW){
if (time >= led_id.timeON) {
led_id.timeON = millis();
led_id.state = HIGH;
Serial.print(led1.state);
digitalWrite(led_id.ledpin, led_id.state);
led_id.timeOFF = led_id.timeON + led_id.ledON;
}
}
}
}

i'm trying this:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1245221219/1#1

The problem with the original post is that the 3 variables - state, ledON, ledOFF - need to be in an array. The way you have it, each of the 3 pins are using the same variables, and it's messing things up. I put together a corrected version, and even tried it, so I know it works :slight_smile:

long time = 0;
long timeON[14];    // I assume your pins go from 0-13
long timeOFF[14];
int state[14];

void setup()
{
 int i;
 for(i=0;i<=13;i++) {          //Edit: changed 14 to 13
   timeON[i] = 0;
   timeOFF[i] = 0;
   state[i] = LOW;
 }
 Serial.begin(38400);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);
}

void loop()
{
 flashled(10, 1000, 500);
 flashled(11, 500, 1000);
 flashled(12, 500, 500);
}

void flashled(int ledpin, int ledON, int ledOFF) {
 time = millis();
 if (state[ledpin] == HIGH) {
   if (time >= timeOFF[ledpin]) { 
     state[ledpin] = LOW;
     //Serial.print(ledpin);Serial.print(" ");Serial.println(state[ledpin]);
     digitalWrite(ledpin, state[ledpin]);
     timeON[ledpin] = timeOFF[ledpin] + ledOFF;
   }
 }
 else {
   if (state[ledpin] == LOW){
     if (time >= timeON[ledpin]) {
       timeON[ledpin] = millis();      // you don't really need this line
       state[ledpin] = HIGH;
       //Serial.print(ledpin);Serial.print(" ");Serial.println(state[ledpin]);
       digitalWrite(ledpin, state[ledpin]);
       timeOFF[ledpin] = timeON[ledpin] + ledON;
     }
   }
 }
}

Good luck!

The problem with the original post is that the 3 variables - state, ledON, ledOFF - need to be in an array. The way you have it, each of the 3 pins are using the same variables, and it's messing things up. I put together a corrected version, and even tried it, so I know it works

Arrrgh!!
Thanks, i was close from the beginning :o

Warning - I made a mistake in my code. It still works, but just cause I lucked out.

int i;
for(i=0;i<=13;i++) { //error was in this line
timeON = 0;
_ timeOFF = 0;_
_ state = LOW;
}_