views:

1346

answers:

3

I need to figure out how to fade in and out of multiple LEDS in a function with an Arduino. Can't use delay() because other things need to run while the light is fading. This is what it has so far, but does not work.

int value = 0;                            // variable to keep the actual value 
int ledpin = 9;                           // light connected to digital pin 9
int p1 = 0;

void setup() 
{ 
  // nothing for setup 
  Serial.begin(9600);
} 

void loop() 
{ 
  inout(50, 30, 9, 0, 0);
  //inout(20, 20, 10);
} 

void inout(int inDelay, int outDelay, int ledpin, long previousmil, int done)
{

  if(millis() - previousmil>inDelay){
    if (value <=255){
      analogWrite(ledpin, value);          // sets the value (range from 0 to 255)         
      value+=5;
    }
    previousmil=millis();
  }

  if(value = 260)
    done = 1;

  if(millis() - previousmil>outDelay && done == 1){

    if (value >0){
      analogWrite(ledpin, value);          // sets the value (range from 0 to 255)                       

      value-=5;
    }
    previousmil=millis();
  }

}
+4  A: 

The only obvious thing is that you've got a state flag for which way to increment value, but you're not testing it in your first if. It would be better to structure your code a bit more. You also may want to track more than one value if you have more than one pin, unless they all should fade in and out at the same time. In that case you'd be best off with an array of structs with the parameters for each pine.

One way of using delay with multiple tasks is to have each task work on the time elapsed since the last loop, and adjust the delay at the end of your loop for the time the tasks take. If your loop is something like:

static unsigned long last_time = 0; // set to millis() in setup
static unsigned long refresh_period = 20; // 50Hz

void loop() 
{
    unsigned long time = millis();
    unsigned long delta = time - last_time;

    doTask1( delta );
    doTask2( delta );
    doTask3( delta );
    doTask4( delta );

    // as tasks may have taken some millis, adjust delay 
    unsigned long post_time = millis();

    if ( post_time - last_time < refresh_period )
        delay( refresh_period - ( post_time - last_time ) );

    last_time = time;
}

Then each task will be run about once every 20ms, and will be passed 20 or so as the number of milliseconds to update their state for. So you get some delay, but everything has a chance to update.

Pete Kirkham
A: 

If you want to throw hardware at the problem, you can hook up your LEDs to an external controller chip, like the TI TLC5940. Those let you program a brightness level per LED and handle the PWM output to the LEDs separately from the ATMega CPU in the Arduino. You only need to reprogram the TLC chip when you want the brightness level to change. There's a nice TLC library available to handle communication with the chip on Google Code.

Ben Combee
+1  A: 

Speculating, but this seems wrong:

if(value=260)

(reminding me of the worlds last mistake in C)

CoderTao