← All projects
Aug 04, 2026Active

ESP32 Sensor Rig

A ground-up analog sensor pipeline on ESP32 — from a noisy raw ADC reading to a stable, multi-sensor serial data stream.

Technologies

C++ESP32Arduino framework

Skills

Embedded systemsAnalog electronicsSignal filteringSerial protocols

Objectives

Build a small, well-understood foundation for analog sensing on the ESP32 before attempting anything more ambitious — specifically:

  • Get comfortable with the ESP32's ADC behavior (12-bit resolution, ADC1 vs ADC2 constraints).
  • Establish a clean, low-noise analog signal chain from a physical sensor to a digital reading.
  • Build a reusable serial data format I can plot and log for future sensor projects.

Background

Most of my prior electronics experience was on the Arduino Uno. Before building anything robotics-adjacent on the ESP32, I wanted a deliberately small project that isolated just the sensing pipeline — no motors, no actuators, no complexity beyond "read the physical world accurately and report it."

Approach

Start with a single photoresistor on a voltage divider, get a stable reading over serial, then extend to a second sensor (a thermistor) and format the output as CSV so both streams can be logged and plotted together.

Implementation

The circuit is a standard voltage-divider photoresistor setup feeding an ADC1-capable GPIO pin (ADC2 pins are unreliable while Wi-Fi is active on the ESP32, so I avoided them from the start). Firmware is written directly against the Arduino framework for ESP32, using analogRead() with an explicit analogReadResolution(12) call to make the 12-bit range explicit in code rather than assumed.

A second sensor (thermistor, also on a voltage divider) was added on a separate ADC1 pin, with both readings printed as a single CSV line per interval (lightRaw,tempRaw,millis), making it trivial to pipe into a plotting script later.

Problems & challenges

Initial readings swung by roughly ±150 out of a possible 4095 even under a static light source — far too noisy to be useful. Traced it to a missing dedicated ground connection between the sensor's voltage divider and the ESP32; the breadboard rail wasn't actually bridged to the board's GND on that side.

Solutions

Ran a dedicated ground wire directly from the sensor divider to the ESP32 GND pin, which brought noise down substantially. On top of that, added a simple software-side moving average (10 consecutive samples) as a cheap low-pass filter rather than adding a hardware smoothing capacitor, since the goal here was to understand the software-side option first.

Testing

Validated by covering and uncovering the photoresistor by hand and confirming the reading tracked smoothly and predictably, without jumps unrelated to actual light changes. Cross-checked the thermistor channel by touching it directly and confirming a smooth reading increase.

Results

A stable two-sensor analog pipeline reading well within ±3 counts of noise (down from ±150), streaming CSV-formatted data over serial at a fixed interval, using only ADC1 pins to stay clear of Wi-Fi/ADC2 conflicts.

What I learned

The single biggest lesson wasn't about the ESP32 specifically — it was that "noisy" sensor data is very often a wiring problem before it's a software problem. I would have reached for a filtering algorithm first if I hadn't methodically checked the physical connections.

Future improvements

  • Move from polling in the main loop to a timer-interrupt-driven sampling approach.
  • Add a third sensor type (likely an IMU) to start building toward a more robotics-relevant sensor stack.
  • Log data to SD card or over Wi-Fi instead of only serial, so runs can be longer than a single active session.