Go Down

Topic: Flash multiple LEDs with different frequencies (Read 126 times) previous topic - next topic

Recently I needed to write an Arduino program to turn on/off multiple LEDs at different frequencies while still allowing other code to run. To solve this, I used the built-in interrupt timer to check when each LED should be turned on/off. Each LED can be turned on with a frequency up to 500 Hz. I thought other people might find the code useful so I'm posting it here. Let me know if you have any questions or suggestions.
Thanks!
-Chris

Code: [Select]

// Chris Torrence, Jan 2019
// License: CC BY
//
// Reference: https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers
//
int playFrequencyDelay[12] = {0};

// Freq is the frequency of blinking in blinks per second
// pin = 2 to 13
void playFrequency(float freq, int pin)
{
  float freq1 = freq;
  if (freq1 > 500) freq1 = 500;
  if (pin >= 2 && pin <= 13)
  {
    if (freq1 > 0) {
      pinMode(pin, OUTPUT);
      playFrequencyDelay[pin - 2] = (int) (500/freq1 + 0.5);
    } else {
      playFrequencyDelay[pin - 2] = 0;
    }
  }
}

// pin = 2 to 13
void stopPlayFrequency(int pin)
{
  if (pin >= 2 && pin <= 13)
  {
    playFrequencyDelay[pin - 2] = 0;
    digitalWrite(pin, LOW);
  }
}

// Used by hd_PlayFrequency
// Interrupt is called once a millisecond
SIGNAL(TIMER0_COMPA_vect)
{
  unsigned long t = millis();
  for (int pin = 2; pin <= 13; pin++)
  {
    // See if our current time is a multiple of the desired LED period
    if (playFrequencyDelay[pin - 2] != 0 && (t % playFrequencyDelay[pin - 2]) == 0)
    {
      digitalWrite(pin, 1 - digitalRead(pin));
    }
  }
}

void setup() {
  // Use Timer0 (millis) for playFrequency
  OCR0A = 0xAF;
  TIMSK0 |= _BV(OCIE0A);
 
  // Let's test the code
  playFrequency(0.5,13);
  playFrequency(1,12);
  playFrequency(2,11);
  playFrequency(5,10);
  playFrequency(10,9);
  delay(10000);
  stopPlayFrequency(13);
  stopPlayFrequency(12);
  stopPlayFrequency(11);
  stopPlayFrequency(10);
  stopPlayFrequency(9);
}

void loop() {
}

vaj4088

Thanks, but how is this better than using millis() or micros() and not having to use timers or interrupts?


Go Up