KaraBox
A Rust programmed Bluetooth-enabled karaoke device built around an STM32 main board and an ESP32 wireless bridge.
Author: Neagu Alexandru-Florin
Group: 1222EEB
GitHub Project Link: https://github.com/UPB-PMRust-Students/fils-project-2026-ithinktoomuch05
Description
This project represents a karaoke device that lets a user pick a song from their phone, stream it via bluetooth to a small dedicated speaker system, and see synchronized lyrics scroll on both their phone and a on-device display - all while a separate display shows the temperature and a small fun LED matrix goes through different colours!!
The system is split into two physical boards that cooperate over Bluetooth and SPI:
- The audio path is a hardware-only board built around an MH-M38 Bluetooth audio receiver that drives a small amplifier and the speakers. The phone pairs to it directly.
- The brain board runs a Rust firmware on an STM32U545RE-Q, drives two small ST7789V TFT displays, a MAX7219 8x8 LED matrix and a DHT22/AM2302 temperature/humidity sensor, and talks to an ESP32-WROOM-32 over SPI. The ESP32 acts as the Bluetooth Classic bridge that hands lyrics and control commands from the phone to the STM32.
Motivation
I chose this project because karaoke is fun and my last project idea sadly died after my motor microcontrollers decided to not work and 2 of them were fried. Fortunately karaoke is even more fun!
Architecture
This is the diagram regarding how the project is organized:

These are the current KiCAD diagrams for the project depicting the power distribution and the communication protocols between the STM32 brain board and its peripherals (the ST7789V display over SPI2 and SPI3, each display, the MAX7219 matrix over SPI2, the ESP32 link over SPI1, and the DHT22 sensor on a single GPIO line.

Main components:
Log
Week 6: 30 March - 6 April
Coming up with possible project ideas.
Week 7: 6 - 12 April
Conceptual stage, thinking how I would want my gimbal project to work, coming up with ideas regarding components and spending a lot of time looking for correct/compatible components, as I think this project is a bit complex for my current level of understading.
Week 8: 12 - 18 April
Ordering a big part of components (motors, drivers+encoders, STM32 board). More research.
Week 9: 19 - 25 April
Ordering next batch of components (IMU, battery and charger). More research x2. Changed to attempting CAN connection (lord have mercy).
Week 10: 26 April - 2 May
Arrival of most components. Realised I need for the CAN bus a twisted pair insulated wire, had lots of trouble finding some available in Romania till I found some and ordered. Started working on the 3D printed components, the motor magnet couplings, the driver cages and the arms, alongside prototyping ways for cable management in Fusion 360.
Week 11: 3 - 9 May
Finished designing the driver cages, still working on the rest of the components. Cable arrived. Realised my drivers have small can cables which I need to further connect to perfboards to fulfill CAN Bus conditions. Starting thinking about the KiCAD schematic and the different communication protocols required for pin connections between the board and the peripherals.



Week 12: 10 - 16 May
Finished the KiCAD schematic and submitted to Git branch for review by lab assistants. Worked on setting up motor drivers and motors with USB-C connection and integrated ODrive Python programs developed for MKS XDRive Mini. Still working on 3D design for arms and rails for coupling the 3 axis components.
Week 13: 18 - 23 May
Things started going horribly wrong. 2 drivers fried, lots of components purchased and unusable, I ended up changing my project idea from SteadyFrame to KaraBox, the karaoke idea... Very little available working time. Lots of stress.
Week 14: 25 - 30 May
Components started arriving and I started assembly whenever I didnt have tests (mostly nights...). Managed to get everything working, relatively well.
Added photos during the building process and a final one with the box and the speakers from after the PM Fair with the cardboard box prototype.







Hardware
Hardware used for creating this project: STM32 NUCLEO-U545RE-Q board, ESP32-WROOM-32 DevKit v1, MH-M38 Bluetooth audio receiver with onboard amplifier, ST7789V 2.8" TFT display, ST7789V 1.3" TFT display, MAX7219 8x8 LED matrix, DHT22 temperature/humidity sensor, a 4Ω speaker pair, and the power distribution with the LiPo battery and the DC-DC step down converter setup I had to DIY in the meantime.
Schematics
Bill of Materials
| Device | Usage | Price |
|---|---|---|
| STM32 NUCLEO-U545RE-Q | The main board - runs the Rust firmware, drives the display and LED matrix, reads the sensor, and commands the ESP32 over SPI | 105 RON |
| ESP32-WROOM-32 DevKit v1 | The wireless bridge - exposes a Bluetooth Classic SPP server to the phone, forwards commands and lyrics to the STM32 over SPI1 | 35 RON |
| MH-M38 Bluetooth Audio Receiver | The audio path - pairs with the phone as a standard A2DP sink and drives the speakers through its onboard amplifier; no firmware needed | 25 RON |
| ST7789V 2.8" TFT Display (240x320, SPI) | The main display - shows the current song title, artist, lyric line being sung | 59 RON |
| Display TFT 1.3 cu ST7789V 240x240 OKY4029) | The other display - used for displaying sensor data | 31 RON |
| MAX7219 8x8 LED Matrix | The accent display - shows a heart icon when Bluetooth is paired, a VU bar while playing, and an idle animation otherwise | 12 RON |
| DHT22 AM2302 | Shows current ambient conditions on the status bar | 40 RON |
| 2x 4Ω speakers | The audio output, driven directly by the MH-M38's onboard amplifier | 30 RON |
| LiPo GENS ACE G-Tech Soaring 4S 14.8 V 2200mA | The battery - supplies power to all components | 150 RON |
| LM2596S | DC-DC Buck Step Down Convertor LM2596S 4.0~40V to 1.25-37V - for supplying correct voltage to STM32 board | 48 RON |
| Gens Ace iMars mini G-Tech | The battery charger - charges the battery when needed | [245 RON] |
| Wires, perfboards, headers | Lots of em | - |
| Total: | ~700 RON |
Software
| Library | Description | Usage in this project |
|---|---|---|
| embassy-stm32 | Hardware abstraction layer for STM32 microcontrollers | Main HAL used for GPIO, SPI, DMA, timers, and peripheral initialization on the STM32U545RE-Q |
| embassy-executor | Async executor for embedded Rust | Provides the entry point and is still used to spawn the ESP32 SPI slave task |
| embassy-time | Async timers and delays | Used for DHT22 polling, LED matrix animation timing, display retry loops, and startup delays |
| embassy-sync | Async synchronization primitives | Used for global channels between modules |
| embassy-futures | Async combinators such as join4 | Used in main.rs with join4(...) to run the DHT22 reader, main LCD display, LED matrix, and small temperature display concurrently |
| embassy-embedded-hal | Adapters between Embassy and embedded-hal traits | Allowss multiple devices to share the same SPI bus with separate chip-select pins |
| embedded-hal | Common embedded hardware abstraction traits | Used by the SPI device drivers |
| mipidsi | MIPI-DCS display driver supporting ST7789 and other displays | Drives both ST7789V displays through SPI and provides display |
| embedded-graphics | 2D drawing library for embedded displays | Used to draw text and clear screen regions on both ST7789V displays |
| heapless | Fixed-capacity data structures for no_std systems | Used for formatting temperature and humidity text for the small display |
| defmt | Compact logging framework for embedded devices | Used for logging startup messages and debugging information |
| defmt-rtt | RTT transport backend for defmt | Sends logs through the ST-Link RTT channel |
| panic-probe | Panic handler for embedded Rust | Reports panics through the debug probe during development |
For the ESP32 side of the project, the firmware is written in C++ on top of the Arduino-ESP32 framework, since the BT Classic SPP stack there is the most mature option available. The dependencies for that part are:
| Library | Description | Usage |
|---|---|---|
| Arduino-ESP32 core | Espressif's official Arduino framework for the ESP32 | Provides the BluetoothSerial library (BT Classic SPP server) and the SPI master driver |
| ArduinoJson 7 | JSON serialization and parsing for Arduino | Parses the line-JSON command protocol from the phone and serializes telemetry events back to it |
For the Android app, the dependencies are:
| Library | Description | Usage |
|---|---|---|
| Jetpack Compose | Modern declarative UI toolkit for Android | The entire UI (connection status, song picker, transport controls, lyrics view) |
| AndroidX Lifecycle | ViewModel and lifecycle-aware components | Holds the playback state and survives configuration changes |
| Kotlinx Coroutines | Structured concurrency for Kotlin | Drives the BT socket reader loop |
Links
- Embassy book - the official guide for async Rust on embedded
- LRC lyrics file format reference
- ESP32 BluetoothSerial library examples
- ST7789V datasheet and init sequence notes
- mipidsi driver design write-up
- Bluetooth Classic SPP UUID and the standard service record format
...