⏱️ 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 using EnableInterruptRisingEdgeWithCallback().
  • 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 on gpiod_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.