When last we left our intrepid band of adventurers, they were standing in Joseph’s driveway with a jeep and fully functional RGB underglow. Like most every engineer finishing a project with near perfect functionality, they decided it needed a total redesign with more functionality.
More colors! Touchscreen control! RAINBOWS!!!
And so, a new quest for the best and brightest parts commenced.
Some basic hardware was decided on pretty quickly. We started prototyping with a Raspberry Pi for the main computer, an arduino for the LED controller, and neopixels for the LEDs.
Neopixels are pretty cool! They’re Adafruit’s brand of WS2812b LED chips in various form factors. They’ve added many form factors and chips over the years for a full lineup of RGB, RGBW, UV, flexible strips, rigid strips, and bare chips. The general idea shared between all of them is their individual addressability. For a full strip you can set the individual color components for every single chip on the strip individually. This gives some pretty cool functionality for patterns and colors, which is why we went with them. Except, at the time for a 144 pixel/m density they were about $80 per meter which was out of our price range, so we went with some cheaper generic strips at about $25/meter.
Development with the neopixels and arduino began in earnest. It was decided the Raspberry Pi would control the colors and patterns over USB to make interfacing easy. To simplify the serial protocol as much as possible, during initial testing it was decided to send single ASCII characters that would correspond to colors or flashing patterns that would be hard-coded on the arduino. (The first of many shortcuts that would come back to bite us.) This worked pretty well and seemed promising, but it was also where we hit the first major snag: For some reason a delay between sending a command and seeing change on the LEDs would build up over time, to a point of near-unresponsiveness after several minutes of the program running.
This problem was eventually traced back to an issue of how the LEDs received control commands. A complete set of RGB values for every chip would be built up, then dumped at once to the pin the control wire was attached to. There was an issue between the interrupt timings of sending all that data every loop and checking the serial buffer that would compound into a significant delay over time. This seemed to be a pretty common issue with the usual libraries and serial communication on standard Arduinos, so I started looking for new hardware.
This was actually great, because in that search I stumbled across PJRC and their fantastic Teensy boards. These boards supported something I had never heard of called DMA, or Direct Memory Access. Using DMA meant that the memory dump to the neopixel control pin wouldn’t be interrupting the main processor, leaving it free to receive serial data at an acceptable rate. In addition there was already a fantastic WS2812b library for the teensy, and an amazing adapter board that would handle the 3.3v to 5v conversion. This is a fantastic stack for controlling neopixels that I’ve been using for every decent-sized installation since.
With the problem of the actual control of neopixel colors and patterns out of the way thanks to the Teensy and adapter board, we then started working on the UI for the Raspberry Pi. Initial development assumed we would be using a PiTFT touchscreen hat for the raspberry pi. For a fast development cycle we went with Processing to write the GUI, as this author was already familiar with it and the built-in serial library seemed to fit the bill. This is where a second shortcut came into play… It turned out the easiest way to make the processing sketch register touches on the PiTFT was to make the cursor invisible and not actually register clicks at all, just the location of the cursor. If the cursor was over the blue button, send the blue command repeatedly, etc. Eventually this spiraled into a multi-screen app with some basic colors and flashing patterns. It actually worked quite well, so we figured it wasn’t yet worth addressing how bad it really was under the hood.
But then we ended up not having a great place to put the pi and the touchscreen inside the vehicle. We just weren’t going to be able to make it look as clean as we wanted. Which brings us to… Smartphone control.
Having already made a long string of design choices that ended up with this invisible-cursor-based processing app, we really didn’t want to start from scratch on the control side just to make it work with a smartphone. Instead we quickly figured out the next band-aid to slap on the problem in the form of the Screens VNC app. The Raspberry Pi would boot, set up a wifi network, and start running the processing sketch in fullscreen whenever the power was switched on. From an iPhone or iPad you would connect to the wifi network, share the screen over VNC, and because Screens supported an invisible cursor it would look and act pretty much the same way it did on the PiTFT.
And this is pretty much where iteration 3 left off. We had met our goals of more colors, and touchscreen control. The strips were cast in a similar manner to iteration 2, but with 2-part casting epoxy to mitigate the stickiness issue. However, there were still improvements to be made. The control system was a little sketchy with all the band-aid fixes, and there were still a few software bugs keeping us from a full rainbow effect. Sounds to me like this won’t be the last we see of our intrepid band of LED wielding adventurers!