Pages: [1] 2   Go Down
Author Topic: LED Chasing Lights Progamming  (Read 2004 times)
0 Members and 1 Guest are viewing this topic.
Los Angeles, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Biyaaaa!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys,

So I have a code for a ring of LEDs to make them chase faster and faster.  I have the LEDs connected into the PWM pins arranged so that they are symmetrical, which is why the pins switching on and off in my code jump around a little. Here's the code:

Code:
void setup() {               
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT); 
}

void loop() {
  digitalWrite(1, HIGH);
  delay(500);             
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(500);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(500);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(500);
  digitalWrite(5, LOW);
  digitalWrite(7, HIGH);
  delay(500);
  digitalWrite(7, LOW);
  digitalWrite(6, HIGH);
  delay(500);
  digitalWrite(6, LOW);
  digitalWrite(8, HIGH);
  delay(500);
  digitalWrite(8, LOW);
  digitalWrite(12, HIGH);
  delay(500);
  digitalWrite(12, LOW);
  digitalWrite(9, HIGH);
  delay(500);
  digitalWrite(9, LOW);
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  digitalWrite(10, HIGH);
  delay(500);
  digitalWrite(10, LOW);
  digitalWrite(0, HIGH);
  delay(500);
  digitalWrite(0, LOW);
  digitalWrite(11, HIGH);
  delay(500);
  digitalWrite(11, LOW);
  digitalWrite(1, HIGH);
  delay(400);             
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  delay(400);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(400);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(400);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(400);
  digitalWrite(5, LOW);
  digitalWrite(7, HIGH);
  delay(400);
  digitalWrite(7, LOW);
  digitalWrite(6, HIGH);
  delay(400);
  digitalWrite(6, LOW);
  digitalWrite(8, HIGH);
  delay(400);
  digitalWrite(8, LOW);
  digitalWrite(12, HIGH);
  delay(400);
  digitalWrite(12, LOW);
  digitalWrite(9, HIGH);
  delay(400);
  digitalWrite(9, LOW);
  digitalWrite(13, HIGH);
  delay(400);
  digitalWrite(13, LOW);
  digitalWrite(10, HIGH);
  delay(400);
  digitalWrite(10, LOW);
  digitalWrite(0, HIGH);
  delay(400);
  digitalWrite(0, LOW);
  digitalWrite(11, HIGH);
  delay(400);
  digitalWrite(11, LOW);
  digitalWrite(1, HIGH);
  delay(300);             
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  delay(300);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(300);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(300);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(300);
  digitalWrite(5, LOW);
  digitalWrite(7, HIGH);
  delay(300);
  digitalWrite(7, LOW);
  digitalWrite(6, HIGH);
  delay(300);
  digitalWrite(6, LOW);
  digitalWrite(8, HIGH);
  delay(300);
  digitalWrite(8, LOW);
  digitalWrite(12, HIGH);
  delay(300);
  digitalWrite(12, LOW);
  digitalWrite(9, HIGH);
  delay(300);
  digitalWrite(9, LOW);
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  digitalWrite(10, HIGH);
  delay(300);
  digitalWrite(10, LOW);
  digitalWrite(0, HIGH);
  delay(300);
  digitalWrite(0, LOW);
  digitalWrite(11, HIGH);
  delay(300);
  digitalWrite(11, LOW);
  digitalWrite(1, HIGH);
  delay(200);             
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  delay(200);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(200);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(200);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(200);
  digitalWrite(5, LOW);
  digitalWrite(7, HIGH);
  delay(200);
  digitalWrite(7, LOW);
  digitalWrite(6, HIGH);
  delay(200);
  digitalWrite(6, LOW);
  digitalWrite(8, HIGH);
  delay(200);
  digitalWrite(8, LOW);
  digitalWrite(12, HIGH);
  delay(200);
  digitalWrite(12, LOW);
  digitalWrite(9, HIGH);
  delay(200);
  digitalWrite(9, LOW);
  digitalWrite(13, HIGH);
  delay(200);
  digitalWrite(13, LOW);
  digitalWrite(10, HIGH);
  delay(200);
  digitalWrite(10, LOW);
  digitalWrite(0, HIGH);
  delay(200);
  digitalWrite(0, LOW);
  digitalWrite(11, HIGH);
  delay(200);
  digitalWrite(11, LOW);
  digitalWrite(1, HIGH);
  delay(100);             
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  delay(100);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(100);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(100);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(100);
  digitalWrite(5, LOW);
  digitalWrite(7, HIGH);
  delay(100);
  digitalWrite(7, LOW);
  digitalWrite(6, HIGH);
  delay(100);
  digitalWrite(6, LOW);
  digitalWrite(8, HIGH);
  delay(100);
  digitalWrite(8, LOW);
  digitalWrite(12, HIGH);
  delay(100);
  digitalWrite(12, LOW);
  digitalWrite(9, HIGH);
  delay(100);
  digitalWrite(9, LOW);
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
  digitalWrite(10, HIGH);
  delay(100);
  digitalWrite(10, LOW);
  digitalWrite(0, HIGH);
  delay(100);
  digitalWrite(0, LOW);
  digitalWrite(11, HIGH);
  delay(100);
  digitalWrite(11, LOW);
  digitalWrite(1, HIGH);
 
}

Now, at the end of this code, I want the 6 PWM LEDs to begin pulsing (fading in and out) in an endless loop. I tried using this code:

Code:
analogWrite(9, brightness);   

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }     
  // wait for 30 milliseconds to see the dimming effect   
  delay(30);                           
}

at the end of it (I also set int brightness = 0 and int fadeAmount= 5 before the setup), but it did not work correctly. What's the best way to go about this? I've searched around but am having trouble finding the answer.  Thanks, guys!
« Last Edit: May 23, 2012, 07:24:16 pm by Fennel Rye » Logged

Fennel Rye

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1271
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

(brightness == 0 || brightness == 255)

The problem here is that if fadeamount does not make it get to exactly 255 or exactly 0, then it won't work. Try

(brightness <= 0 || brightness >= 255)

Also, what did not work?
« Last Edit: May 23, 2012, 08:37:00 pm by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  digitalWrite(1, HIGH);
  delay(500);             
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(500);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(500);

blah blah...

If I may suggest a fairly big simplification:

Code:
const int numberOfLEDs = 14;

const byte LEDorder [numberOfLEDs] = { 1, 2, 3, 4, 5, 7, 6, 8, 12, 9, 13, 10, 0, 11 };

void setup() {               
  for (byte i = 0; i < numberOfLEDs; i++) 
    pinMode(LEDorder [i], OUTPUT);
}  // end of setup

void doCircle (const unsigned long delayAmount)
  {
  for (byte i = 0; i < numberOfLEDs; i++)
    {
    byte pin = LEDorder [i];
    digitalWrite(pin, HIGH);
    delay(delayAmount);             
    digitalWrite(pin, LOW);
    }   // end of for
  }  // end of doCircle
 
void loop()
  {
  for (unsigned long n = 500; n > 0; n -= 100)
    doCircle (n);
  } // end of loop

Then we can look at the problem with the pulsing.
Logged


Los Angeles, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Biyaaaa!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ahhhh. smiley-roll-sweat That is much better. Thank you, Nick. The one thing I understood how to do with the old cumbersome code that I do not with your new, nice and clean code is that once it reaches it's fastest spinning speed (which I would like to be a delay of 10 between lights) I'd like it to spin around at that speed ten times and then begin the pulsing.

My LEDs are very, very bright and I've been getting a bit of a headache working on this. It's too hard for me to not stare at the pretty, blinky LEDs.  If I wanted to set them all at a lower brightness, would I just change digitalWrite(pin, HIGH) into digitalWrite(pin, 100) or something like this? Thanks so much.
« Last Edit: May 24, 2012, 04:01:30 pm by Fennel Rye » Logged

Fennel Rye

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

My LEDs are very, very bright and I've been getting a bit of a headache working on this. It's too hard for me to not stare at the pretty, blinky LEDs.  If I wanted to set them all at a lower brightness, would I just change digitalWrite(pin, HIGH) into digitalWrite(pin, 100) or something like this? Thanks so much.

Something like, but not that.  digitalWrite is as it's name says, digital.  On or off.

You have to use analogWrite to vary the brightness.  Only a select number of the pins on the Arduino support analogWrite though.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

To answer your first question, you could change:

Code:
for (unsigned long n = 500; n > 0; n -= 100)
    doCircle (n);

to something like:

Code:
doCircle (500);
 doCircle (400);
 doCircle (300);
 doCircle (200);
 doCircle (200);
 doCircle (100);
 doCircle (100);

Or even use a table of delays (like the table of pins further up).

Quote
If I wanted to set them all at a lower brightness, would I just change digitalWrite(pin, HIGH) into digitalWrite(pin, 100) or something like this?

No that won't work. digitalWrite is either on or off.

I did something along those lines a while back, but can't find it. Maybe someone else can. Basically it used a timer to establish a "PWM frequency" and then detect that in an interrupt to make all the pins into PWM pins.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here:

http://arduino.cc/forum/index.php?topic=103572.0
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is how you can do it:

Code:
volatile byte wantedPin;   // which pin to pulse on and off

const byte PWMiterations = 40;
const byte PWMdutyCycle = 2;   // <-- should be less than PWMiterations

volatile byte pwmCount;

ISR(TIMER1_COMPA_vect)
{

  // if in "on" cycle turn the LED on
  if (pwmCount > PWMdutyCycle)
    digitalWrite(wantedPin, LOW);      
  else
    digitalWrite(wantedPin, HIGH);      
  
 if (++pwmCount >= PWMiterations)
   pwmCount = 0;
}  // end of TIMER1_COMPA_vect

const int numberOfLEDs = 14;

const byte LEDorder [numberOfLEDs] = { 1, 2, 3, 4, 5, 7, 6, 8, 12, 9, 13, 10, 0, 11 };

void setup()
  {                
  for (byte i = 0; i < numberOfLEDs; i++)  
    pinMode(LEDorder [i], OUTPUT);
    
  // set up Timer 1
  TCCR1A = 0;          // normal operation
  TCNT1 = 0;           // make sure we start at zero
  TCCR1B = _BV(WGM12) | _BV(CS10) | _BV (CS12);   // CTC, scale to clock / 1024
  OCR1A =  5;       // compare A register value (1000 * clock speed / 1024)
  TIMSK1 = _BV (OCIE1A);             // interrupt on Compare A Match
    
  }  // end of setup

void doCircle (const unsigned long delayAmount)
  {
  for (byte i = 0; i < numberOfLEDs; i++)
    {
    noInterrupts ();
    byte pin = LEDorder [i];
    wantedPin = pin;
    pwmCount = 0;
    interrupts ();
    delay(delayAmount);              
    digitalWrite(pin, LOW);
    }   // end of for
  }  // end of doCircle
  
void loop()
  {
  for (unsigned long n = 500; n > 0; n -= 100)
    doCircle (n);
  } // end of loop

Change the constant PWMdutyCycle to get it brighter or less bright. Right now it is fairly dull (2 / 40 cycles on, the rest off).
Logged


Los Angeles, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Biyaaaa!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Now we're getting somewhere! Here's the code I have now:

Code:
const int numberOfLEDs = 14;

const byte LEDorder [numberOfLEDs] = { 1, 2, 3, 4, 5, 7, 6, 8, 12, 9, 13, 10, 0, 11 };

void setup() {               
  for (byte i = 0; i < numberOfLEDs; i++) 
    pinMode(LEDorder [i], OUTPUT);
}  // end of setup

void doCircle (const unsigned long delayAmount)
  {
  for (byte i = 0; i < numberOfLEDs; i++)
    {
    byte pin = LEDorder [i];
    digitalWrite(pin, HIGH);
    delay(delayAmount);             
    digitalWrite(pin, LOW);
    }   // end of for
  }  // end of doCircle
 
void loop()
  {
 doCircle (500);
  doCircle (450);
  doCircle (400);
  doCircle (350);
  doCircle (300);
  doCircle (250);
  doCircle (200);
  doCircle (150);
  doCircle (100);
  doCircle (90);
  doCircle (80);
  doCircle (70);
  doCircle (60);
  doCircle (50);
  doCircle (40);
  doCircle (30);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);

 
  } // end of loop

And it's doing it's speed up and then stay at a 20 delay perfectly.  Now I'm trying to implement the pulsing after it does it's cycle of doCircle (20)'s by using a modified version of your 'fading 20 LEDs' code, but I'm running into problems. I tried this on it's own as an experiment:

Code:
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

const byte pwmPin = 3;
const byte maxPin = 11;

ISR (PCINT0_vect)
 {
static byte val = 0;

 val = !val;
 for (byte i = 0; i <= maxPin; i++)
   if (i != pwmPin)
     digitalWrite (i, val);
 }
 
void setup()
  {
  for (byte i = 0; i <= maxPin; i++)
    pinMode (i, OUTPUT);

  // pin change interrupt
  PCMSK0 = _BV (PCINT1);  // only want pin 9
  PCIFR  = _BV (PCIF0);   // clear any outstanding interrupts
  PCICR |= _BV (PCIE0);   // enable pin change interrupts for PCINT7..0
  }   // end of setup

void loop() 
  {
  // set the brightness of pin 9:
  analogWrite(pwmPin, brightness);   

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255)
    fadeAmount = -fadeAmount ;

  // wait for 30 milliseconds to see the dimming effect   
  delay(30);                           
}  // end of loop

I changed the 'maxPin' to 11, because I didn't want all the LEDs to fade in and out at once (I don't have sufficient power so I only want pins 3, 5, 6, 9, 10, and 11 pulsing) but I only got the pin 3 LED fading.  I'm assuming I'm not understanding the maxPin.  Just tried your brightness limiting code and it worked perfectly. You're helping so much, Nick.  I really aprecciate it.  I apologize for the neverending questions, but it's exciting to be learning this stuff, however slow that process may be.  You've gotten me to the point where this thing is almost finished!  Now I just need it to end with the pulsing loop and have it all activated by a button push.  Hehe.  smiley-roll-blue
« Last Edit: May 24, 2012, 07:08:26 pm by Fennel Rye » Logged

Fennel Rye

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);
  doCircle (20);

Think "loops".

Code:
for (byte j = 0; j < 14; j++)
  doCircle (20);
Logged


Los Angeles, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Biyaaaa!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
for (byte j = 0; j < 14; j++)
  doCircle (20);

Little confused about bytes.  Where are you getting the names 'i' and 'j' from for these bytes?  I understand that they are there to store a number, but I'm getting confused on where the letters are coming from.
Logged

Fennel Rye

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this, it fades a group of LEDs on and off. After that do a bit of experimenting. smiley

Code:
const int numberOfLEDs = 14;

volatile byte wantedPins [numberOfLEDs] =  { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 };   // which pin to pulse on and off

const byte PWMiterations = 40;
byte PWMdutyCycle;   // <-- should be less than PWMiterations

volatile byte pwmCount;

ISR(TIMER1_COMPA_vect)
{
byte i;

  if (pwmCount > PWMdutyCycle)
    {
    // turn all off
    for (i = 0; i < numberOfLEDs; i++)
      digitalWrite(i, LOW);     
    }
  else
    {
    // turn wanted ones on
    for (i = 0; i < numberOfLEDs; i++)
      if (wantedPins [i])
        digitalWrite(i, HIGH);     
    }
   
   
 if (++pwmCount >= PWMiterations)
   pwmCount = 0;
}

void setup()
  {               
  for (byte i = 0; i < numberOfLEDs; i++) 
    pinMode(i, OUTPUT);
   
  // set up Timer 1
  TCCR1A = 0;          // normal operation
  TCNT1 = 0;           // make sure we start at zero
  TCCR1B = _BV(WGM12) | _BV(CS10) | _BV (CS12);   // CTC, scale to clock / 1024
  OCR1A =  5;       // compare A register value (1000 * clock speed / 1024)
  TIMSK1 = _BV (OCIE1A);             // interrupt on Compare A Match
   
  }  // end of setup

 
void loop()
  {
  for (PWMdutyCycle = 0; PWMdutyCycle < PWMiterations; PWMdutyCycle++)
    delay (100);

  for (PWMdutyCycle = PWMiterations; PWMdutyCycle > 0; PWMdutyCycle--)
    delay (100);
   
  } // end of loop

Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Where are you getting the names 'i' and 'j' from for these bytes?


Code:
for (byte j = 0; j < 14; j++)

That declares "j" as in:

Code:
byte j
Logged


Los Angeles, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Biyaaaa!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

But what is byte j? Are you creating and naming a byte with that declaration or is byte j something that already exists that you are calling upon? 
Logged

Fennel Rye

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It is created at that point as a loop variable.
Logged


Pages: [1] 2   Go Up
Jump to: