Pages: [1]   Go Down
Author Topic: Function for multiple blinking led  (Read 1476 times)
0 Members and 1 Guest are viewing this topic.
ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;
      }
    }
  }
}
« Last Edit: June 29, 2009, 08:01:09 pm by sync » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25713
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12743
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

« Last Edit: June 29, 2009, 03:48:49 am by sync » Logged

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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. :smiley
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.
« Last Edit: June 29, 2009, 05:13:40 am by sync » Logged

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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!)
« Last Edit: June 29, 2009, 05:47:11 am by AlphaBeta » Logged

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;
      }
    }
  }
}
« Last Edit: June 29, 2009, 07:05:29 pm by sync » Logged

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i'm trying this:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1245221219/1#1
« Last Edit: June 29, 2009, 07:25:14 pm by sync » Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley

Code:
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!
« Last Edit: June 30, 2009, 06:42:31 pm by Kitep » Logged

ca
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

« Last Edit: June 29, 2009, 08:43:22 pm by sync » Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;
 }
« Last Edit: June 30, 2009, 06:44:27 pm by Kitep » Logged

Pages: [1]   Go Up
Jump to: