This project is a high-frequency data logging system for vehicle suspension telemetry. It utilizes the ESP32’s dual-core architecture to capture sensor data at 100Hz while maintaining a responsive web dashboard and background cloud uploads.
- Power On: Power on the ESP32. The RGB LED will turn White/Purple during boot.
- Initial Setup:
- Search for Wi-Fi:
SD Squared Telemetry(Password:sdsquared). - Visit
http://esp32-ap.local(or192.168.4.1) to enter your local Wi-Fi credentials - i.e. hotspot information.- If you are using a hotspot it is highly reccommended the SSID has no special characters or spaces in it
- Search for Wi-Fi:
- Operation:
- Setup Run: Press Button (GPIO 14) once. LED turns Yellow. A new run file is prepared.
- Record: Press again. LED turns Red. Data logs at 100Hz.
- Stop: Press again. LED returns to Green.
- Sync: Visit
http://esp32.localon your local network to upload files to the cloud.
Indicates the current operational mode of the telemetry system.
| State | Color | Description |
|---|---|---|
| Setup | ⚪ White | Initializing storage and launching tasks. |
| Ready/Idle | 🟢 Green | System ready; waiting to start a run. |
| Run Setup | 🟡 Yellow | New file created on SD and unweighted values recorded; awaiting button press to record. |
| Recording | 🔴 Red | Actively logging sensor data to the SD card at 100Hz. |
| Error | 🔵 Blue | Fatal error: SD Card mount failed or file creation failed. |
Indicates WiFi status and background network activity via GPIO 2.
| State | Pattern | Description |
|---|---|---|
| AP Mode | ⚪ Slow Blink | Acting as an Access Point (1000ms interval). |
| Connecting | ⚪ Fast Blink | Attempting to join a network (200ms interval). |
| Connected | ⚪ Solid | Successfully joined WiFi; Web Server is live. |
| Disconnected | Off | Not connected to any WiFi network. |
- Dual-Core Execution:
- Core 0: Dedicated to 100Hz sensor sampling and SD card I/O to prevent data loss.
- Core 1: Handles Wi-Fi, Async Web Server, and UI updates.
- Storage: Saves high-resolution CSV files to an SD Card (naming format:
run_n+1.csv). - Cloud Integration: Background task streams CSV data + metadata to a Railway-hosted backend via
WiFiClientSecure. - mDNS Support: Access the device via
esp32.localoresp32-ap.localinstead of IP addresses.
The codebase is modularized to separate hardware configuration, global state, storage logic, and networking tasks.
main.cpp: The entry point. It initializes hardware pins, mounts storage, and launches the FreeRTOS tasks on specific cores.config.h: The single source of truth for hardware. It contains pin definitions (LEDs, sensors, SD), sampling frequency, and the backend API URL.globals.h / .cpp: Manages the system's "brain." It stores shared variables like WiFi status and recording state, and handles theupdateOnBoardLed()logic for non-blocking blinking.
storage_manager.h / .cpp: Handles the heavy lifting for the SD Card and LittleFS. It manages the creation of new run files (e.g.,run_1.csv) and flushes data buffers from RAM to the physical card.telemetry_tasks.h / .cpp: Contains the dual-core execution loops:- Core 0 (
DataTask): High-priority loop for 100Hz sensor sampling and physical button debouncing. - Core 1 (
WiFiTask): Manages the web server and system updates.
- Core 0 (
network_manager.h / .cpp: Orchestrates WiFi connectivity (AP vs. Station mode) and defines all Async Web Server routes for the dashboard and data management./dataFolder (Web Interface): Static assets served from LittleFS to provide the user interface:index.html: The initial WiFi configuration portal used to connect the ESP32 to a local network.connected.html: The main telemetry dashboard for viewing recorded runs and entering metadata.style.css: The stylesheet providing a clean, responsive design for both mobile and desktop users.script.js: Frontend logic that fetches the run list, handles metadata forms, and communicates with the ESP32 API.
- Background Upload: A specialized
uploadRunTaskthat streams large CSV files from the SD card to a Railway backend via multipart HTTPS.
| Core | Task Name | Responsibilities |
|---|---|---|
| Core 0 | DataTask |
Button debouncing, 10ms (100Hz) sampling, SD buffering/writing. |
| Core 1 | WiFiTask |
Web server management, mDNS responder, SoftAP configuration. |
| Async | UploadTask |
Background HTTPS POST streaming of CSV data from SD to Cloud. |
| Component | Pin | Notes |
|---|---|---|
| Button | GPIO 9 | Active LOW; cycles Idle ➔ Setup ➔ Record. |
| Onboard LED | GPIO 13 | WiFi connection status. |
| RGB LED | R=10, G=11, B=12 | Status indicators. |
| NeoPixel | GPIO 33 (data), GPIO 21 (power) | Battery level indicator. |
| SD Card CS | GPIO 5 | SPI Chip Select for storage. |
| Front Suspension | GPIO 15 (A3) | Analog input for travel measurement. |
| Rear Suspension | GPIO 14 (A4) | Analog input for travel measurement. |
| Battery Gauge I2C | SDA=3, SCL=4 | MAX17048 at address 0x36. |
The ESP32 hosts an AsyncWebServer with the following endpoints:
GET /: Serves the configuration portal (AP mode) or dashboard (STA mode).POST /connect: Receives SSID and Password to switch from AP to Station mode.GET /runs: Returns a JSON list of all.csvfiles currently stored on the SD card.POST /uploadRun: Triggers a background task to upload a specific file with metadata (run name, track, comments).POST /deleteRun: Removes a specific file from the SD card.
- HTTPS Uploads: Uses
client.setInsecure()to handle certificates without the overhead of root CA management on the MCU. - Buffer Management: Data is captured in a 512-line RAM buffer before being flushed to the SD card to prevent I/O blocking.
- mDNS on Android: Android users should type the full
http://esp32.local/in Chrome to ensure the address is resolved correctly.