16x16 WS2812B matrix display controlled via Wi-Fi TCP socket with a Raspberry Pi Pico W. The design puts emphasis on low-latency video streaming and high-performance playback.
Most importantly, this project is meant to be an eye-catching, reliable household decoration.
- Both 8 bits per-channel mode and 4 bits per-channel mode for lowering network usage and decreasing latency
- Raw TCP sockets used instead of HTTP for minimizing latency as much as possible
- Seamless handling of client<->server connect / disconnect
- Readable code that can easily be used for learning purposes
- Images, Image sequences and GIFs can be stored in flash memory and played back offline with no interruptions
- DMA and PIO based WS2182B control
Any controller that uses TCP sockets and conforms to the Packet Format and the Data Protocol sections below will be compatible with the display.
Take a look at the example controller
The display receives packets through a TCP socket open on port 4242 by deafault. (It can be changed)
- Controller sends a valid packet (look at Packet Format) to the Pico W
- Controller waits for a response from the Pico W
- If the response reads exactly
"ACK", then the whole packet was sent and received succesfully.
After reading the correct response, the next packet can be sent immediately.
Take a look at the packet.hpp file to see all packet types. Mind the default C/C++ struct alignment.
The first byte (uint8_t) of a received packet is always the data_type field. Each packet type has its own unique data type.
RGB data is expected to arrive in the row-major order starting with (x:0, y:0) and (x:0, y:0) being the lower-left corner of the LED matrix:
... , ... , ...
(x:0; y:2), (x:1; y:2), ...
(x:0; y:1), (x:1, y:1), ...
(x:0; y:0), (x:1, y:0), ...
you can imagine the data being sent in rows from bottom to top
8bpp (Full) RGB data layout:
data[0] , data[1] , data[2] , data[...]
RRRRRRRR, GGGGGGGG, BBBBBBBB, ...
1 pixel per 3 bytes
4bpp (Half) RGB data layout:
data[0] , data[1] , data[2] , data[...]
RRRRGGGG, BBBBRRRR, GGGGBBBB, ...
*it is possible to fit 2 whole pixels in 3 bytes
The working example of a compatible controller can be found here in this repository
- Native C++ compiler (e.g. MinGW or msys2) that is added to PATH
- ARM GNU Toolchain and the
PICO_TOOLCHAIN_PATHenvironmental variable. - Pico SDK and the
PICO_SDK_PATHenvironmental variable. - C++ Build system (e.g. Ninja or make) that is added to PATH
Once the prerequisites are satisfied, run the following command:
mkdir build
cd build
cmake -G "Ninja" ..
ninja
or
mkdir build
cd build
cmake -G "MinGW Makefiles" ..
make (ming32-make on Windows)
And copy the built .uf2 file to your Pico's Mass Storage
- 16x16 WS2812B RGB LED Matrix (Aliexpress knockoff is fine too)
- Cables and a connector that typically comes along the WS2812B
- Raspberry Pi Pico W (Not tested on Pi Pico W 2)
- DC Cable Extension Cord or DC 5,5x2,1mm socket with quick connection
- 16x16cm polypropylene light diffuser plate or a piece of paper
- 3D printed frame and grid (both .stl files are in the
3dprintsdirectory) - 1000uF electrolytic capacitor for filtering the WS2812B 5V power input
- 470uF low-ESR electrolytic capacitor for filtering the 5V powering the Pico board
- 100nF ceramic for both the 5V VSYS pin and the 3V3 pin
- 1uF monolythic for filtering the 3V3 pin (the wifi chip is known to generate unwanted current spikes)
- 330Ohm resistor on the DIN line
Please double-check if your power supply can safely provide enough current at 5V. Note that not every WS2812B draws the same amount of current.
Current draw was measured only at 0%, 12.5% and 25% brightness with the whole display set to RGB(255, 255, 255). Higher values were calculated by extrapolatating the measurements.
I am not responsible for any physical damage caused by running this code. Use adequate brightness levels and double-check if your power supply can safely provide enough current in order to avoid any unwanted damage. Some WS2812B LED matrices may require more current than others. The TCP server accepts every incoming connection and every packet with no verification so it may potentially pose a threat to your local network's overall security.



