Feature

Dancing in the (LED) Light

Ray Abram

Issue 2, August 2017

This article includes additional downloadable resources.
Please log in to access.

Log in

Ray’s discovery of the Adafruit NeoPixel light strip was almost by accident, but a happy accident.

NeoPixel by Adafruit is a range of addressable LED light strips, and with minimal wiring and code it can create some amazing dancing light displays. We caught up with Ray to talk about his discovery of NeoPixel, and how he went about using them with a PIC micro.

The NeoPixel LED strips are great. Did you choose these straight-up or were you playing with something else to begin with?

I was originally playing with a microprocessor PWM-ing a bunch of Red LEDs to make an LED chaser. I created the effect of a bright LED (no PWM) and a tail of lesser bright LEDs (more and more PWM). This LED chaser was inside the frame of a sign for the neighbour’s kids bedroom. The girl for whom this sign was for asked if the LEDs could be other colours, and that is when I used Google and discovered NeoPixel LEDs.

The original hand-made sign that inspired the NeoPixel journey.
The original hand-made sign that inspired the NeoPixel journey.

Addressable LEDs are definitely the way to go once there are more than a few. Was your PIC code complex to get right?

The most complex part was making rainbow effects. I found some Arduino code that did what I needed, so I then converted it to work in my project. The second most complex part was getting the timing on a port pin to correctly match the NeoPixel protocol. The PIC needed to run at 48MHz to get the timing close enough for the NeoPixel to accept the data. I used a PICkit to debug and program the code with. The unit also runs from a USB plug pack, so there is no fancy power supply to make, just the PIC connected to the NeoPixel’s “data in” pin.

That’s definitely a simple and elegant solution. How many preprogrammed routines do you have stored in your PIC?

I have nine routines, each of which are selected by holding a button in (this skips to the next effect). The nine effects are:

  • Colour wheel
  • Just 1 red LED on moving forwards along the strip
  • Just 1 red LED on moving backwards along the strip
  • Just 1 red LED on moving forwards then backwards along the strip (like a Cylon’s eye from Battlestar Galactica)
  • Crawling forward red LED effect
  • Crawling backward red LED effect
  • Crawling forward rainbow LED effect
  • Crawling backward rainbow LED effect
  • Fully random LED colour or LED sparkle effect

That’s quite a selection! We can see a tactile switch on the board - is that to cycle through different sequences?

Yes, the tactile simply cycles through the routine currently in operation.

Like many hobbyists, Ray has his own CNC machine for making all sorts of awesome things.
Like many hobbyists, Ray has his own CNC machine for making all sorts of awesome things.

Your circuitry is amazingly simple, have you considered expansion to sync to music from an audio source or microphone?

This could definitely be a future enhancement to the code. The original intention of the code was to create a unique LED light stick for when I was at a Coca-Cola Christmas party in a park. I would need a large lead acid battery to run it, or a USB backup battery pack outputting 5V.

Sounds like something worth tackling. Perhaps some Li-ion batteries would do the trick, depending on your required runtime of course. Have you programmed PIC micros before or did you learn specifically for this project?

I have done some contract software development for some companies over the years, so I have completed some very complex projects on PICs. This code was some of the easiest and more simple code I've written.

It’s so great when a plan comes together and all goes smoothly! You mentioned some timing trickery to get the NeoPixel to accept your code from the PIC. Can you elaborate on this?

The protocol shown below is quite specific on its BIT timing. So to get the PIC to control its port pin accurately, I used an oscilloscope to show the pin. I just kept adjusting some timing loops in my software until my software matched the protocol’s BIT timing. A PIC running with a 48MHz oscillator is only just able to keep up with the BIT timing requirements.

That’s fast! Did you face any unexpected challenges with this project?

For sure. Firstly, I wanted to calculate the colour for each LED just before sending it out, but some of the effects took too long and resulted in only the first Neo Pixel working. It took a bit of thinking to determine the code was taking too long to calculate the effect, so I needed to precalculate the LED colours into RAM and then send them.

Secondly, the point where you connect the NeoPixel “data in” to the PIC’s pin required a 100Ω resistor, which I did not fit at first, and this resulted in the LEDs doing random things.

Thirdly, you need a large capacitor connected across the NeoPixel to make them work reliably, which I did not have originally. This resulted in more weird effects taking place.

A PIC18F45K22 and a handful of components.
A PIC18F45K22 and a handful of components.
Minimal wiring is required to get NeoPixel running.
Minimal wiring is required to get NeoPixel running.

All of these sound like relatively minor issues to overcome, but sometimes the simplest things are the hardest to debug! If you had your time over, or were creating a V2.0 of this project, is there anything you would change?

I would use a more powerful CPU so I can add comms support, which will connect to a WiFi adapter and allow an Android or PC to tell the LEDs what to do.

We would love to see that! What are you working on now?

I want to connect a grid of 32x256 NeoPixel LEDs to a PIC (or maybe a STM32 CPU), so I can scroll messages across the LEDs; but I have not yet started on this project. It is only at the ideas stage at this point in time.

That would be great to see. We hope to check it out once you have tackled it! Thanks for taking us through your NeoPixel project.

Time Constraints:

The NeoPixel strips require high precision timing. Many popular general purpose MCUs such as a Raspberry Pi or Arduino simply cannot handle the speed requirements.

Speed requirements diagram.

DATA Transfer Time (TH+TL=1.25µs±300ns)

T0H

0 code, high voltage time

0.4µs

±150ns

T1H

1 code, high voltage time

0.8µs

±150ns

T0L

0 code, low voltage time

0.85µs

±150ns

T1L

1 code, low voltage time

0.45µs

±150ns

RES

low voltage time

Above 50µs

±150ns

Ray used an oscilloscope to adjust timing loops until the software matched the protocol's BIT timing. A PIC running with a 48MHz oscillator is only JUST able to keep up with the BIT timing requirements!

Ray Abram

Ray Abram

Embedded Software Engineer from West Auckland, NZ