My Projects > NeoPixel Controller

NeoPixel Controller

Technologies Used: VHDL, Assembly, FPGA, Quartus Prime

Project Summary:

This project was my first ECE team project at Georgia Tech for ECE 2031, Digital Design Lab. In this project, we were tasked to build a controller in VHDL for a strand of 256 NeoPixels.

BACKGROUND

During the semester, we learned to design hardware in VHDL which was implemented on an FPGA. Towards the end of the semester, we worked with a Simple Computer, or SCOMP, which was a computer designed entirely in VHDL and implemented on the FPGA we'd been working on all semester. This SCOMP was provided to us by the course instructors. This computer had a memory component that held 16-bit data and a processor which held one 16-bit general-purpose register. During our labs, we interacted with this computer by working with its internals and writing assembly code for it. We later began working with I/O to the SCOMP in the form of peripheral controller devices, also implemented in VHDL on the FPGA. For this project, we had to create an SCOMP peripheral in VHDL which could interact with the SCOMP to control a strand of 256 NeoPixels, which was physically connected to the FPGA. These NeoPixels are addressable and each pixel can be set with a 24-bit color, where 8 bits are red, 8 bits are green, and 8 bits are blue. We were given a basic peripheral which has a RAM component where pixel data can be stored and a protocol that can take stored data and output the proper color to a pixel using a protocol specified by Adafruit.

EMPATHIZE AND DEFINE

Our peripheral had some requirements to meet. Any user of our peripheral must be able to set all pixels to a 16-bit color in one command, a 16-bit color to any specific pixel, and a 24-bit color to any specific pixel. After setting a color to a specific pixel, the controller must also be able to automatically increment the address for the next pixel so the user doesn't need to keep specifying consecutive pixel addresses. We were also tasked with including some additional functionality to the controller, which was up to our team to come up with.

IDEATE

To interact with different peripherals, SCOMP utilizes a decoder called the IO Decoder, which has chip select signals to select a peripheral and communicate with it. For example, the decoder has a chip select signal for the LED controller peripheral, so when SCOMP communicates with it, it selects that and either sends or receives data from it. Our team decided to utilize this system and create chip select signals for every single mode that our peripheral would have and use them as inputs into our NeoPixel Controller. Below is a block diagram for how we implemented this for our basic functionality:

With this, our controller now has inputs for all of the base functionality it implements, and the user simply needs to specify the mode before when they send the data they need. Based on these inputs, we programmed our VHDL to do different things based on the mode the controller is in. Each member of the group took a functionality to work on, and I worked on the ability to set a 24-bit color value to any pixel.

My idea to implement this was to have the user specify R, G, and B values in three seperate instructions for one pixel, 8 bits each. I implemented this functionality using a state machine. When the user first selects the 24-bit mode and loads an 8 bit value from the general-purpose register of SCOMP into the peripheral, the mode is in the state "red", and this value is loaded into the 8-bit red section of the color value. Here is the VHDL for how this state machine works:

This continues for a "green" state to store the green value, and a "blue" state to store the blue value. I also implemented error catching so that if the user selects a different mode before completing all R, G, and B values, the pixel stays at the color last set, and the state machine resets to the "red" state.

After we all completed our individual functionalities, we merged all of our changes together using GitHub. Once we did that, we began working on some additional functionality.

The additional functionality we decided to implement was read functionality, where the SCOMP could store data from the NeoPixels that the user could use for whatever use they wanted. We also decided to implement functionality to be able to adjust the brightness of the NeoPixels with one command and to animate pixels shifting through the string.

Once we finished all of our functionality, we merged our changes and had our files ready for submission. To demonstrate our project, we wrote assembly code as a user of the peripheral would write it, and showed our controller properly working on the NeoPixels to our instructors. Below are videos of the demo running: