In my last post, I showed you how to decode and understand the common color patterns and modes given off by the RGB LED on every Particle device. Today, I want to go one step further and show you how you too can control that powerful little LED in your own apps.
The Particle Device OS exposes two classes that you can interact with the control the onboard RGB LED: the RGB
class and the LEDStatus
class. I’ll walk though examples of both, with the help of a few demos. Before you read on, check out this quick video where I show off both and provide a quick overview of these important classes.
Using the RGB Class
First, let’s take a look at the RGB
Class, which allows you to set the red, green, and blue values for the LED, and control brightness. To show this off, I built a little project with four potentiometers or “pots” each connected to an analog pin on a Particle Photon.
Each pot is an analog device, and when connected to an analog pin on a Photon or Electron, will yield a value between 0
and 4095
, depending on the position of the dial. In the case of my pots above, the maximum left position is 4095
, with the right being 0
. So, to get a value from one of those analog pins into a 0 to 255 range, I’ll divide the result of an analogRead
by 16, and subtract the result from 255.
int red = 255 - analogRead(RED_POT) / 16; int green = 255 - analogRead(GREEN_POT) / 16; int blue = 255 - analogRead(BLUE_POT) / 16; int brightnessPotVal = 255 - analogRead(BRIGHTNESS_POT) / 16;
To start using the RGB
class, I need to first take control of the LED using the control method.
RGB.control(true);
Now, I can call the color and brightness methods to set those values.
RGB.color(red, blue, green); RGB.brightness(brightnessPotVal);
Now, as I turn the dials, things change!
It turns out, there’s an even easier way to control the red, green, and blue values! With the mirrorTo()
method, you can tell the Device OS which analog pins represent the red, green, and blue values, and Particle takes care of the rest!
RGB.mirrorTo(RED_POT, GREEN_POT, BLUE_POT);
Important note: When you’re done using the RGB class, make sure you yield control back to the Device OS by calling RGB.control(false)
so your device can use its normal modes to communicate with you!
Using the LEDStatus Class
The RGB
class is powerful, but there’s another way you can control the colors on the RGB LED, and perform signaling for your own apps: the LEDStatus
class. It’s also the recommended way. Even better, it works without taking total control of the LED, so your device can still notify you, if it needs to. The LEDStatus
class allows you to specify a signal pattern, speed and color, and has plenty of overloads and enums to help you. Check out the docs for more info on everything you can do with the LEDStatus
class.
For this demo, I created a simple mobile app using NativeScript and Vue.js. The app has sliders for controlling red, green, and blue values, a selector for the blink speed, and switches to take control and signal your device. I won’t cover the specifics of how I built the app here, but I did a write up over on Hackster if you’re interested in seeing how to use NativeScript and Vue to build mobile apps for your Particle projects.
On the firmware side, since I’m controlling the LED with an app, I need to expose a few functions as Particle cloud functions:
Particle.function('setRed', setRed); Particle.function('setGreen', setGreen); Particle.function('setBlue', setBlue); Particle.function('setBlinkRate', setBlink); Particle.function('toggleCtrl', toggleCtrl);
Each function is simple; it takes the argument from the app (like the value of the red slider) and sets a variable that the LEDStatus
class will use later:
int setRed(String val) { redValue = val.toInt(); return 1; }
toggleCtrl
, the last function in the list, allows me to trigger when the app wants to manage the RGBLed and, if controlled, to pass in the red, green, blue and blink values to my function.
if (isAppControlled) { useLEDStatusClass(redValue, greenValue, blueValue, blinkRateValue); }
The LEDStatus
class is also defined as a global instance so that I can keep it active while it’s being controlled through the app.
LEDStatus blinkLED;
Unlike the RGB
class, which takes separate integer values between 0 and 255 to control the red, green, and blue values, the LEDStatus class expects a 32-bit integer with a hexadecimal representation of the color (like 0x00ff0000 for red). Thankfully, we can do a bit of bit-shifting and masking in C to easily turn the integer values from the app into a single hex value:
unsigned long RGBHex = (red << 16) | (green << 8) | blue;
I also need to convert the speed selection from the app into an LEDSpeed
Enum value.
switch(blinkRate) { case 0: blinkSpeed = LED_SPEED_SLOW; break; case 1: blinkSpeed = LED_SPEED_NORMAL; break; case 2: blinkSpeed = LED_SPEED_FAST; break; }
Now, I’m ready to set the color, pattern, speed, and then activate the LED if it’s not already:
blinkLED.setColor(RGBHex); blinkLED.setPattern(LED_PATTERN_BLINK); blinkLED.setSpeed(blinkSpeed); if (!blinkLED.isActive()) blinkLED.setActive(true);
Take your exploration further
If you’re building a Particle-powered project, and you need to notify your customers of a status or important change, consider using the LEDStatus
or RGB
classes. Beyond what I covered here today, you can customize the themes Particle uses for mode signaling, and even set up custom, complex patterns of your own.
To learn more about the mobile app I created for the second demo, check out the write up I did on it over at Hackster.io. Hopefully this guide has helped you learn something new about this little LED. If you have any questions, comments, or need help resolving an issue with your Particle-powered apps, visit us over on the Community Forums. We’d love to hear from you!