Controlling LED Sequence

Hi all,

This post is further to my post from yesterday...I think I've got a few more ideas about how C and Arduino work now! I was wondering if anyone has any thoughts on how to do the following:

When a button is pressed an RGB fade sequence (green>yellow>red, with shade in between those colours) is initiated. This fade should last for, for example, 30secs. When 30secs have elapsed the LEDs remain on red until the switch is turned off. Accompanying the RGB fade are white LEDs that come on a different times, for example LED1 at 0sec, LED 2 at 10sec, LED 3 at 20sec. Pressing the button at any time during the fade sequence should turn off all LEDs (both RGB and white) and return the code to the beginning of the sequence. This is so that the next time the button is pressed the sequence starts from the beginning. I hope that makes some sense! =) Essentially it is a fade sequence that is started by a switch going high and constantly checks to see if the switch has gone low.

Thanks to flobotic and mikalhart I have been manipulating some code. This steps through 3 LEDs returning to the beginning when the button is turned off, regardless of when the button is pressed in the sequence. I've tried to add fading LEDs but I can't seem to control them...at the moment they simply fade from LED1 to LED2 for example, but the overall fade from LED1 to LED3 isn't smooth (if that makes any sense).

Any help or advice is much appreciated!! I'm sure this is fairly standard stuff for someone with more experience/knowledge than myself!!

// Version 006
// 16.03.2009

// Output
int led1Pin = 9;      // LED1
int led2Pin   = 10;   // LED2
int led3Pin  = 11;    // LED3
int switchPin    = 2; // Switch

// Program variables
int led1Val       = 0;     // Variables to store the values to send to the pins
int led2Val       = 0;     // Initial values are all LEDs off
int led3Val       = 0;
int wait          = 9;     // 9ms (.009 second) delay
int phase         = 0;     // phase number for fades
bool triggered    = false; // records whether the button has been pressed
int phase0Val     = 255;
int phase1Val     = 0;
int phase2Val     = 0;
int phase3Val     = 0;
int flashVal      = 0;

void setup()
{
 pinMode(led1Pin, OUTPUT);   // sets the pins as output
 pinMode(led2Pin, OUTPUT);  
 pinMode(led3Pin, OUTPUT);
 pinMode(switchPin, INPUT);  // sets the pin as output
 srand(analogRead(0));
}

// Main program
void loop()
{
 
 if (digitalRead(switchPin) == HIGH)
 {
   triggered   = false;
   phase0Val   = 255;
   phase1Val   = 1;
   phase2Val   = 1;
   phase3Val   = 1;
   phase       = 0;
   led1Val     = 0;
   led2Val     = 0;
   led3Val     = 0;
 } 




 if (!triggered)
 {
   if (phase == 0)
   {
     led1Val = 0; // LED 1 off
     led2Val = 0; // LED 2 off
     led3Val = 0; // LED 3 off
     phase0Val--;; // Phase 0 counter down
     phase1Val++;  // Phase 1 counter up
     if (phase1Val == 50) // When Phase 1 counter reaches 50 code moves to Phase 1
       phase = 1;
   }
   else if (phase == 1)
   {
     led1Val = 255; // LED 1 on
     phase1Val--; // Phase 1 counter down
     phase2Val++; // Phase 2 counter up
     if (phase2Val == 255) // When Phase 2 counter reaches 500 code moves to Phase 2
       phase = 2;
   }
   else if (phase == 2)
   {
     led2Val ++; // LED 2 on
     led1Val --; // LED 1 off
     // phase2Val--; // Phase 2 counter down
     // phase3Val++; // Phase 3 counter up
     if (led2Val == 255) // When Phase 3 counter reaches 500 code moves to Phase 3
      phase = 3;
      
   }
   else if (phase == 3)
   {
     led3Val ++; // LED 3 on
     led2Val --; // LED 2 off
     
     phase3Val--; // Phase 3 counter down
     phase0Val++; // Phase 0 counter up
     // LED 3 remains on until switch is turned off. 
     // At the moment it just fades in and then loops again. 
     // It should stay full on (255)
   }
 }
}

You never seem to analogWrite your values?

oops...you're right! The last lines should be....

 analogWrite(led1Pin,   led1Val);   // Write current values to LED pins
 analogWrite(led2Pin,   led2Val);
 analogWrite(led3Pin,   led3Val);
 delay(wait);
}

Essentially it is a fade sequence that is started by a switch going high and constantly checks to see if the switch has gone low.

Like this? :slight_smile: :

/*
|| Version 007
|| 18.03.2009
||
|| Button controlled LED fade
|| Startes a fade on buttonpress, and fades between three PWM out.
||
|| Contributed:
|| Alexander Brevig
*/

#define DEBUG false
#define BAUDRATE 9800

#define PULLUP_RESISTOR 1 //set to 0 if pulldown is used
#define BUTTON_PRESSED (!PULLUP_RESISTOR)

#define FADE_LENGTH 30000 //micoseconds
#define FADE_STEPS (255+255) //one step per possible changestate
#define FADE_DELAY (FADE_LENGTH-(DEBUGFADE_LENGTH1/3)/FADE_STEPS) //tries to compensate for debugging

// Output
#define LED_START_PIN 9 // LED1
#define LED_MID_PIN 10 // LED1
#define LED_END_PIN 11 // LED1
#define SWITCH_PIN 2

// Program variables
byte startVal = 0; // Variables to store the values to send to the pins
byte midVal = 0; // Initial values are all LEDs off
byte endVal = 0;

int fadeState = 0; // Tick through all possible fade variations

void setFadeState(int state){
if(state<255){
startVal = 255-state;
midVal = state;
endVal = 0;
}else if(state<510){
startVal = 0;
midVal = 255+(255-state);
endVal = state-255;
}else{
startVal = 0;
midVal = 0;
endVal = 255;
}
if (DEBUG){ Serial.print("Fade values: "); Serial.print(startVal,DEC); Serial.print(" "); Serial.print(midVal,DEC); Serial.print(" "); Serial.println(endVal,DEC); }
}

void incrementFade(){
setFadeState(fadeState++);
}

void resetFadeState(){
fadeState=0;
setFadeState(fadeState);
}

void setup()
{
pinMode(LED_START_PIN , OUTPUT ); // sets the pins as output
pinMode(LED_MID_PIN , OUTPUT );
pinMode(LED_END_PIN , OUTPUT );
pinMode(SWITCH_PIN , INPUT ); // sets the pin as output
if(PULLUP_RESISTOR){digitalWrite(SWITCH_PIN,HIGH);}
if(DEBUG){
Serial.begin(BAUDRATE); Serial.println("Program start...");
Serial.print("Fade length: "); Serial.print(FADE_LENGTH,DEC);
Serial.print(" fade steps: "); Serial.print(FADE_STEPS,DEC);
Serial.print(" fade delay: "); Serial.println(FADE_DELAY,DEC);
}
//delay(1000);
}

// Main program
void loop()
{
if (digitalRead(SWITCH_PIN) == BUTTON_PRESSED ){
while (digitalRead(SWITCH_PIN) == BUTTON_PRESSED )
{
incrementFade();
analogWrite(LED_START_PIN, startVal); // Write current values to LED pins
analogWrite(LED_MID_PIN, midVal);
analogWrite(LED_END_PIN, endVal);
delay(FADE_DELAY);
}
}else{
resetFadeState();
digitalWrite(LED_START_PIN, LOW); // Write current values to LED pins
digitalWrite(LED_MID_PIN, LOW);
digitalWrite(LED_END_PIN, LOW);
}
}

I fades according to this
Fade Graph

Alexander,

Just logged on and saw your post. Tested it out and it works really well!! Thank you for your help. I'm going through the code to try to understand all the lines...otherwise I'll never learn. I'm sure I'll have a few questions though...=)

I'm going through the code to try to understand all the lines...otherwise I'll never learn. I'm sure I'll have a few questions though...=)

Do not hesitate to ask :slight_smile:

I've been going through the code and think I'm slowing understanding...very slowly. One thing I can't figure out is;

#define FADE_DELAY (FADE_LENGTH-(DEBUGFADE_LENGTH1/3)/FADE_STEPS) //tries to compensate for debugging

What exactly does this line do?

Also, at the moment as soon as the button is pressed the fade from R to B starts immediately. If I wanted to delay the fade by, for example, 5sec could I put a delay as the first line of 'void setFadeState(int State)'. I'm slowly understanding that using delays isn't really the best way to do some things but I can't figure out how else to do it. :-[

#define FADE_DELAY (FADE_LENGTH-(DEBUGFADE_LENGTH1/3)/FADE_STEPS) //tries to compensate for debugging

What exactly does this line do?

I found that when enableing debugging, the serial print commands took about 1/3 of the executiontime of a cycle. So I just subtracted it from fade length.

Ignore the '(DEBUGFADE_LENGTH1/3)' part, then it becomes:

#define FADE_DELAY (FADE_LENGTH/FADE_STEPS)

So in effect FADE_LENGTH = FADE_STEPS * FADE_DELAY

This simply computes how long the program needs to halt in order for a fade to take place. (especially a fade that lasts for FADE_LENGTH milliseconds :slight_smile: