A few weeks ago, I was put on perhaps the most fun internal project anyone has ever been given in the history of Yeti. The goal? Create an LED ticker that would flash emoji in response to people posting emoji-linked excuses on one of our apps, Chelsea Handler’s Gotta Go! If you’re unfamiliar with this app, the gist is that you can set an “excuse” consisting of texts or phone calls that your phone can pester you with later at a set time.
These excuses are supposed to help the user escape awkward situations by letting them point to the excuse on their phone. Each “excuse” can be identified with an emoji, which helps users know what messages and phone calls they will be activating on their phone without having to read a verbose description. So my ticker would tell everyone in the office whenever a user is ducking out of some social event by showing us the emoji that user used for their excuse.
The Emoji Ticker, as it would be creatively named, would serve as a visually striking and fairly useful addition to the office ecosystem. I want to share some best practices that were learned during the project, but before I do, let me share the story of how we planned and executed on this project.
Hardware-wise, the system was simple. We’d be using a Raspberry Pi, some LED Matrix boards, and some jumper wires to connect the two, as well as power supplies for both Pi and Matrix. We also needed software to communicate signals between the Pi and Matrix, so rather than learn me some C and dive into the world of embedded software development (I had deadlines to meet), I went with some code that an expert wrote to do the very same thing.
It even came with useful demos that would make the LED Matrix scroll some preset stuff like “Hello World”, “<rotating rectangle>”, or “<your image in .ppm format scrolling across the screen>”. We could definitely use that last one to display the Emoji on command.
On the software-end, I was planning on adding a hook to our Gotta Go server application that upon receiving a user’s created excuse would send another request (carrying the used Emoji) directly to the Pi. Within the Pi, the request would hit a server which would store this request’s emoji -- as well as any other incoming emoji for 10 seconds -- before firing its stores to a function that would feed the emoji one-by-one to the LED matrix C application.
The C application would be called by a program written in Python and made to make the office sparkle and glow with the beautiful pixelated emoji of our choice. More specifically, we would have a directory of image files of Emoji (in the mysterious .ppm format with the appropriate names), and our program would receive the Unicode code and call the C application with the path of the right image.
Once I had this game plan set in place, I started on the work. The hardware was actually a pain point for a good while. Plugging everything in according to this tutorial I found online (hosted on the same site I bought the LED matrix from) and trying to activate some demo displays yielded nothing on the LED Matrix. The idea of perhaps needing level-shifter chips (the LED Matrix dealt with 5V logic while the Pi dealt with 3.3V logic) in order to make everything work came up as a potential issue in the tutorial I was using. In a panic I bought five, along with a breadboard and multimeter. After plugging everything together on the breadboard under as much scrutiny as I could muster at this point, my simple hardware project was transformed into a nest of dysfunction.
Here's what happened when I plugged in the power:
Fortunately, while the hardware branch of this project was borked, I had implemented my plan for the software side and in doing so had managed to break our office’s internet. It turns out that when you have traffic coming from production server to an office router, the router will treat that traffic no differently than if the traffic were originating from the office. That means the 430-something people who made excuses in the last hour might as well have been doing it right next to me, using our WiFi. Although our company culture prioritizes delighting our app users with above and beyond service, this ticker wasn’t specifically for them so we’d probably need another, less costly solution.
Ultimately, we went from making the Emoji Ticker a server that passively receives messages from Gotta Go to an active program that sends requests to it and then uses the responses. I wrote a Python program that simply calls the Gotta Go server on an infinite loop with a request for excuse emojis posted by users in the past X seconds. The response would then be fed into the same wrapper functions that I’d written from before to interface with the C-code controlling the LED Matrix. The biggest positive to this new plan was that the signals we’d be sending and receiving would be done at a constant rate, rather than at a rate determined by how many users are using Gotta Go. Also, no longer needing to port-forward signals from an outside server to my office’s network made me and everyone else much happier.
After much consternation and grinding of teeth, we enlisted a friend who made a living prototyping hardware to help prune my ever growing tangle of electrical components and hopefully produce results. In moments, he very gracefully helped me find out what I was doing wrong. The tutorial I was using was woefully outdated, and the proper pin-outs were actually on the README of the C application all along. A good lesson learnt from this was “always go with the primary source for documentation, even if it isn’t so simple”. I was so set on using the concise and easy-to-read instructions of the outdated tutorial that I didn’t bother looking at the README of the software I was using.
After plugging everything in directly according to that pinout (without level-shifting and the nest of dysfunction), we started seeing the “Hello World” examples I had been yearning for since the very beginning. My friend and I did discover more issues that needed resolving, but from here on out the project ran relatively smoothly. We figured out that we needed to programmatically kill the process that scrolls our emoji image across the screen after a specific amount of time, and that we needed to change the images we were using to have a large black area to the left, so that each Emoji isn’t repeated a bunch of times on screen. Once we made these tweaks, we had an Emoji Ticker that not only did exactly as everyone hoped, but had a sweet setup made of cardboard and electrical tape!
In total, the project took about 2-3 weeks of work time (although 1-2 of those weeks were spent in hardware limbo). Valuable lessons were learned about the process of starting a hardware project from nothing. The most important lesson to me was the value of code modularity, or the practice of breaking a project into function-specific components (i.e. functions for rendering on the LED matrix, classes for communicating with the Gotta Go server).
As a web dev, it definitely reinforced for me the reasons for why frameworks or paradigms like MVC or VIPER generally seek to separate concerns, namely that it enables the programmer to multitask and work on whatever part of the code isn’t hung up by blockers (cough, cough LED Matrix).
On the hardware side, I learned that using the right documentation and making many small steps rather than a few large ones makes all the difference. Breaking the large task into a bunch of smaller ones made the project much less daunting and gave me the opportunity to celebrate more milestones. On second thought, maybe that's more a lesson on life.