A LED dashboard that can display all of your favorite sports and stock prices, the music you're listening to, the weather outside, the monthly calendar, time and date, as well as any image you'd like to display!
Inspiration
Bitstream is a project that I began working on during the summer after I graduated from Kennesaw State while I was job hunting. I figured it would be a great opportunity to demonstrate my technical skills and bring one of my cool ideas to life.
I had seen displays similar to my project on YouTube and some online shops such as Etsy and Amazon. However, none of them were very robust and they lacking core features that I wanted to have on a display, such as the clock at the bottom. Plus, I just spent 4 years learning electronics and embedded systems, why not try and create it myself!
Credit to hzeller's open source library for interfacing the display at a hardware level: https://github.com/hzeller/rpi-rgb-led-matrix/tree/master
Core Features
Here are some of the core features and specifications from BitStream:
A retro-styled RGB LED display powered by a Raspberry Pi 4
Simultaneously displays a clock and the "active app" (the app displayed on top)
Change the active app or the brightness of the display using encoders
Cycle through different styles for the clock display with a button
A "night mode" that disables apps and displays the time only using the red LEDs
Parts List
64x64 RGB LED Matrix P3.0
Raspberry Pi 4 (4GB RAM)
32GB SD Card
2 Rotary Encoders
2 Push Buttons
5V 4A Power Supply
Jumper Wires and Breadboard (for prototyping)
Note: Parts list subject to change in the future
In this section, I'll describe how I designed the embedded software for BitStream and how I tackled some of the technical challenges that I faced. Here are some of the apps that I have completed so far:
Spotify App: Displays the currently playing song on your Spotify with artist, album cover, and track progress bar.
Baseball App: Shows if your favorite baseball team (Yankees!) is playing today or not, displaying balls, strikes outs, innings, runners on base, and score in real time.
Weather App: Displays the current weather and a 3-hour future weather forecast for any city in the world, in addition to precipitation percentages
Image App: Displays various pre-loaded images and GIFs
I'm currently working on building more apps for the display to display local weather, stock prices, soccer matches, and calendar. I will upload information about them as I complete them!
Stock App: Track stock prices in real-time for all of your favorite stocks
Calendar App: Displays a calendar of the current month (maybe a functionality to view certain tasks you set in a calendar app?)
Various Sports Apps: Baseball uses an ESPN API, so it shouldn't be too difficult to adapt to different sports such as basketball (Knicks!), and college football (Miami!)
Strava App: Display fitness related data from the fitness app Strava
Hardware Components and GPIO
The LED Matrix library from hzeller allows the user to read from any of the GPIO pins that aren't being used for the display (no outputs from GPIO). BitStream uses some rotary encoders and buttons to give the user easy control over the display without needing a mobile app. Here are some of the features associated with some of the hardware components on BitStream:
"Home" Rotary Encoder: This encoder allows the user to go back to the home page (press the encoder down) and to scroll through the app icons on the home page (rotate left/right).
"Action" Rotary Encoder: Lets the user do certain actions within the apps on BitStream, such as pause/play and skip in Spotify or scrolling through all of the MLB games today in Baseball.
Night Mode Button: A push button that allows for "night mode", where the screen only displays the time using only red LEDs.
Power Button: Allows the user to power on/off the BitStream system
Some of these features are still in development, and will be implemented in the next stage of software development for the project.
Multithreading
BitStream has many tasks to juggle, ranging from API calls to handling GPIO inputs. Multithreading is vital to keep the display running smoothly and efficiently, if not then the display begins to flicker or have significant delay. There are two main processes running BitStream (read up on this design choice in the Interprocess Communication section):
Display Process (C++): Handles most of the work on running BitStream, such as setting the pixels for the display and interacting with all of the hardware.
REST API Process (Python): Pings various REST API endpoints and parses JSON responses so the apps have content to display.
There is only a single thread running in the Python process, as it's a fairly simple code and waits for a command from the C++ process before sending any requests. However, there are multiple different threads running in the C++ process:
Main Thread: Initializes the system, creates the other threads, and manages the display when on the home page.
App Thread: Provides control flow and draws on display for whichever an app is selected from the home page.
GPIO Thread: Reads the GPIO inputs and signals to perform some task depending on the user's action.
API Thread: Handles sending the API command to the Python process and parsing the response into variables within the C++ process. May seem redundant, but can take 50-500ms to receive the JSON response so parallelization is necessary.
Clock Thread: Fetches the time and draws the time onto the bottom 1/3rd of the display.
Inter-process Communication
There are two FIFOs used between the two processes: the command pipe and the data pipe. In the command FIFO, the C++ process requests a certain type of data (music, weather, etc.) for the current app. The python process then sends a request to the specific REST API endpoint, parses the JSON response, and formats the essential data for transmission back to the C++ process across the data FIFO. The C++ process receives the data in a comma-separated format and places the data into local variables within the C++ process.
Is this the most efficient solution? Likely not. However, it gives me an opportunity to implement inter-process communication into BitStream. Plus, parsing large JSON files is more robust in Python than in C++.
Remaining Work
I've been able to make good progress on this project while job hunting, however there is still a good bit of work before I would call this project complete. Here is a concise list of some tasks I have lined up for myself:
CAD and 3D-print to enclose the display, Raspberry Pi, and various hardware components
Design a simple PCB to make wiring easier and less messy inside the enclosure
Add more apps to BitStream
Final Thoughts
Building practical and complete projects is one of the best ways to grow as an engineer and to gain confidence in technical skills. This project has been a great learning experience, but I also recognize that there is still a long road ahead before I call myself a master at embedded software. I've refreshed myself on many embedded software concepts and found ways to efficiently implement them. Most importantly, I've begun to unleash my creativity as an engineer to bring cool ideas to life!
Check back here soon as I continue to update my progress with BitStream!