⏱️ How Realtime Performance Was Achieved
This document outlines the key architectural and implementation techniques used in the FluxSand project to meet the realtime programming requirements of ENG 5220. Our design prioritizes low latency, responsiveness, and correctness under timing constraints.
1️⃣ Interrupt-Driven Design Instead of Polling
✅ GPIO Input Handling
- The
Gpio
class supports edge-triggered interrupt callbacks usingEnableInterruptRisingEdgeWithCallback()
. - Physical buttons wake up the
InputHandler
via hardware interrupts. - Avoids busy-wait loops or CPU-intensive polling.
✅ ADS1115 Conversion Completion Interrupt
- The ADC’s
ALERT/RDY
pin connects to a GPIO and signals data-ready via an interrupt. Ads1115
uses this to schedule safe, efficient per-channel data reads.
📌 Implemented using
libgpiod
+ background threads blocked ongpiod_line_event_wait()
, making the system fully event-driven.
2️⃣ Multithreaded Decoupling for Concurrent Realtime Tasks
Each major subsystem runs in a dedicated thread:
Thread | Responsibility |
---|---|
AHRS::ThreadTask() | Updates orientation estimation |
InferenceEngine::InferenceTask() | Runs ONNX inference logic asynchronously |
CompGuiX::ThreadFun() | Simulates sand physics and updates display |
Mpu9250::CalibrateThreadTask() | Runs long-duration background IMU calibration |
This separation ensures that:
- GUI remains responsive even during heavy computation.
- Inference latency does not stall sensor acquisition.
- Long calibration tasks do not interfere with user inputs.
✅ Thread synchronization is done using
std::binary_semaphore
, ensuring safety and data freshness.
3️⃣ Callback-Driven Data Flow and Event Handling
All modules communicate via callbacks instead of polling or shared flags:
MPU9250 interrupt
→ AHRS::OnData(accel, gyro)
→ InferenceEngine::OnData(...)
→ OnModelResult callback
→ GUI rendering or mode switch
This event cascade ensures low-latency and deterministic response to physical motion or user input.
4️⃣ Latency Considerations and Measured Timings
Realtime Path | Typical Latency |
---|---|
GPIO button press → callback | < 20us |
Gesture motion → inference → GUI update | < 15ms |
AHRS update frequency | ~1000Hz |
All major paths have been analyzed and kept within interactive response times.
5️⃣ Avoiding Non-Realtime Traps
We deliberately avoided common pitfalls that break realtime performance:
Bad Practice | What We Used Instead |
---|---|
Busy loops / sleep() | Semaphores, callbacks, and hardware IRQs |
Main thread blocking | Multithreading with clear separation |
Polling sensors repeatedly | Interrupt-based data-ready signaling |
Using delays for timing | std::chrono and thread sleeping per cycle |
✅ Summary
The realtime strategy for FluxSand focuses on:
- Interrupts over polling
- Threaded execution of independent logic
- Asynchronous data processing via callbacks
- Quantifiable latency and accurate timing
- Safe synchronization using semaphores
This architecture ensures predictable, fast, and robust interaction for a physical embedded system running under Linux.
For diagrams, timing charts or demo videos, please refer to the documentation homepage or test logs.