Neopixels are tricolor LEDs with an integrated controller, wired in a long string. The single data line that connects all of the LEDs allows a string of pulses that address every LED so that one can control any or all of them by sending the proper pulse stream.
Each of the three colored LEDs inside a single Neopixel takes an eight bit brightness value, thus we are shifting a 24 bit quantity into the Neopixel to set the brightness of the three colors. When we have a long string of Neopixels, we begin shifting out the 24 bit value for the last Neopixel, followed by the next to last and so forth until the last value we shift is for the first Neopixel in the string.
The bits flow through each Neopixel and out to the next, thus the first Neopixel has seen the bits for all its successors flow through it. The final Neopixel only sees the 24 bits intended for it, while the next to last sees 48 bits.
I bought arrays of Neopixels in a grid of 16 by 16 positions, these are addressed as 256 linear units. They can be chained, thus I will start with two arrays that consist of 512 addressable Neopixels.
DRIVING THE LIGHTS
The wire that runs through our 512 Neopixels is clocked at 800KHz sending out 24 bit values at the rate of about 33,333 positions per second. The string of pulses begins with a minimum low interval of 50 microseconds to reset the devices then the pulses go out. The proportion of on versus off time for each of the bit positions encodes whether that bit is a 1 or a 0.
Each bit position is 1.25 microseconds long. The full 24 bits takes 30 microseconds and my string of 512 Neopixels will therefore consume 15.41 milliseconds to set their values including the initial quiet period. If the chain is updated as fast as possible we will have a refresh rate of almost 65 per second.
The single data line that drives the chain of Neopixels requires 5V logic levels, thus we will be passing it through a level shifter from the 3.3V of the FPGA. The Neopixels are also fed +5V and ground to feed the LEDs themselves.
USEFUL ONLY FOR STATIC OR ONE TIME LATCHED SIGNALS
Some debugging requires me to capture fleeting signals or to see the time relationship. These would be quite difficult to capture via the light arrays, but any static, long lasting or latched signals can be routed to the arrays for display. As an example, I can use one position for each state of a finite state machine I want to monitor. If the FSM sticks in some position I will immediately see which one by the light that is illuminated.
I can also track interesting values such as the cylinder and track active for the drive. I may latch the last address on the SPI link as another idea for helpful data to show on the array. I only give up one output pin to drive all 512 lights, a good tradeoff even with the limitation to slow changing or static information.