Skip to content

SolusDev-sys/ESP32-Realtime-Data

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ESP32 Realtime Data (Upgraded!)

A real-time embedded-to-desktop signal visualization project built to demonstrate cross-platform data streaming and hardware-software integration. Developed using C++ (Arduino framework with FreeRTOS) on the ESP32 and Python on the desktop side, the system generates a live signal, transmits it via serial communication, and renders an animated real-time graph upon reception via PySide6.


Overview

┌─────────────────────┐        Serial / UART         ┌──────────────────────────┐
│      ESP32          │  ──────────────────────────►  │     Desktop (Python)     │
│                     │        115200 baud            │                          │
│  FreeRTOS Tasks     │                               │  PySide6 + QtGraphs      │
│  ├─ toggleLED1      │   PIN2:HIGH | Task:LED1        │  ├─ Serial reader thread │
│  ├─ toggleLED2      │   PIN2:LOW  | Task:LED2        │  ├─ Ring buffer + lock   │
│  └─ serialWriter    │                               │  └─ Live step-plot graph │
└─────────────────────┘                               └──────────────────────────┘

Two FreeRTOS tasks toggle a shared GPIO pin at different intervals (500 ms and 300 ms). Every state change is queued and transmitted over UART. The Python desktop app reads the stream, parses each message, and plots a live step-function graph that updates every 50 ms.


Features

  • Real-time step-plot graph — live HIGH/LOW waveform rendered with QtGraphs
  • Dual FreeRTOS tasks — two independent tasks competing for a shared GPIO pin via mutex
  • Dedicated serial writer task — UART output is decoupled from the GPIO critical section via a FreeRTOS queue, minimising lock contention
  • Finite mutex timeout — 100 ms watchdog instead of portMAX_DELAY; timeouts are logged without hanging the task
  • Thread-safe Python bridge — ring buffer protected by threading.Lock, with a dirty flag to skip idle UI redraws
  • Connection-aware status indicator — animated dot turns green when connected, red when disconnected
  • Auto-reconnect — serial reader automatically re-opens the port on disconnect

Project Structure

├── RTOS_Blinking_LED   # ESP32 firmware (C++ / Arduino + FreeRTOS)
├── main.py            # Desktop application (Python / PySide6)
└── main.qml           # UI layout and live graph (Qt Quick / QtGraphs)

Requirements

ESP32 (Hardware)

Item Detail
Board ESP32 (any variant)
Framework Arduino with FreeRTOS
LED Connected to GPIO 2 (built-in on most boards)
Baud rate 115200

Desktop (Software)

Package Version
Python 3.9+
PySide6 6.x
pyserial 3.x

Running

1. Flash the ESP32

Open RTOS_Blinking_LED.ino in the Arduino IDE (or PlatformIO), select your board and port, then upload.

2. Start the desktop app

python main.py

The graph will begin plotting as soon as the serial connection is established.


Architecture Notes

ESP32 — FreeRTOS Task Design

Task Priority Interval Role
toggleLED1 2 500 ms Drives GPIO HIGH → LOW
toggleLED2 2 300 ms Drives GPIO HIGH → LOW
serialWriter 1 (lowest) event-driven Drains log queue to UART

GPIO writes are the only operations inside the mutex critical section. Serial output happens entirely outside the lock via a 16-slot FreeRTOS queue, eliminating slow UART I/O from the critical path.

Python — Threading Model

Serial thread (daemon)          Qt main thread
──────────────────────          ──────────────
readline() [blocking]           QTimer @ 50 ms
  → parse line                    → _flush()
  → timestamp                       → check dirty flag
  → acquire lock                    → snapshot buffers
      append to deque               → release lock
      set dirty = True              → format + emit signal
  → release lock                      → QML redraws graph

The dirty flag ensures _flush() is a no-op on idle ticks, avoiding redundant list copies and Qt signal emissions.


Signal Format

The ESP32 outputs lines in the following format over UART:

PIN2:HIGH | Task:LED1
PIN2:LOW  | Task:LED2

The Python parser splits on |, reads the state (HIGH/LOW) from the first segment, and the task name from the second.


AI Assistance

This project was reviewed, upgraded, and documented with the help of Claude (Sonnet 4.6), an AI assistant made by Anthropic.


License

AGPL-3.0 license

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors