Crates.io | ws2812-uart |
lib.rs | ws2812-uart |
version | 0.2.0 |
created_at | 2022-04-24 22:06:08.998762+00 |
updated_at | 2025-09-23 15:36:11.702753+00 |
description | UART-based driver for WS2812 and similar smart LEDs |
homepage | |
repository | |
max_upload_size | |
id | 573339 |
size | 22,198 |
Smart LEDs like WS2812 use single wire data transmission at about 800 kHz. In order to reduce overhead one usually wants to use some kind of hardware acceleration.
Most common microcontrollers like STM32 have neither dedicated hardware acceleration nor programmable signal generators. However, there are SPI and UART, each of these is able to control WS2812 with some hacks.
While SPI is the most common interface for generating smart LED signals, UART has some advantages. First, there are much more UARTs at the typical microcontroller with much more possibilities of pin mapping. A typical STM32 can have five or six UARTs with only two or three SPIs. On other devices there is no SPI at all but some UART is still there. Second, UARTs can be much more robust since they are easily configured in output-only mode and do not have any clock signal that one has to ignore.
As a drawback, not every UART is capable of driving a WS2812. There are two physical requirements:
UARTs of STM32 are fast enough and have a configuration bit to invert TX, making its UART to perfect interface for WS2812 LEDs.
If sending byte by byte in 8-N-1 mode, one gets on the wire something like
...0xxxxxxx10xxxxxxxx10xxxxxxxx1...
or, if inverted,
...1xxxxxxx01xxxxxxxx01xxxxxxxx0...
including start and stop bits. We can transfer two bits of WS2812 in one byte of UART by taking
start and stop bits into account. We send a "1" as "11100" and a "0" as "10000" thus making 10
bits out of 2 bits. A byte is 8 bits long and there are 2 extra bits (start and stop) giving us
10 in total. Note that the inverted start bit is always 0 and the inverted stop bit is always 1.
So we send bytes like "xx001yy0". After adding start and stop bits in hardware and inverting they become "1XX001YY00" which is exactly what a WS2812 needs. We only need to adjust baudrate accordingly.