After a repair, WS2812 “smart” LED strips driven with the same data gave different colors.
TL;DR Summary:
- The RoboRIO’s PWM outputs can just barely drive the fast data stream needed by these “smart” LEDs.
- Signal Integrity is important on the LED data stream from RoboRIO to LEDs.
- Not all “compatible” RGB LED strips behave exactly the same when given a distorted data stream.
- There are workarounds and fixes. Simplest: keep the LED data wires SHORT.
What We Did
Given good success using “smart” RGB LED strips driven directly by the RoboRIO last year, my team, 4795, decided to use them again for Hydra, our robot for Charged UP. We followed the usual software guide: Addressable LEDs — FIRST Robotics Competition documentation
This season, the LEDs mainly signal the humanplayer which game piece is desired. Some additional colors and patterns also show some software-debugging status.
We used three strips, two up vertical structural members, and one inside the rotating arm . Just like last year, all strips are fed the same data stream from the RoboRIO, using PWM “Y” cables to split the
data. Each strip is wired with heavier 5V power and ground wires and a scrap of PWM cable with a connector for data and data-ground. Power wires from each strip run directly to 5v outputs from a VRM.
Splitting the data stream with a “Y” cable makes the wiring neater: we don’t have to daisy chain from the “output” end of one strip across or back down the robot structure and over to the next strip of LEDs. We
also don’t have to duplicate the data in software to guarantee that we show the same pattern on every strip so it can be seen from all angles.
Our original LED strips we believe came from Rev, although we’re not 100% sure since we’ve had them since last season
The Problem
All was good at the UNC-Ashville competition until one of the strips was broken in a collision with another robot. The pit crew replaced the damaged strip with another from a different source. That one was from Amazon:
https://www.amazon.com/dp/B08GSCJPMD
The replacement strip shows bright white when the others are magenta, and a bright, pale green when the others are yellow. (See picture at the top of this post.) I guessed at this point that there must be some difference in the chips inside these two different “WS2812B compatible” LED strips - but what?
Debugging and Speculation
When we fed the robot’s three LED strips with properly formatted data from an Arduino running a WS2812 LED demo program (GitHub - adafruit/Adafruit_NeoPixel: Arduino library for controlling single-wire LED pixels (NeoPixel, WS2812, etc.)), all three Y-connected strips show the same, correct colors.
Thinking about the data stream for these LED strips, I got to wondering: what could turn some of the “0” bits into “1” bits, resulting in a brighter, washed-out appearance?
If we google the datasheet for these parts
(https://www.digikey.com/en/datasheets/parallaxinc/parallax-inc-28085-ws2812b-rgb-led-datasheet),
we see that “0” bits are represented by narrow pulses (400ns), and “1” bits by wider pulses (800ns). A complete date bit is about 1200ns, for a data rate of about 800 Kbps. This is a form of pulse-width
modulation, although quite different (and much faster) than the PWM used by servos and motor controllers.
The RoboRIO documentation isn’t very good on electrical charateristics of its outputs, and there’s no schematic for the RoboRIO. Brief rant: NI doesn’t need to provide a complete schematic, but enough shematic of each input and output to fully document (and support teaching about) the interfaces should be required.
The RoboRIO V2 documentation does say that the PWM outputs are rated for “Maximum Frequency 150KHz”. There’s the first problem: the LED data stream is much faster than that. But it works for many teams, at least sometimes.
The RoboRIO V2 documentation also says “the lines on the PWM and Relay ports all have 40KΩ pulldown resistors to ground”, along with a schematic fragment.
Which leads me to wonder, do the PWM outputs not really drive “low” (pull the pin to ground) very well? Is that pulldown resistor the only thing sinking current?
What exactly do motor controllers do with the PWM signal, anyway?
What kind of circuit is the RoboRIO probably designed to drive?
The only FIRST-legal motor controller for which I’ve seen a schematic was the original Jaguar, also known as the “Texas Instruments Stellaris microcontroller reference design kit.” It uses an opto-isolator on the
PWM input, with the PWM data directly driving the LED in the isolator:
This is quite nice, as the pwm is completely isolated from the potentially-noisy motor power. This only requires the RoboRIO (or cRIO!) PWM output to drive “high” (+5 volts), and not to sink much
current.
But if the RoboRIO’s PWM outputs actually are designed especially for this, they’ll actually perform quite poorly for faster data (with narrower pulses).
And there we have my best guess as to the problem: The RoboRIO’s PWM outputs are being asked to drive faster data than they’re designed for, and they do a poor job of pulling the signal back “low”. If
there’s much stray capacitance in the wiring - say from wires that are rather long, or multiple LED strips Y-cabled to the same data - the falling edges of the data bits will be slowed down, making some or all
of the “0” bits stretch into “1” bits. (The rising edges won’t be affected much).
I was able to turn the arduino’s “good” LED data stream into a “bad” stream using a diode and a resistor.
This reliably turns our oddball LED strip to pale, bright, nearly-white colors, while our original LED strip doesn’t seem to mind as much. Here’s a snapshot of two different strips driven through that circuit on
my messy workbench.
Changing to a much lower valued resitor restores a good edge rate, and works around the problem. 2.2K or 2.7K works nicely at home on my bench.
The workaround we’re using on the robot right now is to only drive two strips (one of each type) and disconnect the second Y cable and the long cable (about feet) running up to the rotary arm. That restored both strips to the correct color for our second event, FNC Wake County, and also for the NC DCMP.
But for reliably driving a few feet of cable, or multiple LED strips from any vendor, an active buffer circuit would likely be more reliable. I’ve prototyped this at home with a 74HC04 chip wired as a buffer:
The prototype breadboard is visible in the photo above.
Testing all of this out on the actual robot and competition-veteran LED strips will probably wait until the end of the season. Likewise, dragging my oscilloscope into school to verify and demonstrate all of this in detail to the electrical subteam students will also get to wait until after our last event - which we hope is in Houston!
Update: yes, our first order of business is getting the team and robot to the championship!
Look for me if you want to talk robot electronics!
- Steve