Go Down

Topic: Function for multiple blinking led (Read 1 time) previous topic - next topic

sync

Jun 29, 2009, 09:06 am Last Edit: Jun 30, 2009, 03:01 am by sync Reason: 1
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;
     }
   }
 }
}

AWOL

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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Coding Badly

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

sync

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...}
}

sync

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

sync

#5
Jun 29, 2009, 10:47 am Last Edit: Jun 29, 2009, 10:48 am by sync Reason: 1
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;
     }
   }
 }
}


AlphaBeta

Quote
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


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.

Quote

#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();
}

sync

#7
Jun 29, 2009, 12:11 pm Last Edit: Jun 29, 2009, 12:13 pm by sync Reason: 1
Quote
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. ::)
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.

AlphaBeta

#8
Jun 29, 2009, 12:45 pm Last Edit: Jun 29, 2009, 12:47 pm by AlphaBeta Reason: 1
Quote

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:
Code: [Select]
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:
Code: [Select]
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!)

sync

#9
Jun 30, 2009, 12:22 am Last Edit: Jun 30, 2009, 02:05 am by sync Reason: 1
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;
     }
   }
 }
}

sync

#10
Jun 30, 2009, 02:24 am Last Edit: Jun 30, 2009, 02:25 am by sync Reason: 1
i'm trying this:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1245221219/1#1

Kitep

#11
Jun 30, 2009, 02:30 am Last Edit: Jul 01, 2009, 01:42 am by Kitep Reason: 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 :)

Code: [Select]
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!

sync

#12
Jun 30, 2009, 02:47 am Last Edit: Jun 30, 2009, 03:43 am by sync Reason: 1
Quote
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


Kitep

#13
Jul 01, 2009, 01:43 am Last Edit: Jul 01, 2009, 01:44 am by Kitep Reason: 1
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;
}

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview