First project: fade up LED then turn on another and fade down both

Hi, this is my first Arduino project. I was looking for a way to control LED lights for an art project for school and I can't figure out how to do a very specific series of events. I have a Nano v3.0 with a 328 chip. Any help would be greatly appreciated!

When a normally off momentary switch is pressed, I would like the following to happen:

  1. A Blue LED fades up to 80% over about 1 second (preferably using a cos/sine curve rather than linearly), then
  2. It fades up the rest of the way, from 80% to 100% while a White LED also fades up from 0% to 100% at the same time (this should be very rapid, say 1/4 of a second)
  3. After both LEDs reach 100% they both fade out over about 1 second.
  4. They remain off until the switch is pressed again.
  5. When the switch is pressed, steps 1-4 would happen again.

Can anyone help me with some code? I know it's probably not very complicated, but I'm extremely new to sketches (and coding in general) and I'm not even sure how to search for that type of instruction, so I thought I would see if anyone could help me out. Thanks!

Hi,

If you've got a few minutes to spare, it's well worth checking out the Arduino tutorials on youtube by Jeremy Blum. Much of what you need, both the switch logic and changing the brightness of an LED using PWM is covered in the first two videos so you won't have to watch long before you find 80% of what you need for what you're planning.

All the best,
Geoff

I am also new but here a fast sketch that should do the job (Tryed to explain what i did in comments). Ask if you have questions :slight_smile:

int BluePin = 10;          //Blue LED an pin 10
int WhitePin  = 11;        //White LED an pin 11
int i = 0;

bool presswitch = false;   // switch not pressed


int BlueVal = 0;          // 0 = 0%     255 = 100%
int WhiteVal  = 0; 

void setup()
{
  pinMode(BluePin,   OUTPUT);
  pinMode(WhitePin, OUTPUT);   
}

void loop()
{

if (presswitch == true)   // switch pressed
{

if (BlueVal < 200)                                 // under 80%
{
BlueVal++;                                         //blue from 0% to 80%
analogWrite(WhitePin, WhiteVal); 
analogWrite(BluePin,  BlueVal); 
delay(5);                                 //5*200=1000  means it needs 1 sec to get to 80%
}

if (BlueVal > 200)       //over 80%
{
BlueVal++;                                       // blue from 80% to 100%
WhiteVal+=5;                                  // white from 0% to 100%
analogWrite(WhitePin, WhiteVal);  //write val to LED
analogWrite(BluePin,  BlueVal); 
delay(5);                                        // 1/4 sec
}

if (BlueVal == 255)     //max reached
{
BlueVal = 255;
WhiteVal = 255;

for(i=255;i > 0;i--)          //both fade out over 1 sec
{

presswitch = false;        // switch needs to be pressed again

BlueVal = i;
WhiteVal = i;
analogWrite(WhitePin, WhiteVal); 
analogWrite(BluePin,  BlueVal); 
delay(7);
}
}
}
}

Edit:
did not see Geoffs post before I posted. I recommend trying out what he sayed befor you just use what i did :slight_smile:

Here you go.

void setup(){
int ledone = *insert PWM pin here*;
int ledtwo = *insert PWM pin here*;
int DELAY = 10; // desired delay in ms between each dimming cycle.

pinMode(ledone, OUTPUT);
pinMode(ledtwo, OUTPUT);
}

void loop(){
int i = 0;

while(i < 255){ // slowly light ledone up
i++;  // adds 1 to i.
analogWrite(ledone,i);  // write a PWM value to the LED
delay(DELAY); // wait.
}

i = 0;

while (i < 255){ // slowly light ledtwo up
i++;
analogWrite(letwo,i);
delay(DELAY);
}

i= 0;

while (i > 0){   // now dim them both down.
i --; // removes 1 to i
analogWrite(ledone,i);
analogWrite(ledtwo,i);
delay(DELAY);
}

}

in the easiest way possible (probably not the best way though)

Funny how this post is 2 days old and suddenly 3 people reply at the same time XD

Wow! Thanks everyone XD

I'm heading over to watch those tutorials right now, but I do have an embarrassingly n00b question: What pins do I attach the leads from the switch to? In a normal circuit, I would just put it in series with the power supply, but something tells me that's not what I need to do in this case, otherwise, how does the circuit know the button is pushed -and since it's momentary, not just turn off when released? Maybe the answer is in one of those videos...

Thanks again!

Why not use the IO pins in the Jeremy Blum tutorial? You're right, it doesn't go in the power circuit.

The tutorials helped, and this works, mostly, but I'm still not getting the exact behavior I had hoped for. The button turns on the lights, but the white one turns on first (I just switched the leads to solve that) -but they both stay on for a really long time after they are both lit. I think it might be due to the switch...

int switchPin = 8;     //switch is connected to pin 8
int BluePin = 12;        //Blue LED on pin 12
int WhitePin = 11;     //White LED on pin 11
int i = 0;

boolean pressSwitch = false;    //switch not pressed

int BlueVal = 0;          //0 = 0%   255 = 100%
int WhiteVal = 0;

void setup ()
{
  pinMode (switchPin, INPUT);
  pinMode (BluePin, OUTPUT);
  pinMode (WhitePin, OUTPUT);
}

void loop ()
{
  if (digitalRead(switchPin) == HIGH)
  {
  if (BlueVal < 200)        //over 80%
  {
    BlueVal++;              //Blue from 80% - 100%
    WhiteVal+=5;            //White from 0% - 100%
    analogWrite (WhitePin, WhiteVal);    //write val to white LED
    analogWrite (BluePin, BlueVal);       //write val to blue LED
    delay (5);
  }
if (BlueVal > 200)       //over 80%
{
BlueVal++;                                       // blue from 80% to 100%
WhiteVal+=5;                                  // white from 0% to 100%
analogWrite(WhitePin, WhiteVal);  //write val to LED
analogWrite(BluePin,  BlueVal); 
delay(5);                                        // 1/4 sec
}

if (BlueVal == 255)     //max reached
{
BlueVal = 255;
WhiteVal = 255;

for(i=255;i > 0;i--)          //both fade out over 1 sec
{

pressSwitch = false;        // switch needs to be pressed again

BlueVal = i;
WhiteVal = i;
analogWrite(WhitePin, WhiteVal); 
analogWrite(BluePin,  BlueVal); 
delay(7);
}
}
}
}

Hi,

You'll need to select a PWM capable IO pin for each of your LEDs. BluePin is using 12 which isn't (presuming you're using an Arduino Uno or similar). From the AnalogWrite reference page:

On most Arduino boards (those with the ATmega168 or ATmega328), this function works on pins 3, 5, 6, 9, 10, and 11.

Not quite sure what you're wanting to achieve in the sections below, but the code blocks for when BlueVal is less than 200 is the same as when it's greater than.

    if (BlueVal < 200)        //over 80%
    {
// the bit in here
    }
    if (BlueVal > 200)       //over 80%
    {
// is exactly the same as the bit in here
    }

Also, in case this next comment was what you wanted to achieve...

      delay(5);                                        // 1/4 sec

That only pauses the code for 5/1000 sec. For 1/4 sec delay(250) is what you'd need. (refer: Delay reference page)

majikfraug:
the white one turns on first (I just switched the leads to solve that) -but they both stay on for a really long time after they are both lit.

You'll find white turns on first because you're incrementing the brightness by 5 each loop through (in the code that's WhiteVal+=5), whereas the blue pin is being incremented by 1 (in the code that's BlueVal++). White will reach 100% brightness 5 times sooner because you've coded it that way. As a side note, because you only start to dim the LEDs after BlueVal reaches full, at this point WhiteVal will be off the scale (remember 0..255 for analogWrite). Presently that bit of code will never be reached though - more on that below.

majikfraug:
I think it might be due to the switch...

Check your logic. If the switch is high, you increment the brightness of both LEDs when BlueVal is almost any value (> 200 or <200), but the way I read it, when BlueVal is actually equal to 200 it will have nothing to do. Your LED brightness will be stuck at 200. Change one of those tests to >=200 or <=200 so it knows what to do actually at 200.

All the best,
Geoff

At some point you are likely to discover that the use of the delay() function gets in your way because the Arduino can do nothing else while it waits for the time to pass. You should study the technque in the Blink Without Delay example sketch. The longer demo in the first post in this Thread may also help.

It would probably be much easier to start using the BWoD technique rather than have to change all your code later to get rid of the delay()s.

...R

Compare this part of your code to mine. you exedently put the same in both if states :wink:

if (digitalRead(switchPin) == HIGH)
{
if (BlueVal < 200) //over 80%
{
BlueVal++; //Blue from 80% - 100%
WhiteVal+=5; //White from 0% - 100%
analogWrite (WhitePin, WhiteVal); //write val to white LED
analogWrite (BluePin, BlueVal); //write val to blue LED
delay (5);
}
if (BlueVal > 200) //over 80%
{
BlueVal++; // blue from 80% to 100%
WhiteVal+=5; // white from 0% to 100%
analogWrite(WhitePin, WhiteVal); //write val to LED
analogWrite(BluePin, BlueVal);
delay(5); // 1/4 sec
}

thats how it should look like for the right behavior:

if (BlueVal <= 200)                                 // under 80%
{
BlueVal++;                                         //blue from 0% to 80%
analogWrite(WhitePin, WhiteVal); 
analogWrite(BluePin,  BlueVal); 
delay(5);                                 //5*200=1000  means it needs 1 sec to get to 80%
}

if (BlueVal > 200)       //over 80%
{
BlueVal++;                                       // blue from 80% to 100%
WhiteVal+=5;                                  // white from 0% to 100%
analogWrite(WhitePin, WhiteVal);  //write val to LED
analogWrite(BluePin,  BlueVal); 
delay(5);                                        // 1/4 sec
}

Btw I was using a arduino mega he has PMW on pin 10 and 11. if you use a other board check witch pins support PMW and just change them if you have to.

to geoff :

delay(5); // 1/4 sec

That only pauses the code for 5/1000 sec. For 1/4 sec delay(250) is what you'd need. (refer: Delay reference page)

The delay(5); happens 200 times until it is 80% lit so it is equal to 1 sec, isn't it? I am really new to arduino and I kinda know delay is never good though

DotAku:
The delay(5); happens 200 times until it is 80% lit so it is equal to 1 sec, isn't it? I am really new to arduino and I kinda know delay is never good though

Agreed. My remark was just since the comment and code don't align.

Cheers! Geoff

majikfraug:
When a normally off momentary switch is pressed, I would like the following to happen:

  1. A Blue LED fades up to 80% over about 1 second (preferably using a cos/sine curve rather than linearly), then

have you addressed this fade up yet ?

not sure if the fibonacci sequence of delays referred to here would help. it seems simple enough to implement.

http://forum.arduino.cc/index.php/topic,41433.0.html

I just started looking at fading up and down for lights.

create 3 additional values
int blue1 =0
int blue2=0
int blue3 =0

once the button is pressed, and state has changed
blue1=1

blue3-blue1+blue2

BlueVal=blue3

// your code goes here to light the lights

blue2=blue1 //takes the value in blue1
blue1=blue3// takes last total

if the steps are too great, you could use the same number a couple times in a row or divide by some value to make the fadeup effect smoother.

Awesome tips everyone! This is a big learning experience for me, and I'm looking forward to mastering the interface... eventually :slight_smile:

Nice to hear, same goes for me... btw did you get the right behavior after you did what I said? :slight_smile: