After last week’s awesome meetup, I’ve had a few members reach out with follow up questions about Arduino, NeoPixels, and next steps to creating their own hardware creations. This document will serve as a basic guide to Arduino and the NeoPixel library, and I’ll go through a couple of very basic sketches. I’ll follow up with some more detailed projects later. Of course, all I’m really doing is collecting and distilling existing information into one post, so if you’re looking for more information about Arduino or NeoPixels, check the links below for more info.
- Adafruit’s NeoPixel Guide provides a great overview of what the WS2812 LEDs (aka NeoPixels) are and how to get started with them.
- Arduino’s Getting Started Guide contains a bunch of information about the Arduino project, including documentation about the projects history, compatible boards, and how to use the IDE.
- Arduino Nano Hardware Page has some basic information about the Arduino Nano. The boards distributed at the meetup were Arduino Nano clones, so most of the information about the Nano is correct. The major difference between the clones and the “Genuine” Arduinos is that the clones use a CH340G USB-Serial converter as opposed to a FTDI USB-Serial converter.
Arduino is an open source hardware and software platform that was developed to make hardware and software development more accessible to anyone interested. It started as a project in Italy as an extension of another open source software project. The first boards shipped in 2005, and since then, the project has grown significantly. Since the board designs and the software that powers them is open source, the Arduino community has grown significantly since its start. Besides Arduino themselves, several companies (Intel, MediaKit, TI, PJRC) manufacture hardware development kits that either completely compatible with the Arduino ecosystem, or use parts of the software tools in their own kits. The first official Arduino boards shipped with an 8-bit Atmel AVR micro-controller on them, and many of the official Arduino boards still use Atmel chips on them. The Arduino Nano clones that were handed out at the event have an Atmel 328p chip on them. Given that Arduino supports many hardware types, it’s important that the Arduino code is compiled for the right architecture.
Getting Started with the Arduino IDEThe Arduino Nano is programmed using the Arduino IDE. It’s in the IDE that you write “sketches” that are then compiled into firmware that your computer writes to the Arduino connected to it using a USB cable. To start, we’re going to load, modify, and run an example sketch that will blink an onboard LED. Onboard LED? Most Arduino and Arduino compatible boards already have a LED connected to an output pin soldered somewhere on the board. On the Arduino Nano clones, it should be on Pin 13. For the purposes of the demos, I’m using a Teensy 2.0 board. It’s very similar in size to the Arduino Nano, but it uses an Atmel 32u4 and has its LED on pin 11.
The Blink SketchFirst, open up Arduino. Then, select the Blink example sketch from the “File>Examples>01. Basics” dropdown menus.
The Blink sketch should then appear in your sketchbook. We’ll go through each part of the sketch. Please note that the comments in my sketch may be slightly different than yours due to the libraries I have installed.
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
// Pin 13 has an LED connected on most Arduino boards.
// Pin 11 has the LED on Teensy 2.0
// Pin 6 has the LED on Teensy++ 2.0
// Pin 13 has the LED on Teensy 3.0
// give it a name:
int led = 11;
The first block of code in the sketch has documentation in comments and an integer declaration and initialization statement. Arduino uses C++ style comments, where the remainder of a line can be commented out with //
and you can use /* */
to designate a block comment. Comments are super helpful with documenting the code at its source. Don’t just document code for other people, I can’t count the number of times I’ve looked at code I’d written years ago and wondered “What the heck was I thinking?”. Comments can help alleviate that. In this case, we have a brief description of the sketch along with some useful information about what pin the LED is attached to on different boards. Since I’m using a Teensy 2.0, I need to set the led
integer value to 11. For the Nano, it should be 13.
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
Arduino sketches have two primary functions that are used. setup()
is run whenever the board is power cycled or reset. setup()
only runs once, which makes it ideal for initializing variables, setting pin modes, instantiation of libraries, etc… In this instance, we’re using the pinMode() function to setup our previously defined LED pin to be an OUTPUT. Pins can be inputs or outputs depending on what you need your sketch to do. Some pins only work as digital (0 or 1) inputs/outputs, while other pins have the ability to sample analog signals using an ADC and output Pulse Width Modulation or an analog signal using a DAC. Once we have the pinMode initialized, we can then move on to our next function, the loop()
function.
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
So as the comment at the top of the code suggests, the loop()
repeats itself over and over again forever - well as long as the device has power. The first statement, digitalWrite(led, HIGH)
turns the led on. delay(1000)
pauses the loop()
for 1,000 milliseconds (also known as a second) and then the next digitalWrite(led, LOW)
turns the led off. Our final delay(1000)
statement pauses the loop()
for a second. Note that using delay()
isn’t really the best way to blink an LED. delay()
is blocking - that means that no code runs on the microcontroller until the delay()
statement finishes. If we wanted to do some calculations as the LED was blinking, they would be paused as well. The “BlinkWithoutDelay” sketch located at “File>Examples>02. Digital” shows how to blink an LED without using a delay()
statement.
Before we upload the code to the board, we need to make sure that we have the drivers installed for our board, and that we have the correct board selected. With the Arduino Nano clone, we need drivers for the CH340G USB-serial converter chip. Apparently Windows 10 and Linux support the CH340G out of the box, but you’ll need a driver for Mac. Apparently there are issues with the old version of the driver with OS 10.12, so follow this guide to install the appropriate drivers. Once the drivers are installed, we need to select the appropriate board from the “Tools>Board:>” dropdown. Note that I’m using a Teensy 2.0, the Arduino Nano is listed lower in the dropdown.
Finally, we have to upload the code to our board. Make sure that the USB cable is plugged into your computer and the Arduino, and click the upload button on the IDE to program the Arduino. After the firmware is transferred and the board resets, you should have a blinking light!
So I made a quick screencast of the steps listed above. Check it out!
What’s a NeoPixel?A NeoPixel is just a name that Adafruit uses to refer to a bunch of different RGB (and RGBW) individually addressable LEDs. We’re using a NeoPixel that is using a WS2812 RGB individually addressable LED. The LED itself has three inputs and three outputs. Power, ground, and data are the three inputs, and they are passed through to the next LED in the strip, allowing you to set the Red, Green, and Blue intensities for each LED in the strip individually. The data signal to control the LEDs brightness is timing dependent, and a little complex to generate. Luckily for us, the folks over at Adafruit wrote a nice library that takes care of all that complicated logic and makes it super simple for us to create cool light patterns.
Installing the Adafruit NeoPixel libraryBefore we can use the NeoPixel Library, we have to install it! It used to be a little complicated to install libraries into the Arduino IDE, but they’ve since simplified it and included a handy Library Manager. It’s listed under the “Sketch>Library” dropdown menu.
Then, we can search for and install the Adafruit NeoPixel Library! Simple as that!
So we’re going to write a new sketch, this time blinking a single NeoPixel green once every second. For simplicity's sake, we’re only going to blink the first LED, and we’re going to use the simpler delay()
method to blink the LED (blinking the NeoPixel without delay is left as an exercise for the reader).
Our first step is to hook up our NeoPixels to the Arduino. I’m using a strip of NeoPixels that has 23 LEDs on them. First, connect the ground wire of the NeoPixels to one of the ground pins on the Arduino (GND). Then hook the power wire to the +5V pin on the Arduino. Since we’ll only be driving one LED, the Arduino will be able to power it just fine. But microcontroller outputs can only drive a limited amount of current and if we were to try and drive a large number of LEDs or something more current intensive like a motor, we would have to use an external power supply. For data, I’m going to use pin D0 on my microcontroller, which corresponds to Arduino Pin 5 in the Arduino IDE. If you followed my earlier guide on hooking up hardware with the Arduino Nano clone, you would use Pin 2.
Import the Adafruit NeoPixel LibraryIn order to use the Adafruit NeoPixel Library in our sketch, we have to import it. Open a new sketch and either type #include <Adafruit_NeoPixel.h>
or use the “Sketch>Include Library” dropdown menu to include it.
Next, we need to #define
a couple of constants; PIN is the pin we have the NeoPixel data line connected to, and NUM_LEDS is the length of the NeoPixel strip. Once we have that, we can create an instance of the Adafruit_NeoPixel called strip, that uses the PIN and NUM_LEDS values defined earlier. The final parameter is a value to indicate the type of NeoPixel that’s being used. The WS2812 LEDs that we use are NEO_GRB + NEO_KHZ800
.
//define NeoPixel Pin and Number of LEDs
#define PIN 5
#define NUM_LEDS 23
//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
Our setup()
functionWe then need to called the begin()
method on our NeoPixel strip to set it up. Any time we make changes to the strip, we need to send them to the strip using the show()
method. This allows us to queue up all of the pixel changes and then push them out all at once. Since we haven’t set any strip pixels, our call to show()
sets all of the LEDs to be off.
void setup() {
// start the strip and blank it out
strip.begin();
strip.show();
}
Our loop()
functionFinally, in our repeating loop, we just copy the previous blink example, but use the strip.setPixelColor()
function to turn the LED on and off. The strip is zero-indexed, so the first pixel is 0. To set the first pixel red, we would set it to a value of (255, 0, 0)
and to turn it off, we would set it to (0, 0, 0)
. Again, we have to call strip.show()
after each call to actually change the value of the LED. Finally, we put a delay(1000)
in between the setPixelColor()
calls to blink the LED. All together, it looks like:
void loop() {
// set pixel to red, delay(1000)
strip.setPixelColor(0, 255, 0, 0);
strip.show();
delay(1000);
// set pixel to off, delay(1000)
strip.setPixelColor(0, 0, 0, 0);
strip.show();
delay(1000);
}
In actionAnd that’s it! We’ve recreated the Arduino Blink Sketch and can now blink a NeoPixel.
Going Forward…I realize that blinking LEDs isn’t exactly groundbreaking, but it gives us a good start for creating really cool lighting applications. I’ll break down some more advanced NeoPixel programming in my next post. Happy Hacking!
Comments