Pages: [1] 2   Go Down
Author Topic: Can anyone Help me out with Code for a RGB LED Throbbing/Breathing effect  (Read 2913 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Im Trying to help a friend of mine with a RGB LED Control system for giant kaleidoscopes hes building, he is looking for a specific effect and Im having trouble finding anything similar on the web:

He wants a "Breathing"  "Pulsating" or "Throbbing" effect that dims right down to near or complete darkness before building up again in next colour in sequence.
Ive found some code for a nice breathing effect on a single colour LED :
Code:
int ledPin = 13;
int x = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int outVal = yforx(x);
  analogWrite(ledPin, outVal);
  delay(18);
  x++;
}

int yforx(int x) {
  return (-240*abs(sin(x*0.01)))+255; //sine wave
}


And Ive also found code for changing between 7 colours:


Code:
/***************************
Author: Seth Leeper
Version: 1
Purpose: To cycle the tri-color LED
contained within the Sparkfun starter kit
through every available color combination with
a fade in/fade out effect.
************************************/

int RED = 5;    // RED pin of the LED to PWM pin 9
int GREEN = 6;  // GREEN pin of the LED to PWM pin 10
int BLUE = 7;   // BLUE pin of the LED to PWM pin 11

int DELAY_TIME = 15;  //changes speed of fading
int MAX_BRIGHT = 255; //sets maximum brightness, 255 max brightness
int COLOR_MIX = 0; //variable to change the colors that are mixed in switch statement

void fade_in(int x) //loop that gradually turns the LED on using PWM
{
    int counter;
    
    for(counter = 0; counter < x; counter++)
    {
        led_mixer(COLOR_MIX, counter);
        delay(DELAY_TIME);
    }
}

void fade_out(int x) //loop that gradually turns the LED off using PWM
{
    int counter;
    
    for(counter = x; counter > 0; counter--)
    {
        led_mixer(COLOR_MIX, counter);
        delay(DELAY_TIME);
    }
}

void led_mixer(int color, int x) //uses switch statement to mix color combinations
{
    switch(color)
    {
      case 0:
        analogWrite(RED, x);
        break;
      case 1:
        analogWrite(GREEN, x);
        break;
      case 2:
        analogWrite(BLUE, x);
        break;
      case 3:
        analogWrite(BLUE, x);
        analogWrite(GREEN, x);
        break;
      case 4:
        analogWrite(RED, x);
        analogWrite(BLUE, x);
        break;
      case 5:
        analogWrite(RED, x);
        analogWrite(GREEN, x);
        break;
      default:
        analogWrite(GREEN, x);
        analogWrite(BLUE, x);
        analogWrite(RED, x);
      break;
    }
}

void setup()
{
  // nothing for setup
}

void loop() //loop forever
{
  fade_in(MAX_BRIGHT); //gradually turn the LED on to max brightness
  fade_out(MAX_BRIGHT); //gradually turn off the LED
  COLOR_MIX++; //increment to the next color combination
  
  if(COLOR_MIX == 7) //if all color combinations have been displayed, reset the cycle
  {
    COLOR_MIX = 0;
  }
}

Im just having problems combining the two programs, im not looking for a smooth fade, If I was I would have plenty of code to pick from, Problem is that I need the brightness to die right down before next colour comes in,
Can anyone offer any assistance or point me in the direction of something similar thats already out there?
Thanks.

P.S. Im new to arduino and havnt time to learn it all from scratch as ive other projects to work on so im trying to use code I can find on net and modify it to save some time but Im starting to realise this is harder than I thought! smiley
« Last Edit: June 19, 2011, 06:24:39 pm by DeViL303 » Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Haha... well, I think I may have a segment of code that'll help. I spent about 2 hours sequencing these values and making sure they work right... originally, this was a massive block of sequential code where each step in the sequence was hard-coded. It rolls 3 sequential LEDs "down" in sequence, then back "up" to the top as a cute little startup animation using the 33.3/45/78 RPM indicator LEDs in my Arduino-controlled record player smiley

It executes blindingly fast without the delay - in fact, it runs so fast you can't even see it run at all. With the delay in there the way it is now, it completes the whole animation in about 1 second.
Code:
 // startup animation
  unsigned int thisBlip = 1; // 1 to begin the loop
  byte fadeDirection = 1;
  while (thisBlip) {
    if (thisBlip > 0 && thisBlip <= 255) analogWrite(3, constrain(thisBlip-0,0,255));
    else if (thisBlip > 255 && thisBlip < 511) analogWrite(3, constrain(255-(thisBlip-255),0,255));
    if (thisBlip > 127 && thisBlip <= 383) analogWrite(5, constrain(thisBlip-128,0,255));
    else if (thisBlip > 383 && thisBlip < 638) analogWrite(5, constrain(255-(thisBlip-383),0,255));
    if (thisBlip > 255 && thisBlip <= 511) analogWrite(6, constrain(thisBlip-256,0,255));
    else if (thisBlip > 511 && thisBlip < 766) analogWrite(6, constrain(255-(thisBlip-511),0,255));
    if (fadeDirection) thisBlip++;
    else thisBlip--;
    if (thisBlip > 638) fadeDirection = 0; // you can adjust 638 to change the ending point, goes up to 766 to make the last LED fade completely out at the end before going back "up" and going back through the sequence to the top again. at 638 it reverses when the last LED is full brightness.
    delay(1);
  }
  digitalWrite(3,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
Adapt the pin numbers (3, 5, 6) to your RGB pins, and adjust delay(1) to your desired "rate", and it very well should cycle though the RGB pins very smoothly smiley
« Last Edit: June 19, 2011, 06:30:12 pm by FalconFour » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Fast reply, Thanks, will have a go with that now. wow ,Is that the complete code, very short, nice!


Im getting an error " expected unqualified Id before "while" but its probably me doing something stupid.

Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Strange, compiles OK for me. Maybe you have something above/below the block that's messed up? Or did you change something in it?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes its probably me, Im really only just learning to code, last code i learned was BASIC years and years ago. I just pasted yours into new sketch but i changed pins to 9,10,11 .

When i took on this project I thought I would find some ready made code that would be very close to what I wanted but seems I can only find single colour breathing/throbbing code, and none seem easy to modify to RGB.

Basically im looking for a standard 7 colour RGB fade but with more of a gap between the colours (after the fade out), I know there must be hundreds of ways to code this effect but not sure which to take, maybe to have a "Black" (Red=0 Green=0 Blue=0) colour in between each colour fade would be a good way but I dont know enough to achieve this in code, yet, but I'm learning.

Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, since it fades through-then-back-through, it will exit the loop and turn all the colors off at the end of the loop (digitalWrite(x,LOW);). If you're doing that in a loop, you can just add a "delay(1000);" to add a 1 second "off" period at the end of each sequence. If you want to pause after each color transition, that may get a little more complicated... but you should be able to set a "if (thisBlip == XX) delay(1000);" conditional (equal, only fires once per cycle) in the loop to catch when each color is fully "on", and pause it there for a second.

Still curious about that compile error. Did you get that resolved? If not, can you post the whole thing you've got in the program?

edit: ooh, 7 colors, that's a little more complex, it'd have to fade through each color combination instead of just going 1->2, 2, 2->3, 3 (3 colors, I think). You can probably just dick with the numbers and expand the sequence with more combinations, like having two analogWrite() with the same calculated value, for those colors that need both red and green (pink), or blue and green (cyan), or red/green (yellow), for example...
« Last Edit: June 19, 2011, 07:06:13 pm by FalconFour » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

well as im such a noob i literally just pasted your code into a new blank sketch and changed the pin numbers to my pins on my mega, im really only at the copy and paste stage with my coding!
Im trying to figure out how to combine it with the colour fading code but im so far off being capable yet!

Edit: even 3 colours would do at this stage as im losing hope.

BTW: thanks for all the help

Even A hardcoded version on a loop would do me as this does not need to be dynamic , just dont know where to start.
« Last Edit: June 19, 2011, 07:25:58 pm by DeViL303 » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Any idea how I would modify this to dim more in between colours as its almost what i want just not enough "breathing"
Code:
int RED = 5;    // RED pin of the LED to PWM pin 9
int GREEN = 6;  // GREEN pin of the LED to PWM pin 10
int BLUE = 7;   // BLUE pin of the LED to PWM pin 11

int DELAY_TIME = 15;  //changes speed of fading
int MAX_BRIGHT = 255; //sets maximum brightness, 255 max brightness
int COLOR_MIX = 0; //variable to change the colors that are mixed in switch statement

void fade_in(int x) //loop that gradually turns the LED on using PWM
{
    int counter;
   
    for(counter = 0; counter < x; counter++)
    {
        led_mixer(COLOR_MIX, counter);
        delay(DELAY_TIME);
    }
}

void fade_out(int x) //loop that gradually turns the LED off using PWM
{
    int counter;
   
    for(counter = x; counter > 0; counter--)
    {
        led_mixer(COLOR_MIX, counter);
        delay(DELAY_TIME);
    }
}

void led_mixer(int color, int x) //uses switch statement to mix color combinations
{
    switch(color)
    {
      case 0:
        analogWrite(RED, x);
        break;
      case 1:
        analogWrite(GREEN, x);
        break;
      case 2:
        analogWrite(BLUE, x);
        break;
      case 3:
        analogWrite(BLUE, x);
        analogWrite(GREEN, x);
        break;
      case 4:
        analogWrite(RED, x);
        analogWrite(BLUE, x);
        break;
      case 5:
        analogWrite(RED, x);
        analogWrite(GREEN, x);
        break;
      default:
        analogWrite(GREEN, x);
        analogWrite(BLUE, x);
        analogWrite(RED, x);
      break;
    }
}

void setup()
{
  // nothing for setup
}

void loop() //loop forever
{
  fade_in(MAX_BRIGHT); //gradually turn the LED on to max brightness
  fade_out(MAX_BRIGHT); //gradually turn off the LED
  COLOR_MIX++; //increment to the next color combination
 
  if(COLOR_MIX == 7) //if all color combinations have been displayed, reset the cycle
  {
    COLOR_MIX = 0;
  }
}
Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

All Arduino sketches have two parts: setup() and loop() at a minimum.

setup() runs only once at the start, when you first plug it in or reset it. It does just what it says: it "sets up" things that are used in the loop.

loop() runs continuously, around and around, until you unplug it.

So in your case...

Code:
void setup() {
  pinMode(9,OUTPUT); // set up LEDs as outputs.
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
}
void loop() {
 // startup animation
  unsigned int thisBlip = 1; // 1 to begin the loop
  byte fadeDirection = 1;
  while (thisBlip) {
    if (thisBlip > 0 && thisBlip <= 255) analogWrite(3, constrain(thisBlip-0,0,255));
    else if (thisBlip > 255 && thisBlip < 511) analogWrite(3, constrain(255-(thisBlip-255),0,255));
    if (thisBlip > 127 && thisBlip <= 383) analogWrite(5, constrain(thisBlip-128,0,255));
    else if (thisBlip > 383 && thisBlip < 638) analogWrite(5, constrain(255-(thisBlip-383),0,255));
    if (thisBlip > 255 && thisBlip <= 511) analogWrite(6, constrain(thisBlip-256,0,255));
    else if (thisBlip > 511 && thisBlip < 766) analogWrite(6, constrain(255-(thisBlip-511),0,255));
    if (fadeDirection) thisBlip++;
    else thisBlip--;
    if (thisBlip > 766) {
      delay(1000); // hold 1 second at one end of the sequence
      fadeDirection = 0; // you can adjust 638 to change the ending point, goes up to 766 to make the last LED fade completely out at the end before going back "up" and going back through the sequence to the top again. at 638 it reverses when the last LED is full brightness.
    }
    delay(1);
  }
  digitalWrite(3,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  delay(1000); // hold 1 second at the beginning of the sequence before looping
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, nice one, thanks, that has helped alot, ive modded it too this now
Code:
void setup() {
  pinMode(9,OUTPUT); // set up LEDs as outputs.
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
}
void loop() {
 // startup animation
  unsigned int thisBlip = 1; // 1 to begin the loop
  byte fadeDirection = 1;
  while (thisBlip) {
    if (thisBlip > 0 && thisBlip <= 255) analogWrite(9, constrain(thisBlip-0,0,255));
    else if (thisBlip > 255 && thisBlip < 511) analogWrite(9, constrain(255-(thisBlip-255),0,255));
    if (thisBlip > 127 && thisBlip <= 383) analogWrite(10, constrain(thisBlip-128,0,255));
    else if (thisBlip > 383 && thisBlip < 638) analogWrite(10, constrain(255-(thisBlip-383),0,255));
    if (thisBlip > 255 && thisBlip <= 511) analogWrite(11, constrain(thisBlip-256,0,255));
    else if (thisBlip > 511 && thisBlip < 766) analogWrite(11, constrain(255-(thisBlip-511),0,255));
    if (fadeDirection) thisBlip++;
    else thisBlip--;
    if (thisBlip > 766) {
      delay(1000); // hold 1 second at one end of the sequence
      fadeDirection = 0; // you can adjust 638 to change the ending point, goes up to 766 to make the last LED fade completely out at the end before going back "up" and going back through the sequence to the top again. at 638 it reverses when the last LED is full brightness.
    }
    delay(1);
  }


  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(11,LOW);
  delay(1000); // hold 1 second at the beginning of the sequence before looping
}

Its looking good but i need to invert it as its fading back to full on white between colours,  My led strip must be wired the other way
« Last Edit: June 19, 2011, 07:39:37 pm by DeViL303 » Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Whoops! Good catch, I forgot to change the analogWrite's to 9/10/11. Unfortunately I don't have an RGB LED to play with, so I really don't know what else to change... I wouldn't think it would be going full on white between colors, since only up to two are supposed to be on at a time. Maybe you've got negative logic on the pins (ground controlling each pin), so LOW would be on. Hmm... I'll play around with the code and see if I can make it work in reverse...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, yes my led strips are common anode, yours must have been common cathode. cheers . even just seeing your code has helped alot, i must do more research smiley
Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Alright, I flipped around the inversions in the if/else conditions, now it inverts going up instead of down smiley
Code:
void setup() {
  pinMode(9,OUTPUT); // set up LEDs as outputs.
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
}
void loop() {
  // startup animation
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);
  digitalWrite(11,HIGH);
  unsigned int thisBlip = 1; // 1 to begin the loop
  byte fadeDirection = 1;
  while (thisBlip) {
    if (thisBlip > 0 && thisBlip <= 255) analogWrite(9, constrain(255-thisBlip,0,255));
    else if (thisBlip > 255 && thisBlip < 511) analogWrite(9, constrain(thisBlip-255,0,255));
    if (thisBlip > 127 && thisBlip <= 383) analogWrite(10, constrain(255-(thisBlip-128),0,255));
    else if (thisBlip > 383 && thisBlip < 638) analogWrite(10, constrain(thisBlip-383,0,255));
    if (thisBlip > 255 && thisBlip <= 511) analogWrite(11, constrain(255-(thisBlip-256),0,255));
    else if (thisBlip > 511 && thisBlip < 766) analogWrite(11, constrain(thisBlip-511,0,255));
    if (fadeDirection) thisBlip++;
    else thisBlip--;
    if (thisBlip > 766) {
      delay(1000); // hold 1 second at one end of the sequence
      fadeDirection = 0; // you can adjust 638 to change the ending point, goes up to 766 to make the last LED fade completely out at the end before going back "up" and going back through the sequence to the top again. at 638 it reverses when the last LED is full brightness.
    }
    delay(1);
  }
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);
  digitalWrite(11,HIGH);
  delay(1000); // hold 1 second at the beginning of the sequence before looping
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Brilliant, That is working perfect, nice one, youve made things so much easier! Thanks a mill  smiley-grin

Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sweet! And you can make it pause on each color step using the values in the "if" statements, for example:

if (thisBlip == 127) delay(500);
if (thisBlip == 255) delay(500);
if (thisBlip == 383) delay(500);
if (thisBlip == 511) delay(500);
if (thisBlip == 638) delay(500);

... inside the while() loop, and it'll pause 1/2 second on each mid-step transition, probably making it even cooler to watch smiley-wink

Now I want an RGB LED of my own! LOL...
Logged

Pages: [1] 2   Go Up
Jump to: