The above is a picture of the neopixel we will be using. NeoPixels come in a variety of shapes and sizes:
Each NeoPixel contains a number of multicolor LED lights – each of which is called a pixel. The collection of pixels on a NeoPixel is called a strip. This terminology will become important when we start coding.
When I teach this course in person, the first step we do is solder wires to the NeoPixel. In the online version of the course, this is not practical but fortunately there is a way to use the NeoPixel without soldering.
First look at the back of your NeoPixel (shown here on the left)
You will need to connect three jumper wires to the NeoPixel:
If you turn your neopixel rightside up, you will see these marked as V+, G, and IN.
It is possible to connect wires to the neopixel by simply passing a jumper wire through these holes into the breadboard. In this case the breadboard is just holding the wires in place:
Let me start by repeated a paragraph we encountered in the Servo experiment which explained the line
#include <Servo.h>
Instead of writing all of the code themselves, software developers rely on code written by others. For example, if I wrote some code for an Arduino to control a Roomba vacuum cleaner: roomba.TurnLeft(45)
, roomba.TurnRight(90)
, roomba.Forward(10)
, I might share that code with others. This collection of shared procedures is called a library. Before you can use the procedures in a library you need load the library into your code. This is done with the include statement. So
#include <Servo.h>
instructs the Arduino IDE to include the Servo library and this allows us to use procedures like attach
,detach
, and write
. The Arduino IDE comes with a set of standard libraries we can use, including the Servo library. We can also install and use libraries written by others. For example, people might download and install my Roomba library and include it in their code:
#include <Roomba.h>
The company that makes the NeoPixel, Adafruit, has created a library that abstracts away some of the complexity of the NeoPixel and makes it easy for us to program it. We will need to download and install the library, and then include it in our code:
#include <Adafruit_NeoPixel.h>
First you will need to download the NeoPixel library. When you go to that page you should see a green download button on the right (a downward facing arrow followed by the word Code):
When you click that button you should see the popup:
Select “Download ZIP”.
After you download the file you will need to unzip it. This will create a folder called Adafruit_NeoPixel-master.
Here is the basic code:
#include <Adafruit_NeoPixel.h>
int neo = 3;
// in the line following these comments we define the neopixel strip
// Parameter 1 = number of pixels in strip - in this case 16
// Parameter 2 = Arduino pin number (most are valid) - in this case the neo variable above
// Parameter 3 = pixel type flags, add together as needed:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, neo, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, int wait) {
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
Running this code should give you a cool effect.
We have worked with a multicolor LED before. This one works differently. Here is the scoop. As with our original multicolor work, we specify values for red, green, and blue, but this time 0 means no color and 255 is the max color. To turn a particular pixel, a particular color is a 2 step process: first we must create the color using
strip.Color(r, g, b)
where r, g, b
are integers between 0 and 255 indicating the intensity of the red, green, and blue components, respectively. So, if we wanted to create the color red we would do
strip.Color(255, 0, 0)
That’s 255 for red and 0 for both green and blue
and if we wanted blue:
strip.Color(0, 0, 255)
and if we wanted purple we might do:
strip.Color(150, 0, 150)
Now we can set a particular pixel to a particular color using
strip.setPixelColor(i, c);
where i
is the number of the pixel and c
is a color. So if we want to set the first pixel to red we would do:
strip.setPixelColor(0, strip.Color(255, 0, 0));
and if we wanted to set the next pixel to blue we would do
strip.setPixelColor(1, strip.Color(0, 0, 255));
This command doesn’t actually turn on the pixel, which might seem screwy. It works like this. Suppose we have 16 people each with a variety of colored huge poster boards. We go down the line of people saying things like Person 1, when I say show, you hold up the red board, Person 2, the blue board and so on. We’ve instructed everyone what they are going to do and then we say:
strip.show();
delay(wait);
and those people hold up those boards. It’s the same with these lights.
Again,
strip.setPixelColor(1, strip.Color(0, 0, 255));
sets one of the pixels on the NeoPixel to blue. How would we set all 16 pixels to blue? Hopefully you are thinking a for loop. If we want to turn all the pixel to blue all at the same time we would do:
// make a blue color
uint32_t blue = strip.Color(0, 0, 255);
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
delay(wait);
So we first set all the pixels to blue and then, after that is done, we show them.
If we wanted them to turn blue one after another around the circle we would do:
// make a blue color
uint32_t blue = strip.Color(0, 0, 255);
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
Remember in one of the first experiments we talked about binary numbers? And we could safely forget about them until now. A color ranges from 0 to 255. That is 256 distinct values. To represent that we would need
128s column | 64s column | 32s column | 16s column | 8s column | 4s column | 2s column | 1s column |
---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
So that is 8 bits needed to represent the value of red, and 8 for green, and another 8 for blue. That is a total of 24 bits to represent a RGB number.
In the Arduino Uno, when we use an integer:
int led1 = 3;
The size limit of the integer is 16 bits which can represent numbers from -32,768 to 32,767. So an integer is 16 bits but we need 24 bits to represent an RGB value. An int
is just too small.
Another data type that the Arduino has goes by the name of uint32_t
. uint
is short for unsigned integer, which means it can only represent postive integers. That is fine for our case since we can’t have a negative number for a color value. The 32 in uint32_t
denotes how many bits there are—32. That is more than enough to hold the RGB value and that is why we have things like:
void colorWipe(uint32_t c, int wait) {
Can you modify the loop function so it wipes red, then wipes violet, then wipes blue, then wipes violet.
Can you create a function:
void redBluePassing(){
}
which changes the pixels from red to blue and back again. To test, change the loop function to:
void loop() {
redBluePassing();
}
It should look like
We are going to write a function that initially looks like:
void theaterChase(uint32_t c, int wait) {
}
The argument c
is the color, and wait
is the wait time.
We are going to code that function in steps.
write two loops in theaterChase
that will blink every third light on and then off for the wait
time. One loop turns every third pixel on. Outside the loop we will
strip.show();
delay(wait);
Then we will have another loop that turns them off and then after the loop, we have a show
and delay
.
For testing, replace the loop function with this one:
void loop() {
theaterChase(strip.Color(255, 0, 0), 500); // Red
theaterChase(strip.Color(0, 255, 0), 500); // Green
theaterChase(strip.Color(0, 0, 255), 500); // Blue
}
It should look like
Notice that 2 adjacent pixels blink – that’s fine.
Okay. So now inside the function theaterChase
you have 2 loops. One loop turns on every third led, the other loop turns them off. Enclose those two loops (as a unit) inside a larger loop that repeats the blinking ten times. The psuedo code is
Our code from the previous step looked something like
repeat 10 times:
for every third pixel:
turn it on
end for loop
strip show
delay
for every third pixel:
turn it on
end for loop
strip show
delay
end repeat
It should look like the second part of the previous video.
To illustrate this part let’s make a little table explaining what we did.
step | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | * | * | * | * | * | * |
Here we’ve number the lights 0 through 15 and we indicate which lights we are blinking with asterisks. And we repeat this one step 10 times. What we want to do is repeat 3 steps, 10 times. That is, step 1, step 2, step 3, step 1, step 2, step3 and so on. And we want the steps to look like:
step | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | * | * | * | * | * | * | ||||||||||
2 | * | * | * | * | * | * | ||||||||||
3 | * | * | * | * | * | * |
or the same idea represented by a picture:
Our code from the previous step looked something like
repeat 10 times:
for every third pixel:
turn it on
end for loop
strip show
delay
for every third pixel:
turn it on
end for loop
strip show
delay
end repeat
Let’s alter this in substeps.
Between the repeat and for add a loop three times line. For example:
repeat 10 times:
for p = 0, 1, and 2:
for every third pixel:
turn it on
end for loop
strip show
delay
for every third pixel:
turn it on
end for loop
strip show
delay
end for p
end repeat 10 times
Note that we added a for
loop but didn’t do anything substantive yet.
Remove the
strip show
delay
lines just before the end of the for p
loop.
Change the 500s in the loop function to 50s:
void loop() {
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color(0, 0, 127), 50); // Blue
}
In the turning pixels on loop you probably have something like:
strip.setPixelColor(i, c);
and something similar in the turn off loop Add plus p
to both lines:
strip.setPixelColor(i+p, c);
Add at least 3 more theaterChase
lines to the loop function to display different colors.
For this remix we are going to combine your red and blue passing in the night function with the theaterChase
one. Let’s call it:
void redAndBlueChasing(int wait){
}
So we want a chase pattern but the pixels will gradually change from red to blue and back again. It’s easier than you’d think! Seriously, it is – don’t laugh.
Recall that in theaterChase
the outer loop repeated the chase 10 times. To convert the function to go red to blue is pretty easy. You are going to change the outer loop to repeat 256 times – from 0 to 255 and then use the loop variable to set the color of the pixels. Easy peasy.
To go back again (from blue to red) here is what you do. Let’s call that big blog of code that repeats 256 times (including the first line with the for loop to the } ending the loop), the big for loop that repeats 256 times. Let’s copy the big for loop that repeats 256 times and paste it immediately after the big for loop that repeats 256 times. Now we have 2 the big for loop that repeats 256 times – one right after the other. In the second one you need to change a line so it goes blue to red.