Go Down

Topic: LED Chasing Lights Progamming (Read 2 times) previous topic - next topic

Nick Gammon

To answer your first question, you could change:

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


to something like:

Code: [Select]

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.

Nick Gammon


Nick Gammon

This is how you can do it:

Code: [Select]
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).

Fennel Rye

#8
May 25, 2012, 02:06 am Last Edit: May 25, 2012, 02:08 am by Fennel Rye Reason: 1
Now we're getting somewhere! Here's the code I have now:

Code: [Select]
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: [Select]
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:
Fennel Rye

Nick Gammon

Code: [Select]

  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: [Select]
for (byte j = 0; j < 14; j++)
 doCircle (20);

Go Up