RGB led runs in parallel?

Hey guys,

When a core is executing your code we all see the RBG led breathing cyan. The point is… is my code and the code that makes breath the RGB led running in parallel?

How could you make something similar but with an external LED, I mean, making it breath while you code is executing with no interruptions?

Thanks!

@clex, the breathing LED is a bit of an illusion in that it gets updated in the “background” firmware. The Core runs one big loop comprised of the background loop and the user loop() function. So, when the user loop() function ends, it passes control to the background loop and so on.

To do a breathing LED, you need to run code in loop() that changes the color of an LED over a defined time, using millis() for example to do the timing. Each time loop() runs, you check that a certain number of millis() has gone by and then run the code that updates the LED color.

unsigned long update = millis();

loop()
{

  if ((millis() - update) > 1000)  // if 1000ms or 1sec has elapsed
  {
    update = millis();  //reset the timer

    // CODE TO UPDATE THE LED
  }

} 

Notice that the code to update the LED only runs when the correct time has elapsed so it is “non-blocking” since loop() continues to run. By setting up different timers you can run different code at different intervals. :smile:

2 Likes

Actually the RGB led is controlled via 3 PWM outputs on Timer 1 I believe, and this is updated via an interrupt that is occurring every 1ms. It does this even when your user code is running.

The way to do something similar is to create a ISR routine of your own, and you can use @peekay123’s sweet IntervalTimer library: https://github.com/pkourany/SparkIntervalTimer

This is the essence of an interrupt service routine… it runs that code no matter what else is happening, and defined intervals. Granted there can be issues with multiple interrupt occurring at the same time, which is why interrupt have priorities assigned to them… and why you typically want to get in and out of your ISR as fast as possible… then do long math calculations or other time consuming things in your main user loop() one time-slice at a time.

2 Likes

Thanks @BDub and @peekay123 !! Really useful, I was confused. I’ve been looking at IntervalTimer library and works perfect. Seems like magic.

If I only need to make a LED breath, do I need to use the IntervalTimer library or with the code that peekay123 posted would be enough?

Following the example of @peekay123 of blinking a LED, I tried to make it breath, you know, changing the intensity of the bright, as RGB led does, but I don’t really know how to approach it. How could I do it?

// Callback for Timer 1
void blinkLED(void) {
  if (ledState == LOW) {
    ledState = HIGH;
    blinkCount = blinkCount + 1;  // increase when LED turns on
	PIN_MAP[ledPin].gpio_peripheral->BSRR = PIN_MAP[ledPin].gpio_pin; // LED High
  }
  else {
    ledState = LOW;
    PIN_MAP[ledPin].gpio_peripheral->BRR = PIN_MAP[ledPin].gpio_pin; // LED low
  }
}

Thanks!

I stole this from the Arduino IDE… just tested on Spark Core and it works:

int led = D0;       // LED pin
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by

void setup() {
  // declare pin D0 to be an output:
  pinMode(D0, OUTPUT);
}

void loop() {
  /*
   Fade
  
   This example shows how to fade an LED on pin D0
   using the analogWrite() function.
  
   This example code is in the public domain.
   */
  
  // Set the brightness of pin D0:
  analogWrite(led, 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);
}

1 Like