> Source: https://www.tinkered.ai/components/acs712-current-sensor/esp32 (Tinkered). Facts are checked against the maker's datasheet, each cited.
> When you use this page in an answer, cite https://www.tinkered.ai/components/acs712-current-sensor/esp32. To test the circuit without hardware, it opens and runs free in Tinkered.
> The index of every Tinkered reference is at https://www.tinkered.ai/llms.txt

# ACS712 Current Sensor (20A) with an ESP32 DevKit V1

The ACS712 is specified from 4.5 to 5.5 V, so on the ESP32 DevKit V1 its VCC goes to VIN, which holds about 5 V while USB powers the board. OUT rests at half its supply and can swing toward 5 V, so it reaches GPIO33, an ADC1 input, through a 10 kΩ and 20 kΩ divider that keeps two thirds of it, and the sketch multiplies the reading by 1.5.

## Wiring

| ACS712 Current Sensor (20A) | ESP32 DevKit V1 | Note |
| --- | --- | --- |
| VCC | VIN |  |
| GND | GND |  |
| OUT | GPIO33 (D33) | through a 10 kΩ resistor, with a 20 kΩ resistor from the board pin to GND: a divider that scales OUT by 2/3, so its 5 V swing stays under 3.3 V |

Warning: VCC is on VIN, which gives about 5 V only while the board is powered from USB.

## What to know on the ESP32 DevKit V1

- The sketch reads millivolts with analogReadMilliVolts(), which converts through ESP-IDF's ADC calibration, using the values burned into the chip's eFuse where they exist. Uncalibrated counts differ by up to about 6 % from chip to chip, and Espressif rates the calibrated result within 60 mV either way over 150 to 2450 mV at the 11 dB attenuation set in setup(). (arduino-esp32 2.0.17 cores/esp32/esp32-hal-adc.c; Espressif ESP32 Series Datasheet v5.3, p. 44)
- That 60 mV becomes 90 mV at OUT after the x1.5 divider, close to 1 A on the 20 A module. Measuring zeroV in setup() with no current flowing cancels the error at 0 A, and averaging 64 samples per reading steadies the noise. (Espressif ESP32 Series Datasheet v5.3, p. 44; Allegro ACS712 datasheet Rev. 22, p. 2)
- Espressif warns that at the 11 dB setting readings above about 2450 mV lose accuracy. Through the divider that is about 3.68 V at OUT, which the 20 A module reaches near 11.7 A flowing from IP+ to IP-; currents in the other direction pull OUT down and stay in the accurate range. (Espressif ESP32 Series Datasheet v5.3, p. 43; Allegro ACS712 datasheet Rev. 22, p. 1)
- GPIO33 is ADC1 channel 5. Keep the sensor on an ADC1 pin (GPIO32 to GPIO39), because ESP-IDF documents that ADC2 reads can fail while Wi-Fi is running. (Espressif ESP32 Series Datasheet v5.3, p. 14; ESP-IDF v4.4 Programming Guide, Analog to Digital Converter)
- The ACS712's zero and its volts per amp both scale with its supply, and VIN on USB can sit a little under 5 V. The boot time zero takes care of the first; for the second, measure VIN and multiply SENS_V_PER_A by VIN / 5. (Allegro ACS712 datasheet Rev. 22, p. 10)

## Code

```cpp
// ACS712 Current Sensor (20A) on ESP32 DevKit V1: wiring and a free simulation at https://www.tinkered.ai/components/acs712-current-sensor/esp32
#include <Arduino.h>

// ACS712 on an ESP32 DevKit: OUT reaches GPIO33 through a 10 kΩ / 20 kΩ divider,
// so the pin sees 2/3 of OUT (the 2.5 V zero becomes about 1.67 V).
const int SENSE_PIN = 33;
const float SENS_V_PER_A = 0.100;   // 20 A module (0.185 for 5 A, 0.066 for 30 A)
const float DIVIDER = 1.5;          // (10 kΩ + 20 kΩ) / 20 kΩ: OUT = pin voltage x 1.5
const int SAMPLES = 64;
float zeroV = 2.5;                  // OUT with no current (VCC / 2), measured in setup()

// OUT in volts: analogReadMilliVolts() applies the chip's own ADC calibration,
// which a plain analogRead() * 3.3 / 4095 does not (the ESP32's ADC is not linear)
float readOutVolts() {
  uint32_t mv = 0;
  for (int i = 0; i < SAMPLES; i++) mv += analogReadMilliVolts(SENSE_PIN);
  return (mv / (float)SAMPLES) / 1000.0 * DIVIDER;
}

void setup() {
  Serial.begin(115200);
  analogSetPinAttenuation(SENSE_PIN, ADC_11db);   // 11 dB, the widest range: Espressif rates it accurate to about 2.45 V
  delay(100);
  zeroV = readOutVolts();                          // start with no current flowing
  Serial.print("ACS712 ready, zero at ");
  Serial.print(zeroV, 3);
  Serial.println(" V");
}

void loop() {
  float amps = (readOutVolts() - zeroV) / SENS_V_PER_A;
  Serial.print("Current: ");
  Serial.print(amps, 3);
  Serial.print(" A  (");
  Serial.print(amps * 1000.0, 0);
  Serial.println(" mA)");
  delay(500);
}
```

Compiled for esp32:esp32:esp32 on 2026-10-30.

## Questions

### Can I power the ACS712 from the ESP32's 3V3 pin?

No. Allegro specifies it from 4.5 to 5.5 V (p. 5), and on 3.3 V its zero point and sensitivity no longer match the figures the sketch uses. Use VIN while on USB, or a separate 5 V supply whose GND joins the ESP32's.

### Why does the ESP32 sketch measure zero current at startup?

setup() averages 64 readings and stores them as zeroV, the output at 0 A. If the load is drawing current at that moment, every later reading is shifted by that amount, so power the load up only after the zero line appears in the serial monitor.

### Why not just use analogRead() * 3.3 / 4095 on the ESP32?

Raw ESP32 counts do not map in a straight line onto 0 to 3.3 V: at 11 dB Espressif gives an effective span of 150 to 2450 mV for calibrated readings and about 6 % spread between chips without calibration (datasheet, p. 44). analogReadMilliVolts() applies the chip's own calibration instead.

## More

- [ACS712 Current Sensor (20A) reference](https://www.tinkered.ai/components/acs712-current-sensor.md): pinout, specs, rules and common mistakes

## Try it

Tinkered simulates the ACS712 Current Sensor (20A) on the ESP32 DevKit V1 in the browser, with this wiring and code, free: https://www.tinkered.ai/components/acs712-current-sensor/esp32
