Pages: [1]   Go Down
Author Topic: Arduino can't fade 2 LEDs at same time?  (Read 952 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone, I'm trying to create an lighting effect with my arduino but I'm running into a bit of a problem. I have 13 LEDs hooked up in a row on my breadboard, connected to pins 1-13. The first led in the row is hooked to pin 11, and the last led is hooked to pin 2, which I understand to both be PWM pins. The effect I'm going for is for the first LED (hooked to pin 11) to start out at it's brightest, fade a bit, then the leds between the first and the last to turn on and off in order until they reach the last LED which brightens a bit, and so on, and so on until the first LED is off, and the last LED is at it's brightest, then it reverses going from last to first.

Whats happening instead is it works one way (from first LED to last), then when the order reverses the first LED just blinks on and off instead of fading up its brightness.

I'm new to C++ programming, so I'm wondering if I've messed up something in my code. Can someone take a look and let me know if they see anything that would cause this behavior?

Code:
int leds[]= {13, 12, 10, 9, 8, 7, 6, 5, 4, 2, 1};
int digLeds = 11;
int timer = 30;
int fadeLEDfront = 11;
int fadeLEDback = 3;

void setup() {
  for(int j = 0; j < digLeds; j++){
    pinMode(leds[j], OUTPUT);
  }
  analogWrite(fadeLEDfront, 255);
  analogWrite(fadeLEDback, 0);
}

void loop() {
  // LEDs pulse front to back
  for( int fade = 15; fade <= 255; fade += 15 ){
    analogWrite(fadeLEDfront, 255 - fade);
    for( int i = 0; i < digLeds; i++){
      digitalWrite(leds[i], HIGH);
      delay(timer);
      digitalWrite(leds[i - 1], LOW);
      delay(timer);
    }
    analogWrite(fadeLEDback, fade);
    digitalWrite(leds[digLeds - 1], LOW);
    delay(timer*3);
  }
 
  randomLightShow();

  //LEDs pulse back to front 
  for( int fade2 = 15; fade2 <= 255; fade2 += 15 ){
    analogWrite(fadeLEDback, 255 - fade2);
    for( int i = digLeds; i >= 0; i--){
      digitalWrite(leds[i], HIGH);
      delay(timer);
      digitalWrite(leds[i + 1], LOW);
      delay(timer);
    }
    analogWrite(fadeLEDfront, fade2);
    digitalWrite(leds[0], LOW);
    delay(timer*3);
  }
 
  randomLightShow();
  ledsOff();
   
}

void ledsOff(){
  for( int n = 0; n < digLeds; n++ ){
    digitalWrite(leds[n], LOW);
  }
}

//lights up LEDs randomly for random length of time
void randomLightShow(){
 
  int ranCycles = random(10,50);
  for( int r = 0; r < ranCycles; r++ ){
    int ranLength = random(1, digLeds);
    int ranArr[ranLength];
    ledsOff();
   
    //pick random LEDs
    for(int b = 0; b < ranLength -1; b++ ){
      int ranLED = random(0, digLeds);
      ranArr[b] = leds[ranLED];
    }
   
    for (int j = 0; j < ranLength -1; j++) {
      digitalWrite(ranArr[j], HIGH);
    }
    delay(timer);
    ledsOff();
  }
 
}
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 515
Posts: 31567
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The first led in the row is hooked to pin 11, and the last led is hooked to pin 2, which I understand to both be PWM pins
What board are you using:-
Quote
On most Arduino boards (those with the ATmega168 or ATmega328), this function works on pins 3, 5, 6, 9, 10, and 11. On the Arduino Mega, it works on pins 2 through 13. Older Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11.

Code:
int leds[]= {13, 12, 10, 9, 8, 7, 6, 5, 4, 2, 1};
Pin 1 is normally used for serial communications and should be avoided if possible.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 553
Posts: 46300
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Arduino can fade any number of LED at the same time. Not using delay(), though. That function absolutely, positively, has to do.

Read, understand, and embrace the blink without delay example.

It will, of course, require a complete rewrite of your program.
Logged

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

Quote
What board are you using:-
Arduino Uno, the diagram next to the pins says pins 11, 10, 9, 6,5, and 3 are pwm pins.

Quote
Pin 1 is normally used for serial communications and should be avoided if possible.
Ah, good to know. I'm going to take the LED out of that pin then.

Quote
The Arduino can fade any number of LED at the same time. Not using delay(), though. That function absolutely, positively, has to do.
Wait... so why does it work one way but not the other then?
« Last Edit: January 04, 2013, 04:38:35 pm by RaveCraft » Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The Arduino can fade any number of LED at the same time. Not using delay(), though. That function absolutely, positively, has to do.
Wait... so why does it work one way but not the other then?

The simplified but not totally accurate explanation is that if you use delay, you can only do one thing at a time, because you can't do anything else while you are waiting for the delay call to complete.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Temple, Texas
Offline Offline
Sr. Member
****
Karma: 14
Posts: 354
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The fact that it works "going forward" suggests your approach might work (if you are happy with how it is working "forward").
But, there is a bug in your "backward" code.  This is the correction:

Code:
//LEDs pulse back to front
  for( int fade2 = 15; fade2 <= 255; fade2 += 15 ){
    analogWrite(fadeLEDback, 255 - fade2);
    for( int i = digLeds-1; i > 0; i--){       // <<<<<<<<<<<<<<<<<<<<<<<<
      digitalWrite(leds[i-1], HIGH);          // <<<<<<<<<<<<<<<<<<<<<<<<
      delay(timer);
      digitalWrite(leds[i], LOW);              // <<<<<<<<<<<<<<<<<<<<<<<<
      delay(timer);
    }
    analogWrite(fadeLEDfront, fade2);
    digitalWrite(leds[0], LOW);
    delay(timer*3);
  }


Cheers,
John
Logged

Offline Offline
Edison Member
*
Karma: 20
Posts: 2116
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
// Fade all IO by Osamu Iwasaki
// November 10, 2010

#include <MsTimer2.h>

#define OUT_MIN 0  // First pin
#define OUT_MAX 19  // Last pin (this includes the analog pins)

byte luminance[20];
byte lumi[20] = {};

void setup()
{
 int i;

 for(i = OUT_MIN; i <= OUT_MAX; i++){
   pinMode(i, OUTPUT);
   digitalWrite(i,LOW);
 }


 for(i = OUT_MIN; i <= OUT_MAX; i++){
   digitalWrite(i,HIGH);
   delay(150);
 }
 for(i = OUT_MIN; i <= OUT_MAX; i++){
   digitalWrite(i,LOW);
   //delay(50);
 }
 delay(1000);

 MsTimer2::set(1, int_pwm);
 MsTimer2::start();
}


void int_pwm() {

 static int f_wait[20];
 static int f_max_time[20];
 static int f_speed[20];
 static int f_ct[20];
 static long f_interval[20];

 static int ch;

 for(ch = OUT_MIN; ch <= OUT_MAX; ch++){
   if(f_wait[ch] == 0){
     f_wait[ch] = f_speed[ch] + 1;

     if( (f_ct[ch] < 255) )
       if(luminance[ch] != 255)
         luminance[ch] ++;

     if(f_ct[ch] == 255){
       if(f_max_time[ch] == 0)
         f_max_time[ch] = 0; // On Max Time
       else
         f_max_time[ch] --;
     }

     if( (f_ct[ch] > 255) && (f_ct[ch] < 511) && (f_max_time[ch] == 0))
       if(luminance[ch] != 0)
         luminance[ch] --;

     if(f_ct[ch] >= 511){
       if(f_interval[ch] == 0){
         f_interval[ch] = 10 * random(100); // fading seed
         f_speed[ch] = random(100); // fading speed
         f_ct[ch] = 0;
       }
       else
         f_interval[ch] --;
     }
     else
       f_ct[ch] ++;
   }
   f_wait[ch] --;
 }
}

void fading(){

 static byte counter = 0;
 static boolean prev_off[20];
 int i;

 for(i = OUT_MIN; i <= OUT_MAX; i++){
   if(lumi[i] == 0){
     if(prev_off[i] == HIGH){
       digitalWrite(i,LOW);
       prev_off[i] = LOW;
     }
   }
   else
     lumi[i] --;
 }

 counter --;

 if(counter == 0){
   for(i = OUT_MIN; i <= OUT_MAX; i++){
     if(luminance[i]){
       digitalWrite(i,HIGH);
       prev_off[i] = HIGH;
     }
     lumi[i] = luminance[i];
   }
 }
}


void loop(){
 fading();
}

upload that and run it.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You sure can fade multiple leds, with delays.

Here is an example:

Code:
  time_mask=0x80;
  do {
    //fade led0
    if (dc0 & time_mask) digitalWrite(LED0, HIGH);
    else digitalWrite(LED0, LOW);

    //fade led1
    if (dc1 & time_mask) digitalWrite(LED1, HIGH);
    else digitalWrite(LED1, LOW);

    ...
    time_mask = time_mask >> 1;  //reduce time
    delayMicroseconds(time_mask); //waste some time
  } while (time_mask);

dc0/dc1 are duty cycles for led0/led1.

you can add as many leds there to fade.
Logged

Pages: [1]   Go Up
Jump to: