Cornell University ECE4760
Driving Pixel Display Strips
NeoPixel display strips (e.g. Adafruit) use the WS2812 Intelligent control LED Light Source. The WS2812 uses a one-wire communication scheme with critical timing requirements. From the datasheet you can see that the codes for 0/1 are set by duration of the logic-high part of a bit-time. I had to hand-tune each of the four times to the nearest machine cycle to make the system work. The data transfer for each LED is green, then red, then blue, 8-bits each, msb first. The first LED written is the one nearest to the data source line. Each LED after that has to be written quickly. A logic zero for greater than 50 microseconds resets the pixel-count to the first pixel..
Connections to the strip followed the Adafruit recommendations. The data line drive line has a 300 ohm series resistor. The power supply was set to 3.4 volts, with a 150 microfarad capacitor close to the strip in parallel with the power supply. Current drawn from the supply depends on the intensity of each of the LEDs, but for full white is around 60 mA/LED. Full intensity for one of RGB is about 20 mA/LED. The demo code defines a pulse on the green channel then moves it while changing the background LEDs. (video) The code was hacked from the example given on the SignalPath site.
DotStar display strips (e.g. Adafruit) use the APA102 RGB LED control IC. This chip uses slightly simplified 32-bit SPI communication (no chip-select line) to receive data. The LEDs must be driven at 5 volts and take about 60 mA/LED at full power. The 3.3 volt PIC32 logic is level-shifted to 5 volts using a 74LS125 as recommended on the Adafruit site.
The 32-bit protocol is:
The application must fill an array with colors to display, then invoke a transmit routine which formats the array and blasts it to the SPI channel. The transmit routine sends a start-frame, 150 LED-frames, then an end-frame. Total time to transmit at 10 MHz SPI bus rate is 0.58 milliseconds. The API consists of just a few routines:
There are demo codes for writing RGB and for HSV which work well on a 1 meter strip. The colors are driven by direct-digital-synthesis sine waves of settable frequency from 0.5 millihertz to faster than you can see. Frequency setting is via the dds_inc variables. As configured a increment of 2000 corresponds to about 1 Hz. With a 16 bit DDS accumulator the frequency of sine output is related to increment as
increment = Fout * 2^16 * DDS_sample_time
So for example, for 2 Hz and sample time 0f 30 millisec, the inc = 2 * 2^16 * 0.030 = 3932.
Since the sine tables are only 256 entries, only the top byte of the accumulator is used as an index.
An application of this system grabs music from a standard line-out signal (about 1 volt peak-to-peak), though a analog high-pass filter (to set the DC level to Vdd/2 shown below) to the ADC, then uses a nonlinear digital low pass filter of the ADC input to drive LED color. The audio is sampled at 8KHz. The mean of the sampled signal is subtracted from the signal, then the absolute value of the difference is lowpassed at approximately the rate of the LED update. But, if the current signal is greater than the low pass output, then in the current signal just replaces the low pass output. This helps to capture fast beat transients. I do not have video because the high-contrast of the LED light blinds my cellphone camera.
A stereo version uses two spi channels to drive two DotStar strips using the same input scheme as above from the L/R audio channels.
The green wire next to ground is the spi data line and the yellow wire is spi clock. This appears to vary from strip-to-strip.
Final project 2017 using DotStar Jason Ben Nathan and Eldar Slobodyan
Copyright Cornell University October 24, 2018