If you are trying to configure analog for Acebott ESP32 robotics kits, the direct answer is that you must use the ADC1-capable GPIO pins (typically GPIO 32, 33, 34, 35, 36, and 39) exposed on the Acebott shield. The ESP32’s internal ADC is notoriously noisy and non-linear at the voltage rails, meaning a raw analogRead() will yield jittery data. To get stable analog readings for line trackers, potentiometers, or light sensors on an Acebott board, you must use 12-bit resolution, apply an 11dB attenuation, and implement software multisampling.
This guide covers the exact pin mappings for the Acebott ESP32 STEM shield, provides production-ready Arduino C++ code with built-in noise filtering, and details the specific hardware traps that cause ADC failures on this platform.
Hardware Spec Sheet & Parts List
Difficulty Rating: Intermediate (Requires understanding of voltage dividers and ADC attenuation)
Estimated Time: 25 minutes
Required Components
- Microcontroller: ESP32-WROOM-32E DevKit V1 (30-pin or 38-pin variant, depending on your Acebott shield header)
- Shield: Acebott ESP32 Robotics Expansion Board
- Analog Sensor 1: 10kΩ Linear Taper Potentiometer (for testing variable voltage)
- Analog Sensor 2: GL5528 Photoresistor (LDR) with a 10kΩ pull-down resistor
- Wiring: 22 AWG solid core jumper wires
- Measurement: True-RMS Digital Multimeter (to verify actual voltage vs. ADC reported voltage)
Acebott ESP32 Analog Pin Mapping
The Acebott shield silkscreen often labels analog ports as A0, A1, A2, etc. However, the ESP32 does not have dedicated 'A' pins like an Arduino Uno. These labels map to specific GPIOs that are hardwired to the ESP32's internal SAR ADC.
| Acebott Silkscreen | ESP32 GPIO | ADC Channel | WiFi Safe? | Notes & Constraints |
|---|---|---|---|---|
| A0 / Port 1 | GPIO 36 (SVP) | ADC1_CH0 | Yes | Input only. No internal pull-up. Best for LDRs. |
| A1 / Port 2 | GPIO 39 (SVN) | ADC1_CH3 | Yes | Input only. Susceptible to RF noise if WiFi is active. |
| A2 / Port 3 | GPIO 34 | ADC1_CH6 | Yes | Input only. Standard analog input. |
| A3 / Port 4 | GPIO 35 | ADC1_CH7 | Yes | Input only. Standard analog input. |
| Unused / Internal | GPIO 32 | ADC1_CH4 | Yes | Often used for internal battery voltage monitoring on Acebott boards. |
| Unused / Internal | GPIO 33 | ADC1_CH5 | Yes | Available on breakout headers. |
Stable Analog Reading: The Code
The ESP32's internal ADC suffers from high noise floors and non-linearity near 0V and 3.3V. The code below targets the ESP32 Arduino Core v2.0.14+. It uses analogReadMilliVolts(), which automatically applies the factory eFuse calibration data stored on your specific ESP32 silicon, vastly improving accuracy over the raw analogRead() function. It also implements a 16-sample moving average to eliminate high-frequency jitter.
/*
* Acebott ESP32 Analog Sensor Reader
* Target: Acebott ESP32 Shield + ESP32-WROOM-32E
* Core: ESP32 Arduino Core v2.0.14 or newer
*/
// Pin definitions mapped to Acebott Shield ADC1 ports
#define PIN_POTENTIOMETER 34 // Acebott A2
#define PIN_LDR 36 // Acebott A0
// Multisampling configuration to smooth ESP32 ADC noise
const int SAMPLE_COUNT = 16;
const int SATURATION_THRESHOLD_MV = 3100; // ESP32 ADC non-linear above ~3.1V
void setup() {
Serial.begin(115200);
delay(1000); // Allow serial monitor to connect
// Configure ADC for maximum resolution and voltage range
analogReadResolution(12); // 12-bit (0-4095)
analogSetAttenuation(ADC_11db); // Full 0-3.3V range
Serial.println("Acebott ESP32 Analog Reader Initialized.");
}
void loop() {
// Read Potentiometer with multisampling and error handling
int pot_mv = readStableAnalogMV(PIN_POTENTIOMETER);
// Read LDR with multisampling and error handling
int ldr_mv = readStableAnalogMV(PIN_LDR);
// Error Handling: Check for ADC saturation / overvoltage
if (pot_mv >= SATURATION_THRESHOLD_MV) {
Serial.printf("[WARN] Potentiometer saturated at %d mV. Check for 5V leak!\n", pot_mv);
} else {
Serial.printf("Potentiometer: %d mV\n", pot_mv);
}
if (ldr_mv >= SATURATION_THRESHOLD_MV) {
Serial.printf("[WARN] LDR saturated at %d mV. Check pull-down resistor.\n", ldr_mv);
} else {
Serial.printf("LDR: %d mV\n", ldr_mv);
}
Serial.println("-------------------");
delay(500);
}
// Function to read analog voltage in millivolts with noise filtering
int readStableAnalogMV(int pin) {
long total_mv = 0;
for (int i = 0; i < SAMPLE_COUNT; i++) {
// analogReadMilliVolts uses eFuse calibration for accuracy
total_mv += analogReadMilliVolts(pin);
}
return (int)(total_mv / SAMPLE_COUNT);
}
Debugging ADC Failures & Error Strings
When configuring analog for Acebott ESP32 builds, you will inevitably hit hardware or software snags. If your serial monitor misbehaves, check these first three things:
- Verify Voltage Levels: Use a multimeter to ensure the sensor output does not exceed 3.3V. Acebott kits sometimes include 5V sensors; plugging these directly into the shield will saturate the ADC and can permanently damage the GPIO.
- Check WiFi/ADC2 Conflicts: If your code initializes
WiFi.begin(), ensure you are not using ADC2 pins (GPIO 25, 26, 27, etc.). - Confirm Grounding: The sensor ground must be tied to the Acebott shield's GND. A floating ground will cause the ADC to read random electromagnetic noise.
Common Error Strings and Ranked Causes
Symptom 1: analogRead() returns 4095 continuously (or analogReadMilliVolts returns ~3300)
- Cause 1 (Most Likely): Overvoltage. A 5V sensor is connected without a voltage divider. The internal ESD protection diodes are clamping the pin to VDD (3.3V).
- Cause 2: Missing pull-down resistor on an LDR or open-circuit potentiometer wiper. The pin is floating high.
- Cause 3: You are attempting to read an output-only pin or a pin strapped to VDD on the Acebott shield.
Symptom 2: Readings fluctuate ±150 counts on a stable DC voltage
- Cause 1: ESP32 inherent ADC noise. Fix this by implementing the multisampling loop provided in the code above.
- Cause 2: USB power supply noise. The 5V rail from a cheap PC USB port is notoriously noisy. Power the Acebott board via a regulated LiPo battery or a high-quality 5V wall adapter.
Symptom 3: Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU 0)
- Cause 1: You placed
analogRead()oranalogReadMilliVolts()inside an Interrupt Service Routine (ISR). The ESP32 ADC read function takes several microseconds and uses RTOS mutexes, which will trigger the Watchdog Timer if called from an ISR. Move analog reads to the mainloop()and use a boolean flag in your ISR.
Extending and Simplifying the Build
How to Simplify
If you do not need precise millivolt readings and only care about relative changes (e.g., tracking a line or detecting basic light/dark thresholds), you can simplify the code by dropping analogReadMilliVolts() and using the raw analogRead(). This saves a small amount of CPU overhead. Just remember that raw values will drift with temperature and vary from board to board.
How to Extend (The 16-Bit Upgrade)
The ESP32's internal 12-bit ADC is fundamentally flawed for precision robotics (like calculating exact distances via IR sensors). To extend this build for professional-grade precision, bypass the internal ADC entirely and add an ADS1115 16-Bit I2C ADC.
- Wiring: Connect ADS1115 SDA to GPIO 21, SCL to GPIO 22, VDD to 3.3V, and GND to GND on the Acebott shield.
- Result: You gain true 16-bit resolution (0-65535), a programmable gain amplifier (PGA), and hardware-level noise rejection.
- Cost: An ADS1115 breakout board costs roughly $4 to $8, a highly cost-effective upgrade for advanced Acebott robotics projects.
Frequently Asked Questions
Can I use analog for Acebott ESP32 while WiFi is connected?
Yes, but only if you use ADC1 pins (GPIO 32, 33, 34, 35, 36, 39). The ESP32's WiFi radio shares hardware resources with ADC2. The moment you call WiFi.begin(), the hardware multiplexer locks out ADC2 pins (like GPIO 25, 26, 27). If your Acebott shield routes a specific sensor port to an ADC2 pin, you must either disable WiFi, move the sensor wire to an ADC1 pin, or use an external I2C ADC.
Why does my Acebott line-tracking sensor give digital highs instead of analog values?
Many line-tracking modules included in STEM kits have a built-in comparator chip (like the LM393) with a blue trimmer potentiometer. These modules output a clean Digital HIGH/LOW on the DO (Digital Out) pin, and an analog voltage on the AO (Analog Out) pin. If you are reading 4095 or 0 exclusively, ensure you have wired the sensor's AO pin to the Acebott shield's analog port, not the DO pin. Furthermore, verify the sensor is powered by 3.3V; if powered by 5V, the AO pin will output up to 5V, saturating the 3.3V ESP32 ADC.
How do I calibrate the 3.3V reference on the Acebott board?
You do not need to manually calibrate it in software if you are using ESP32 Arduino Core v2.0.x or newer. Espressif burns a unique calibration value into the eFuse of every ESP32 chip at the factory. The analogReadMilliVolts() function automatically queries this eFuse value and applies the correction curve. If you are using an older core version, you must manually map the raw ADC values using a multimeter and a map() function, but upgrading your board manager package is the recommended fix.






