The modulo operator and the "if" statement are two fantastic utilities that you can use to rotate between settings on a device. We'll demonstrate both with a project that cycles between four color settings on an LED light.
Ring Light projectWe'll be trying this out by building a ring light, which is great for mobile video. It uses a DigiSpark to control a 24-LED ring of NeoPixels, and runs on a 5V rechargeable USB power bank. It has four modes that are switched with the press of a button.
One huge factor in video quality is the amount of light you can focus on the subject. The quality of that light is also important: harsh light is unflattering and unwelcoming; you can temper the office fluorescents with some warm yellow, or blend some bright white with your home lights to create the perfect environment.
The circuitThe whole thing runs on a DigiSpark, which is an excellent breakout board for the ATtiny that makes programming a breeze.
- My NeoPixel ring is soldered into 5V, GND, and pin 1.
- There's a slide switch in the power line, so I can easily turn it off to save power, without changing the light setting I was on.
- Finally, the button is soldered between 5V and pin 2.
I smashed some button code into Adafruit's "simple" NeoPixel example. I created separate variables for the red, green, and blue channels (rVal
, gVal
, bVal
) so that I can produce different qualities of light.
Once the button is pressed, all colors turn on at full brightness (255). There's a delay
variable that functions in two ways: to debounce the button (so it doesn't read multiple presses), and to "wipe" the color around the ring in an aesthetically pleasing way.
Say you have a value that increases by 1, each time your loop
code runs. The modulo ( %
) divides that number by another number – typically the number of modes – and uses the remainder to control things:
colorMode = (colorMode + 1) % 4;
In this case, I have a variable that rotates between four color modes. The colorMode
variable increments (adds one) each time you push the button, and that's what tells the later code which colors to set. Notice the % 4
at the end – it's a modulo operator, which means that the variable should loop through four states (0-3). Once it's hit 3, on the next round, it starts again at 0 instead of going on to 4. This is really useful for any project that can run in several modes.
This is because when colorMode
is 0, if you divide it by 4, there are 0 fours and 0 left over. When it's 1, there are still 0 fours, with a remainder of 1. Divide 2 by 4, and you get 0 fours and 2 left over: lighting mode "2" is activated. And 3 contains no fours, with 3 left over. When colorMode
reaches 4, there is one 4 and – back to 0 left over. The variable never gets above that, in this case, but it could keep going forever and you'd just keep cycling between those 4 values.
Now, let's feed the result into an if
statement that controls the light itself:
if (colorMode == 1) {
// warm light
rVal = 255;
gVal = 200;
bVal = 100;
} else if (colorMode == 2) {
// dim white
rVal = 100;
gVal = 100;
bVal = 100;
} else if (colorMode == 3) {
// dim, warm light
rVal = 100;
gVal = 80;
bVal = 40;
} else {
// back to full brightness, all white
rVal = 255;
gVal = 255;
bVal = 255;
}
Note the three types of controllers here: if
, if else
, and else
. You can use if
on its own, or provide however many extra options you want with the else if
modes, then account for any other cases with else
.
The light starts at full brightness (white), then goes to a bright, warm light, then dim white, then dim warm light, then back to full brightness again. If you want to add another mode, just put it in with another else if
statement before the final else
.
Sharp eyes will note that this "if" statement itself is nested inside another "if", which detects the button press – just like in our original Button example sketch. So, if the button is never pressed, none of this code is run at all.
Colors: The NeoPixels take the three brightness values for red, green, and blue in different ratios. By decreasing blue, we get a yellowy light, and by taking the green down a bit less, it becomes a nice, warm, slightly orange color. And for the dim lights, I've reduced each channel to 40% of its original brightness.
Next stepsObviously, this needs some kind of enclosure. I might 3D-print one out of white PLA, to help diffuse the light without blocking it.
Future versions may include a simple two-slider setup: one for brightness, one for warmth. But I like this control system because it's easy to return to the same exact settings.
Stay tuned for more tutorials in the Hackster 101 series!
Comments
Please log in or sign up to comment.