Arduino Nano ESP32 - ACS712 Current Sensor

How much current does your motor really pull? Is your 12V LED strip drawing what its label says? In this guide, we will learn how to use the ACS712 current sensor with the Arduino Nano ESP32 to find out. The sensor runs on 5V, but the Nano ESP32 analog pins accept only 3.3V, so we will also add a small two-resistor divider. In detail, we will learn:

Arduino Nano ESP32 and ACS712 current sensor

Hardware Preparation

1×Arduino Nano ESP32
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×ACS712 30A Current Sensor Module
1×10kΩ and 20kΩ Resistors (from a resistor kit)
1×12V DC Device (e.g. 12V DC Motor)
1×Alternatively, 12V DC Device (e.g. 12V LED Strip)
1×12V Power Adapter
1×DC Power Jack
1×Breadboard
1×Jumper Wires
1×Recommended: Screw Terminal Expansion Board for Arduino Nano
1×Recommended: Breakout Expansion Board for Arduino Nano
1×Recommended: Power Splitter for Arduino Nano ESP32

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of ACS712 Current Sensor

The ACS712 is a small chip from Allegro that measures current, both DC and AC. Inside it, the current runs through a thick copper path. This current makes a magnetic field, and a Hall sensor right next to the path turns that field into a voltage. The copper path is not wired to the Nano ESP32 side at all (it is isolated up to 2.1 kV RMS), and its resistance is only about 1.2 mΩ, so it barely changes the circuit you measure.

ACS712 current sensor pinout
image source: diyables.io

The module has a 3-pin header on one side and a 2-pin screw terminal on the other side:

  • VCC pin: connect to 5V. On the Arduino Nano ESP32, use the VBUS pin (5V from USB). The 3.3V pin is not enough for this chip.
  • GND pin: connect to GND (0V).
  • OUT pin: analog output voltage. Connect it to the Arduino Nano ESP32 analog pin A0 through the voltage divider (see the wiring part).
  • Screw terminal (IP+ and IP−, sometimes not labeled): this goes in series with the load. Cut one power wire of the load and put the terminal in the gap, so all of the load current flows through the sensor. Current that goes in at IP+ and out at IP− gives a positive reading.

A small LED on the board lights up when the module has power.

At 0 A, OUT sits at half of the supply, about 2.5V. When current flows one way, OUT goes up. When it flows the other way, OUT goes down. The output follows the real 5V supply (it is ratiometric), so if VBUS is 4.9V, the zero point is about 2.45V.

The chip comes in three current ranges. This guide uses the 30A version.

ACS712 5A ACS712 20A ACS712 30A
Current range ±5A ±20A ±30A
Sensitivity 185 mV/A 100 mV/A 66 mV/A
ACS712 30A Module
Supply voltage 5V (4.5V to 5.5V)
Output at 0 A about 2.5V (half of VCC)
Output at +30 A about 4.48V
Output at −30 A about 0.52V
Sensitivity 66 mV per amp
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 30A range is big, so the sensor is not good at small currents. The Nano ESP32 reads its analog pin with 12 bits, and after the divider one step is about 18 mA. With normal noise, you will see readings jump by about ±50 to 100 mA even with no load. So use it for loads of about 0.5 A and up: motors, lamps, LED strips, heaters and chargers. The code averages many readings to make the numbers calmer.

How the Sensor Output Becomes Amps

Each amp moves the output by 66 mV, starting from the zero voltage. So the formula is:

current_A = (Vout - Vzero) / 0.066

Example: if Vzero is 2.49V and Vout reads 2.56V, the current is (2.56 − 2.49) / 0.066 ≈ 1.06 A.

Do not trust the 2.5V number blindly. Every module and every USB port is a bit different. The code measures Vzero at startup, while no current flows, and uses that value.

Wiring Diagram

The ACS712 needs 5V, so its VCC goes to VBUS. But then OUT can rise to about 4.5V, which is too high for a 3.3V analog pin. Two resistors fix this: OUT → 10kΩ → A0 → 20kΩ → GND. Pin A0 now sees 2/3 of the sensor voltage (4.5V becomes 3.0V), and the code multiplies the reading by 1.5 to get the real value back.

The wiring diagram between Arduino Nano ESP32 and ACS712 current sensor

This image is created using Fritzing. Click to enlarge image

Wiring table of ACS712 Module and Arduino Nano ESP32

ACS712 Module Arduino Nano ESP32
VCC → VBUS (5V)
GND → GND
OUT → 10kΩ resistor → A0 (and A0 → 20kΩ resistor → GND)

On the load side, the 12V adapter plugs into the DC power jack. Run the jack's + wire to one screw of the ACS712, the other screw to the + of the 12V DC device (for example a DC motor, LED strip or lamp), and the DC device − back to the jack's − wire. The 12V circuit and the Nano ESP32 share no wires.

We use A0 because it belongs to ADC1 of the ESP32-S3 chip. The A4 to A7 pins belong to ADC2, which stops working while WiFi is on. With A0, you can add WiFi to this project later.

※ NOTE THAT:

Mains AC (110V/220V) is dangerous. Learn with a low-voltage DC load first, like the 12V DC device in this guide. If you ever measure a mains circuit, never touch the screw terminal or its wires while the power is on. That side of the module carries the full load voltage.

How To Program For ACS712 Current Sensor

No library is needed.

  • Set the analog pin and the numbers for the divider and the sensor:
#define SENSOR_PIN A0 #define DIVIDER_RATIO 1.5 #define SENSITIVITY 0.066
  • Let the analog pin read up to about 3.1V:
analogSetAttenuation(ADC_11db);
  • Read the pin voltage in millivolts and turn it back into the real sensor voltage. analogReadMilliVolts() uses the chip's own calibration, so it is more accurate than analogRead():
float voltage = analogReadMilliVolts(SENSOR_PIN) / 1000.0 * DIVIDER_RATIO;
  • Find the zero point in setup(), while the load is OFF, by averaging 1000 readings.
  • Turn the voltage into amps:
float current = (voltage - zeroVoltage) / SENSITIVITY;

Arduino Nano ESP32 Code - ACS712 DC Current

The code below finds the zero voltage at startup. Then, every 0.5 seconds, it averages 300 readings and prints the sensor voltage and the current.

/* * This Arduino Nano ESP32 code was developed by newbiely.com * * This Arduino Nano ESP32 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-acs712-current-sensor */ #define SENSOR_PIN A0 // The Arduino Nano ESP32 pin connected to the divider middle point #define DIVIDER_RATIO 1.5 // 10k + 20k divider: sensor voltage = pin voltage x 1.5 #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV per amp (0.066 V/A) #define SAMPLES 300 // number of readings averaged for each result float zeroVoltage = 2.5; // sensor output at 0 A, measured again in setup() // read the sensor output voltage (in volts), averaged over many samples float readSensorVoltage(int count) { long sum_mv = 0; for (int i = 0; i < count; i++) { sum_mv += analogReadMilliVolts(SENSOR_PIN); // voltage on the pin, in millivolts } float pin_voltage = (sum_mv / (float)count) / 1000.0; return pin_voltage * DIVIDER_RATIO; // undo the divider to get the real sensor voltage } void setup() { Serial.begin(9600); analogSetAttenuation(ADC_11db); // allow the analog pin to read up to about 3.1V // the load must be OFF now, so the sensor output is the real zero point Serial.println("Calibrating... keep the load OFF"); zeroVoltage = readSensorVoltage(1000); Serial.print("Zero voltage: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } void loop() { float voltage = readSensorVoltage(SAMPLES); float current = (voltage - zeroVoltage) / SENSITIVITY; // amps Serial.print("Sensor output: "); Serial.print(voltage, 3); Serial.print(" V | Current: "); Serial.print(current, 2); Serial.println(" A"); delay(500); }

Detailed Instructions

Follow these instructions step by step:

  • If this is the first time you use Arduino Nano ESP32, see how to setup environment for Arduino Nano ESP32 on Arduino IDE.
  • Wire the components according to the provided diagram. Leave the 12V adapter unplugged for now.
  • Connect the Arduino Nano ESP32 to your computer using a USB Type-C cable.
  • Launch the Arduino IDE on your computer.
  • Select the appropriate Arduino Nano ESP32 board (e.g., Arduino Nano ESP32) and COM port.
  • Copy the code above and paste it into the Arduino IDE.
  • Open the Serial Monitor and set the baud rate to 9600.
  • Click the Upload button to send the code to the Arduino Nano ESP32. The load must be OFF while the board starts, because this is when the zero point is measured.
  • Wait until the Serial Monitor shows the zero voltage. Then plug in the 12V adapter to turn the DC device on.
  • Watch the current go up. If your DC device is a motor, hold its shaft lightly with your fingers and the current rises more.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Nano ESP32
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Nano ESP32' on 'COM15')
New Line
9600 baud
Calibrating... keep the load OFF Zero voltage: 2.487 V Sensor output: 2.490 V | Current: 0.05 A Sensor output: 2.485 V | Current: -0.03 A Sensor output: 2.489 V | Current: 0.03 A Sensor output: 2.546 V | Current: 0.89 A Sensor output: 2.541 V | Current: 0.82 A Sensor output: 2.544 V | Current: 0.86 A Sensor output: 2.567 V | Current: 1.21 A Sensor output: 2.571 V | Current: 1.27 A Sensor output: 2.543 V | Current: 0.85 A
Ln 11, Col 1
Arduino Nano ESP32 on COM15
2

The first lines show a few tens of mA with no load. That is normal noise for the 30A version. If the numbers come out negative when the DC device is on, swap the two wires on the screw terminal.

※ NOTE THAT:

If the reading is far off, check that VCC is on VBUS and not on 3.3V, and that the 10kΩ resistor sits between OUT and A0 while the 20kΩ resistor sits between A0 and GND. If the two resistors are swapped, the pin only sees 1/3 of the voltage.

Measuring AC Current

With AC, the current changes direction many times per second (50 or 60 times, depending on your country). The sensor output swings above and below the zero voltage, so a plain average gives almost 0 A. We use the RMS value instead. The code samples the signal for 200 ms, which covers 10 cycles at 50 Hz and 12 cycles at 60 Hz. For each sample it takes the distance from the zero voltage and squares it. Then:

current_RMS = sqrt(average of (Vout - Vzero)²) / 0.066

Safety again: a mains circuit can kill. Do not try this on 110V/220V unless you know how to work with mains safely, and keep your hands away from the screw terminal while the power is on. The wiring to the Nano ESP32 and the zero calibration are the same as above.

Arduino Nano ESP32 Code - ACS712 AC Current

/* * This Arduino Nano ESP32 code was developed by newbiely.com * * This Arduino Nano ESP32 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-acs712-current-sensor */ #define SENSOR_PIN A0 // The Arduino Nano ESP32 pin connected to the divider middle point #define DIVIDER_RATIO 1.5 // 10k + 20k divider: sensor voltage = pin voltage x 1.5 #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV per amp (0.066 V/A) #define WINDOW_MS 200 // 200 ms = 10 cycles at 50 Hz, 12 cycles at 60 Hz float zeroVoltage = 2.5; // sensor output at 0 A, measured again in setup() // read the real sensor output voltage (in volts) once float readSensorVoltage() { return analogReadMilliVolts(SENSOR_PIN) / 1000.0 * DIVIDER_RATIO; } void setup() { Serial.begin(9600); analogSetAttenuation(ADC_11db); // allow the analog pin to read up to about 3.1V // the load must be OFF now, so the sensor output is the real zero point Serial.println("Calibrating... keep the load OFF"); float sum = 0; for (int i = 0; i < 1000; i++) { sum += readSensorVoltage(); } zeroVoltage = sum / 1000; Serial.print("Zero voltage: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } void loop() { float sumSquares = 0; long count = 0; unsigned long startTime = millis(); // sample for a fixed time window that covers several AC cycles while (millis() - startTime < WINDOW_MS) { float diff = readSensorVoltage() - zeroVoltage; // distance from the zero point sumSquares += diff * diff; count++; } float rmsVoltage = sqrt(sumSquares / count); // RMS of the AC part of the signal float rmsCurrent = rmsVoltage / SENSITIVITY; // amps (RMS) Serial.print("AC current (RMS): "); Serial.print(rmsCurrent, 2); Serial.println(" A"); delay(500); }

Upload it the same way, with the load off at startup. Example output with a small AC appliance switched on after the calibration:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Nano ESP32
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Nano ESP32' on 'COM15')
New Line
9600 baud
Calibrating... keep the load OFF Zero voltage: 2.492 V AC current (RMS): 0.07 A AC current (RMS): 0.06 A AC current (RMS): 0.58 A AC current (RMS): 0.61 A AC current (RMS): 0.59 A
Ln 11, Col 1
Arduino Nano ESP32 on COM15
2

Noise also adds a small RMS value when nothing is on, so a reading below about 0.1 A means "about zero".

Video Tutorial

※ 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!