This here is a WS2812B from World Semi.
These little guys have been around for a while.
They're about 30 cents a piece but the thing that makes them really cool is they're individually
controlled red blue and green LEDs.
They're digitally controlled by virtue of having that tiny little integrated circuit
right there on dye.
They can be changed together to be many, many LEDs long.
These little guys support 24-bit color.
That's 8 for red green and blue.
Each one of these bits have to be sent out over the wire but we only have one wire so
we have to encode our bits using a very precise timing.
And uuh that's kind of annoying but kind of cool because now with one wire we can control
0's, 1's or even reset the whole strip.
By sending a 0, we send it on for a short period then off.
Or a 1, when we send it on for longer then off for less.
But the timing is restrictive.
Conveniently, Tim over at CPLDCPU has compiled a chart that gives a much better idea as to
what the timings really are.
This was really cool.
Every month it felt like someone was coming up with a new way of controlling these, through
DMA off of an STM to SPI on a PIC...
Except on the ESP8266 - the only thing I was aware of was my thing, which was terrible
because it just sat there and waited through all those periods and I needed my CPU because
I wanted to run colorchord on it.
So, I was going to need to do something different.
That difference came when sprite_tm posted this.
An ESP8266 MP3 Deoder with I2S support.
The reason I2S was so important was now, instead of manually controlling the output pin and
spending an enormous amount of time doing that, information could be loaded into RAM
and hardware (DMA) on the chip could just simply shift this out as I2S Data.
Unfortunately at the time of creating this video, I haven't been able to figure out a
way of one-shotting the DMA for the I2S.
I'm sure that someone maybe more well connected or smarter than I am could figure that part
out.
But, here's the neat thing.
We have a whole data block of WS2812 data.
We have some zeroes to send that reset pulse.
We have to figure out how to set up that data in WS2812 data.
These are actually just bytes of RAM.
Each byte has 8 bits, and each bit gets shifted out of this data register at a variable speed.
We can control it so we can get our timing right and we don't have to worry about any
finnicy CPU cycles.
There's two ways that you can do it (at least that other people do it, I'm sure there are
more).
The first one that I saw was with the SPI on the PIC project, where they'll use three
samples and to make a 0 they'll turn it high low low, what that does is produce a very
short high pulse, and a longer low pulse -- or high, high, low which produces a longer high
pulse and a shorter low pulse.
That's just fine, takes a little bit extra effort, though to create this, and in the
event of something like a STM32 if you're using SPI, you don't have that great control
over the port and you need better timing windows.
You can actually get that by making four samples instead of three, where it's on for a very,
very small amount of time and off for longer - or on for a much longer period of time and
off for a short period of time.
You then take these slices and stack them together, end to end in RAM.
And this is what the actual DMA will output.
So, under the first scheme, it takes 24 bits of space to encode 8 bits of color data, a
tradeoff I am more than happy to make when it comes to the performance, reliability and
overall usability of this.
Or, if you have to use the four mechanism for more tolerant timing, it's a little less
efficient on memory, but it's a lot easier to encode, and it only takes 16 bits of space
to encode 4 bits of color data, so 32 bits for the same size as 24.
Once this data is loaded into the data buffer, which it can be done at any time even while
the DMA is operating.
It's then shifted out by the DMA in its own time, without the core doing anything.
What we get from this is a tiny little ESP8266 that can talk over the network and receive
WS2812 data outputting it to, in this case 296 WS2812's reliably without even breaking
a sweat.
How cool is that?