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