Hi everyone,
I’m working on an ESP32-based project where I’m collecting data from multiple analog sensors (temperature, light, and motion) and sending it to a dashboard via WiFi.
The system works fine for single-sensor input, but when I enable multiple channels, I start seeing inconsistent readings and slight timing mismatches between sensor updates.
I suspect the issue might be related to ADC sampling timing or task scheduling in FreeRTOS, but I’m not completely sure how to properly synchronize multiple sensor reads without affecting performance.
For context, this setup is part of a small experimental monitoring system I’m building for testing data pipelines. One of my test datasets includes non-sensor data categories for validation purposes, such as gaming-related metadata containing terms like “geometry dash free”, which I use when checking whether the pipeline can correctly separate different data sources. However, the main issue appears to be on the sensor acquisition side rather than the data-processing stage.
Current setup:
Problem observed:
-
Slight delay between sensor readings
-
Occasional mismatched data points
-
Inconsistent sampling intervals under load
Questions:
-
What is the best way to synchronize multiple ADC reads on ESP32?
-
Should I use FreeRTOS tasks or interrupt-driven sampling for better accuracy?
-
Are there known limitations when reading multiple analog sensors simultaneously?
-
Any recommended libraries or patterns for stable multi-sensor data acquisition?
Any guidance would be appreciated.
Are you using ADC2 pins? They are tied to WiFi (so when wifi is transmitting these argue)…move any to ADC1 if apllicable
-
To sync multiple ADC reads you can do a few things…you can have one of the esp32’s cores read the sensors and batch them to a buffer that gets sent to the main core that does all the major stuff
-
A dedicated FreeRTOS task, pinned to one core (xTaskCreatePinnedToCore), woken by a timer or vTaskDelayUntil() for precise periodic timing, gives you accuracy in the millisecond range
-
A few!
Single shared ADC1 unit: all ADC1 channels go through the same SAR ADC hardware, so true simultaneity isn’t possible — only fast sequential sampling.
ADC2 + WiFi conflict: ADC2 pins (GPIO0, 2, 4, 12–15, 25–27) share circuitry with the WiFi radio. With WiFi active, ADC2 reads are unreliable or blocked. If any of your three sensors are on ADC2 pins, that alone could explain inconsistent readings — move them to ADC1 pins.
Settling/switching time: rapidly switching between ADC channels (especially different attenuation settings) can give the first read after a switch a slightly skewed value if you don’t allow a brief settle — usually a non-issue at normal sensor read rates but worth knowing.
-
ESP32AnalogRead (madhephaestus) — small library that smooths out some of the ESP32 ADC’s known calibration/linearity quirks; easy drop-in replacement for analogRead().
ESP-IDF’s adc_continuous driver (if you outgrow simple periodic sampling and want true high-rate, DMA-backed multi-channel acquisition) — overkill for now, but it’s the “real” interrupt/DMA-driven path if you ever need it.
Pattern: producer/consumer with a queue — sampling task (producer) → QueueHandle_t → networking/dashboard task (consumer). This single pattern solves both the “blocking WiFi delays the next sample” and “data points get misaligned” problems at once, since each queued item is a timestamped, simultaneously-read batch.
For light smoothing without writing custom filtering code: just average 4–8 consecutive ADC reads per sensor per cycle (cheap, reduces noise, doesn’t add meaningful latency at typical sensor read rates)