Multi-modal Reaction Time Trainer
A reaction time training device with random rounds selected from 4 stimulus-response pairs.
Author: Alexandru Dima
GitHub Project Link: https://github.com/UPB-PMRust-Students/acs-project-2026-dimutz
Description
A multi-modal reaction-time training device built on an STM32 microcontroller, using various visual, audio, and mechanical stimuli (LEDs, buzzer, OLED display, servo motor) and multiple user input methods (buttons, analog sensors, and IMU gestures). The device measures reaction time across randomized rounds, calculates performance scores in real time, stores user profiles and leaderboards in non-volatile memory, and provides a structured game-like experience with menus, sessions, and statistical feedback.
Motivation
I chose this project in order to explore embedded systems through an interactive application focused on training and measuring human reaction times. It combines real-time input processing with precise timing to evaluate how quickly users respond to different stimuli. This makes it both a technical exercise in building a responsive system and a practical tool for improving reaction speed under varying conditions.
Architecture
Log
Week 21 - 27 April
Researched and ordered hardware components from Sigmanortec.
Week 5 - 11 May
Tested hardware components, soldered MPU pins and built the hardware.
Week 12 - 18 May
Developed the software and tested it. Some tweaks are needed.
Week 19 - 25 May
Hardware
The system is based on an STM32 NUCLEO development board, complemented by multiple input and output peripherals. It includes visual outputs (OLED display and LED), an audio output (buzzer), and mechanical output (servo motor). User interaction is handled through a push button, a rotary encoder, analog sensors (potentiometer and photoresistor), and an IMU sensor for gesture detection. Data storage is implemented using an SD card module and non-volatile memory (EEPROM) for saving user profiles and leaderboards.

Schematics
Bill of Materials
| Device | Usage | Price |
|---|---|---|
| Nucleo-U545-RE-Q | The microcontroller | Lab provided |
| OLED display & EC11 Encoder Module | Display - menu + stimulus; Encoder - menu control | 39.98 RON |
| SG90 Servomotor | Stimulus | 9.49 RON |
| Active 5V Buzzer | Stimulus | 1.11 RON |
| LED | Stimulus | 0.30 RON |
| Momentary push button | Response | 4.05 RON |
| Potentiometer | Response | 13.65 RON |
| Photoresistor | Response | 1.69 RON |
| MPU-6500 Module | Response | 12.00 RON |
| MicroSD Module | Data export | 4.38 RON |
| MicroSDHC Card | Data export | 14.98 RON |
| EEPROM AT24C256 | Profile storage | 7.24 RON |
| MB102 Power Supply | Servo power | 6.69 RON |
| Resistor kit | Resistors | 15.16 RON |
| Jumper Wires (M-M 20cm) | Connections | 8.97 RON |
| Jumper Wires (M-F 20cm) | Connections | 8.97 RON |
Software
| Library | Description | Usage |
|---|---|---|
| embassy-stm32 | Async HAL for STM32 (GPIO, I²C, ADC, PWM, EXTI) | Board init, peripherals, and drivers for the STM32U545 |
| embassy-executor | Async/await executor for embedded | Runs main, encoder/button tasks, and the application loop |
| embassy-time | Timers and delays | Round timing, debounce, random wait, and frame pacing |
| embassy-sync | Sync primitives for Embassy | Mutex around the shared I²C bus |
| embassy-embedded-hal | Adapters between Embassy and embedded-hal | I2cDevice for OLED, EEPROM, and MPU on one bus |
| ssd1306 | Display driver for SSD1306 OLED | 128×64 OLED over I²C |
| embedded-graphics | 2D graphics library | Menus, game UI, text, and the false-start mark |
| embedded-hal | Hardware abstraction traits | I²C trait used by EEPROM and MPU drivers |
| defmt | Efficient embedded logging | Debug logs (rounds, false starts, sensor values) |
| defmt-rtt | RTT transport for defmt | Sends log output to the debug probe |
| cortex-m | Cortex-M support crate | Low-level CPU access (e.g. nop during ADC sampling) |
| cortex-m-rt | Runtime for Cortex-M | Reset vector and runtime startup |
| panic-probe | Panic handler | Prints panics over defmt on the probe |
| heapless | Collections without heap allocation | Fixed-size Vec and String for profiles and UI |
| static_cell | 'static initialization helper | Stores the shared I²C bus for the firmware lifetime |