Experiment 11: NeoPixel

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)

link to larger image

You will need to connect three jumper wires to the NeoPixel:

  • one to one of the power 5V holes
  • one to one of the power signal ground holes
  • one to Data Input

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:

link to larger image

Hardware Hookup

link to larger picture

Libraries

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 NeoPixel Library

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>
Download the library

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”.

Install the library

After you download the file you will need to unzip it. This will create a folder called Adafruit_NeoPixel-master.

  • Rename the folder Adafruit_NeoPixel (removing the -master suffix)
  • move the folder to your Arduino/libraries folder. The Arduino folder is typically in your Documents directory

The Basic Code

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.

READ THIS. Some important lines in the above.

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);
      }

unit32_t

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) {

Remix 1. ExtraWipes (easy)

Can you modify the loop function so it wipes red, then wipes violet, then wipes blue, then wipes violet.

Remix 2. Red and Blue Passing in the Night (medium)

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

Remix 3. TheaterChase (hard)

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.

Step 3. The challenging bit.

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.

substep 1

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.

substep 2

Remove the

     strip show
     delay

lines just before the end of the for p loop.

substep 3

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
}

substep 4

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);

substep 5 Test your code. It should be awesome

substep 6 Add more colors. It should be most awesome

Add at least 3 more theaterChase lines to the loop function to display different colors.

Remix 4. Red and Blue Chasing Each Other in the Night (medium)

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.

now you have code that chases from red to blue

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.


Next section: