Let me know what you guys think.
One question about the code, why does the LedPanel struct use a String as a buffer rather than using a Vec<u8>?
edit - I think I see the reason now. Using a string made it easy to print the u8 as a string of bits, which you could then iterate over using chars. This was used to help perform the conversion from bits directly representing colors to the on the wire representation.
Note: God bless the Oscilloscope, essential for these projects.
We built a similar WS2812b array at university for an embedded systems design project: https://github.com/joe-wright/wiisel
We looked at using a Raspberry Pi but instead settled on an mbed FRDM-KL25Z so we had more control over the signal timing. The trade-off was that the KL25Z only had 16KB memory instead of the Pi's 512MB, so getting everything to fit took a bit of creativity and a few late nights...
To my knowledge, this is not possible with a Raspberry Pi. You should see glitches on the output when your loop generating the 1s and 0s is interrupted.
That may be ok it if you just when to send one static light pattern but the glitches should be more evident if you want to create beautiful, flowing light patterns.
That's why it's better to drive those WS2812b with an Arduino that you code bare metal.
When you still want bare metal, pick a modern uC like ESP8266 (cheap, 32 bit, integrated WiFi for trivial connectivity) instead of "classic" overpriced, outdated 8/16 bit AVR (Attiny/Atmega) based Arduino hardware.
Arduino the software platform still works great of course, but so does NodeMCU which is the go to stack on ESP8266.
That said the ESP8266 still has a place because of how cheap you can usually find them. Lowest price arm board that i know of from a manufacturer is the Teensy LC at ~$12USD, but there are cheaper ones out there on ebay and aliexpress. I just can't say anything about how well they work or are supported by anyone.
For the specific purpose of controlling APA102 via wifi, ESP8266 (NodeMCU or similar) seems optimal, as 1x SPI and WiFi are the only peripherals needed and so ESP8266 is a perfect fit hardware-wise, and it's well-supported, extremely beginner friendly (<25 easy lines of code to get these LEDs blinking via WiFi, mouse-click based library download) and cheap.
In general, for intermediate users and up (anyone not lost right away without peripheral libraries from SparkFun/AdaFruit), and unless Wifi is needed, I fully agree on ARM. I'd recommend the STM32 portfolio. These scale really well from learning platform to full on commercial use (with the F0/F1/F4/F7 MCU's, stm32duino/libopencm3/mbed frameworks, Arduino/PlatformIO dev environments, all in order of complexity and/or professionalism). The STM32F* eval boards are nice but pricy; there are fewer universally useful cheap small-formfactor (ie Arduino-like) boards.
(WIP modular synth sequencer: https://photos.app.goo.gl/PcMqnUThygRG3T8v7 )
I also have since bought a couple of ESP32 and think they are awesome.
If you don't use the more power hungry board features they still work fine.
The only thing that is missing is good Rust support.
Not sure how fast that's gonna happen, but one may hope!
That having been said, if this works reliably, it's fantastic. The ESP32 is pretty great, but controlling WS2812b LEDs from a Pi Zero would be extremely convenient as well.
You can then manually assign a thread to an isolated core, and it will run there without any interruptions from thread switching.
You can also map
interrupt handlers away from those isolated CPUs.
There may be architectural things that cause interruptions you can’t mitigate though (like SMIs on Intel).
And the userspace sends entire buffer in one syscall, so those underruns will have to be caused by kernel stall, which usually only happens when buggy device drivers are present.
> Now taking a look at the duties of the PWM signal we need to send, we can approximate the highs and lows to some multiple of 1/3. This means that if we run a MOSI SPI signal at triple the frequency the lights expect, then we can send a single WS2812b "panel bit" using a combination of 3 SPI bits.
Source: wrote a software UART for an embedded project