ESP32 S3 - ACS712 Current Sensor

How much current does your motor really pull when it starts, runs or gets stuck? The ACS712 answers that with a single analog wire, and the ESP32 S3 turns its voltage into amps you can read on your PC. This guide uses the 30A module and a safe 12V DC device, such as a DC motor, LED strip or lamp, so you can try everything on your desk.

What you'll build in this tutorial:

  1. What the ACS712 is and how it senses current without touching your circuit
  2. How to connect it to the ESP32 S3 through a small 10kΩ/20kΩ divider
  3. A DC current meter sketch that finds its own zero point at startup
  4. An AC (RMS) version of the sketch for current that changes direction
ESP32 S3 - ACS712 Current Sensor

Overview of ACS712 Current Sensor

The ACS712 from Allegro is a current sensor chip that reads both DC and AC current. Inside the chip, the load current runs through a thick copper path. That current creates a magnetic field, and a Hall sensor sitting next to the path turns the field into a voltage. Your load and the ESP32 S3 are never wired together: the two sides are isolated up to 2.1 kV RMS. The copper path is only about 1.2 mΩ, so putting the sensor in your circuit changes almost nothing for the load.

With no current, the OUT pin sits in the middle of the supply, about 2.5V. When current flows from IP+ to IP−, the voltage goes up. When it flows the other way, the voltage goes down. On the 30A version used here, every amp moves the output by 66 mV.

Key Specifications

The module needs a 5V supply (4.5V to 5.5V). It will not work properly at 3.3V, so on the ESP32 S3 it takes power from the 5V pin. Its output is ratiometric, which means the 2.5V center and the 66 mV/A step both scale with the real supply voltage. At full scale the OUT pin swings from about 0.52V (−30 A) to about 4.48V (+30 A).

Feature Value
Chip ACS712ELCTR-30A-T (Allegro)
Measuring range −30 A to +30 A (DC or AC)
Sensitivity 66 mV per amp
Output at 0 A VCC / 2 (about 2.5V)
Supply voltage 5V (4.5V to 5.5V)
Bandwidth 80 kHz
Total output error about ±1.5% at 25°C
Isolation 2.1 kV RMS
Copper path resistance about 1.2 mΩ

The ACS712 comes in three current ranges. They look the same, so check the marking on the chip before you use the code:

Version Range Sensitivity
ACS712-05B ±5 A 185 mV/A
ACS712-20A ±20 A 100 mV/A
ACS712-30A ±30 A 66 mV/A

A bigger range means a coarser reading. With the divider and the 12-bit ADC of the ESP32 S3, one ADC step on the 30A module is close to 17 mA. Add normal electrical noise, and you will often see 50 to 100 mA of "fake" current at 0 A. So this module is best for loads from about 0.5 A upward: motors, lamps, LED strips, heaters and chargers. Averaging many readings helps a lot, and both sketches below do that.

ACS712 Pinout

The module has a 3-pin header for the ESP32 S3 side and a 2-screw terminal block for the load side. A small LED lights up when the module is powered.

ACS712 current sensor pinout
  1. VCC — 5V power; connect to the 5V pin of the ESP32 S3
  2. OUT — analog output (about 0.5V to 4.5V); goes to the ESP32 S3 through the divider
  3. GND — ground; connect to GND of the ESP32 S3
  4. IP+ — first screw terminal; current entering here reads as positive
  5. IP− — second screw terminal; current leaves the sensor here

On some modules the two screw terminals have no labels. If your readings come out negative, just swap the two load wires.

How the ACS712 Converts Current to Voltage

The math is short. Take the OUT voltage, subtract the voltage you get at 0 A (Vzero), and divide by the sensitivity:

current (A) = (Vout − Vzero) / 0.066

For example, if Vzero is 2.48V and Vout is 2.55V, the current is (2.55 − 2.48) / 0.066 ≈ 1.06 A. The code does not assume Vzero is exactly 2.5V. Your 5V pin may be 4.9V or 5.1V, and the chip has a small offset, so the sketch measures the real Vzero at startup while the load is off.

Wiring Diagram between ACS712 and ESP32 S3

The analog pins of the ESP32 S3 accept 3.3V at most, but the ACS712 OUT pin can reach about 4.5V. A simple divider fixes this: OUT goes through a 10kΩ resistor to GPIO1, and a 20kΩ resistor goes from GPIO1 to GND. This scales the signal by 2/3, so 4.48V becomes about 2.99V, and the code multiplies by 1.5 to get the real value back.

The wiring diagram between ESP32 S3 ACS712 current sensor

This image is created using Fritzing. Click to enlarge image

From To
ACS712 VCC ESP32 S3 5V pin
ACS712 GND ESP32 S3 GND (any GND pin, e.g. the one on the right side)
ACS712 OUT 10kΩ resistor, other end to GPIO1
GPIO1 20kΩ resistor, other end to GND
12V adapter + (via DC power jack) ACS712 IP+
ACS712 IP− DC device +
DC device − 12V adapter − (via DC power jack)

GPIO1 is an ADC1 pin on the right-side header, close to the GND pins, so the divider wiring stays short. Only the 5V wire has to go to the left side, because the 5V pin is there. Stay on ADC1 (GPIO1 to GPIO10), because ADC2 pins stop working well once WiFi is on. The screw terminal goes in series with the load: cut the plus wire between the adapter and the DC device and put the sensor in that gap.

Safety Notes

Never connect the ACS712 OUT pin straight to a GPIO; without the divider, a large current can push more than 4V into the pin and damage the ESP32 S3. The screw terminal side carries the full load voltage, so learn with a low-voltage DC load like the 12V DC device in this guide. Mains AC (110V or 220V) can kill. If you later measure a mains device, never touch the screw terminal or its wires while the circuit is live, and keep the whole module in a closed box.

ESP32 S3 Code - ACS712 Current Sensor

At startup the sketch takes 1000 readings with no current flowing and stores their average as the zero voltage. After that, every 500 ms it averages 200 readings, multiplies by 1.5 to undo the divider, and uses the formula above to print the sensor voltage and the current. It uses analogReadMilliVolts(), which applies the ESP32 S3's built-in ADC calibration and gives better results than turning a raw analogRead() value into volts by hand.

/* * This ESP32 S3 code was developed by newbiely.com * * This ESP32 S3 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3/esp32-s3-acs712-current-sensor */ #define ACS712_PIN 1 // ESP32 S3 GPIO1 (ADC1) connected to the middle of the 10k/20k divider on the ACS712 OUT pin #define DIVIDER_RATIO 1.5 // (10k + 20k) / 20k: undo the divider to get the real ACS712 OUT voltage #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV (0.066 V) per amp #define ZERO_SAMPLES 1000 // readings used to find the zero-current voltage at startup #define AVG_SAMPLES 200 // readings averaged for each current value float zeroVoltage = 2.5; // OUT voltage at 0 A, measured again in setup() // Read the ACS712 OUT voltage (in volts), averaged over many samples float readSensorVoltage(int samples) { long sum_mV = 0; for (int i = 0; i < samples; i++) { sum_mV += analogReadMilliVolts(ACS712_PIN); // calibrated reading in millivolts delayMicroseconds(100); } float pin_V = (sum_mV / (float)samples) / 1000.0; // voltage on the GPIO pin return pin_V * DIVIDER_RATIO; // voltage on the ACS712 OUT pin } void setup() { Serial.begin(115200); analogSetAttenuation(ADC_11db); // allow the full 0 - 3.1V input range // The load MUST be off now: no current may flow through the sensor Serial.println("Calibrating zero point, keep the load OFF..."); delay(500); zeroVoltage = readSensorVoltage(ZERO_SAMPLES); Serial.print("Zero voltage: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); Serial.println("Done. You can turn the load ON now."); } void loop() { float voltage = readSensorVoltage(AVG_SAMPLES); float current = (voltage - zeroVoltage) / SENSITIVITY; // amps (negative = reverse direction) Serial.print("Sensor voltage: "); Serial.print(voltage, 3); Serial.print(" V | Current: "); Serial.print(current, 2); Serial.println(" A"); delay(500); }

Detailed Instructions

  1. New to ESP32 S3? Complete our Getting Started with ESP32 S3 guide first.
  2. Build the circuit: Wire everything as in the diagram, but leave the 12V adapter unplugged for now.
  3. Connect the board: Plug the ESP32 S3 into your computer with the USB Type-C cable.
  4. Choose board and port: In Arduino IDE, select the ESP32 S3 board and the correct COM port.
  5. Upload the code: Paste the sketch into Arduino IDE and click Upload.
  6. Open the Serial Monitor: Set the baud rate to 115200. The load is still off, so the sketch measures a clean zero point.
  7. Turn the load on: When the Serial Monitor shows "Done", plug in the 12V adapter. The DC device turns on and the current appears.
  8. Test it: If your DC device is a motor, hold its shaft lightly with your fingers. The motor works harder and the current goes up.
  9. Pro Tip: Always switch the load off before you power or reset the ESP32 S3. If the load is running during calibration, every reading after that will be wrong by the current that was flowing.

Serial Monitor Output

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
Calibrating zero point, keep the load OFF... Zero voltage: 2.481 V Done. You can turn the load ON now. Sensor voltage: 2.483 V | Current: 0.03 A Sensor voltage: 2.478 V | Current: -0.05 A Sensor voltage: 2.482 V | Current: 0.02 A Sensor voltage: 2.538 V | Current: 0.86 A Sensor voltage: 2.544 V | Current: 0.95 A Sensor voltage: 2.541 V | Current: 0.91 A Sensor voltage: 2.553 V | Current: 1.09 A Sensor voltage: 2.567 V | Current: 1.30 A Sensor voltage: 2.545 V | Current: 0.97 A
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

The first three lines were taken with the DC device off; small values like 0.03 A or −0.05 A are normal noise. Here the DC device was a 12V DC motor. It ran at about 0.9 A, and the 1.30 A line came from slowing the shaft by hand.

Measuring AC Current with the ESP32 S3

AC current flips direction many times per second (50 or 60 times, depending on your country). The OUT voltage swings above and below the zero point, so one average would come out close to 0 A. Instead, the second sketch uses the RMS value, the number a clamp meter shows. For 200 ms, which covers 10 full cycles at 50 Hz or 12 at 60 Hz, it reads the sensor again and again, squares each difference from the zero voltage, and adds them up. Then it divides by the number of samples, takes the square root, and divides by 0.066:

RMS current (A) = sqrt( mean( (Vout − Vzero)² ) ) / 0.066

The wiring and divider stay the same. The zero calibration still needs the load off at startup.

※ NOTE THAT:

An AC load usually means mains voltage, which is dangerous. Ask an experienced person to help, never touch the screw terminal or wires while the circuit is live, and keep the module in an insulated box. If you are a beginner, test this sketch only with low-voltage loads.

/* * This ESP32 S3 code was developed by newbiely.com * * This ESP32 S3 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3/esp32-s3-acs712-current-sensor */ #define ACS712_PIN 1 // ESP32 S3 GPIO1 (ADC1) connected to the middle of the 10k/20k divider on the ACS712 OUT pin #define DIVIDER_RATIO 1.5 // (10k + 20k) / 20k: undo the divider to get the real ACS712 OUT voltage #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV (0.066 V) per amp #define ZERO_SAMPLES 1000 // readings used to find the zero-current voltage at startup #define WINDOW_MS 200 // sampling time: 10 cycles at 50 Hz, 12 cycles at 60 Hz float zeroVoltage = 2.5; // OUT voltage at 0 A, measured again in setup() // Read the ACS712 OUT voltage (in volts) once float readSensorVoltage() { float pin_V = analogReadMilliVolts(ACS712_PIN) / 1000.0; // voltage on the GPIO pin return pin_V * DIVIDER_RATIO; // voltage on the ACS712 OUT pin } void setup() { Serial.begin(115200); analogSetAttenuation(ADC_11db); // allow the full 0 - 3.1V input range // The load MUST be off now: no current may flow through the sensor Serial.println("Calibrating zero point, keep the load OFF..."); delay(500); float sum = 0; for (int i = 0; i < ZERO_SAMPLES; i++) { sum += readSensorVoltage(); delayMicroseconds(100); } zeroVoltage = sum / ZERO_SAMPLES; Serial.print("Zero voltage: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } void loop() { // Sample for the whole window and add up the squared differences from zero float sumSquares = 0; long count = 0; unsigned long start = millis(); while (millis() - start < WINDOW_MS) { float diff = readSensorVoltage() - zeroVoltage; sumSquares += diff * diff; count++; } float rmsVoltage = sqrt(sumSquares / count); // RMS of the AC part of the signal float rmsCurrent = rmsVoltage / SENSITIVITY; // RMS current in amps Serial.print("AC current (RMS): "); Serial.print(rmsCurrent, 2); Serial.println(" A"); delay(300); }

Detailed Instructions

  1. Keep the same wiring, and make sure the AC load is switched off.
  2. Upload this second sketch and open the Serial Monitor at 115200 baud.
  3. Wait for the zero voltage line, then switch the load on.
  4. Pro Tip: Very small AC loads (below about 0.3 A) mostly show noise on the 30A module. For those, use the 5A version and change SENSITIVITY to 0.185.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
Calibrating zero point, keep the load OFF... Zero voltage: 2.476 V AC current (RMS): 0.07 A AC current (RMS): 0.06 A AC current (RMS): 0.44 A AC current (RMS): 0.45 A AC current (RMS): 0.44 A
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

Here the load was a small 100W bulb on 230V, which pulls about 0.43 A. The 0.06 to 0.07 A with the bulb off is the noise floor of the 30A module, and it adds a little to every RMS result.

Applications and Project Ideas

Once the ESP32 S3 knows how many amps flow, you can watch, log and protect almost any DC load.

  1. Motor stall alarm: Turn off a motor through a relay or MOSFET when its current jumps far above normal.
  2. Battery charge monitor: Track the charging current of a 12V battery and see when it drops near zero.
  3. Solar output logger: Measure the current from a small solar panel every minute and save it to an SD card.
  4. 3D printer power watch: Watch the heated bed current and spot when the heater switches on and off.
  5. Power meter: Combine this sensor with the ESP32 S3 - Measure Voltage tutorial and multiply volts by amps to get watts.
  6. WiFi energy dashboard: Send the current to a web page or MQTT broker so you can check it from your phone.

Video Tutorial

Watch the step-by-step video walkthrough for this ESP32 S3 project below.

Challenge Yourself

When the readings make sense, try these tasks to go further.

  1. Beginner: Make the built-in LED light up when the current is above 1.0 A.
  2. Intermediate: Track the highest current since startup and print it next to the live value, so you can catch the motor's start-up peak.
  3. Advanced: Read the 12V supply with a voltage sensor, multiply by the current, and show watts and watt-hours on an OLED display.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!