ESP8266 - ACS712 Current Sensor

This tutorial instructs you how to use ESP8266 to find out how many amps a device draws, with the ACS712 30A Hall effect current sensor. The NodeMCU has only one analog pin, A0, and it can not take the 5V signal of the sensor directly, so we will also add two resistors. In detail, we will learn:

We suggest:

ESP8266 NodeMCU ACS712 current sensor

Hardware Preparation

1×ESP8266 NodeMCU ESP-12F
1×Alternatively, ESP8266 D1 Mini NodeMCU ESP-12F
1×Alternatively, ESP8266 NodeMCU ESP-12E (Uno-form)
1×Micro USB Cable
1×Alternatively, ESP8266 NodeMCU ESP-12F (SMD-form)
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×Resistor Kit (10kΩ and 20kΩ)
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 ESP8266

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 tells the ESP8266 how much current flows through a wire. Inside the chip, the current passes through a thick copper path. This current makes a small magnetic field, and a Hall sensor placed next to the copper turns that field into a voltage. The load side and the ESP8266 side never touch electrically (the chip is isolated up to 2.1 kV RMS), and the copper path is only about 1.2 mΩ, so putting the sensor in a wire hardly changes your circuit. It works for both DC and AC current.

The module comes in three versions. They look the same, so read the text on the chip. This tutorial uses the 30A version.

5A version 20A version 30A version
Chip marking ACS712ELCTR-05B ACS712ELCTR-20A ACS712ELCTR-30A
Current range -5A to +5A -20A to +20A -30A to +30A
Sensitivity 185 mV/A 100 mV/A 66 mV/A
ACS712 30A
Supply voltage 5V (4.5V to 5.5V), not 3.3V
Output at 0A about half of the supply (about 2.5V at 5V)
Output at +30A / -30A about 4.48V / about 0.52V
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 output is "ratiometric". It means the output moves together with the real supply voltage of the module. If VCC is a little lower than 5V, the zero point is also a little lower than 2.5V. This is why our code measures the zero point itself, instead of assuming 2.5V.

ACS712 current sensor pinout

The ACS712 module has a 3-pin header and a 2-pin screw terminal:

  • VCC pin: must be connected to 5V. On the NodeMCU, this is the VIN pin (some boards print VU).
  • GND pin: must be connected to GND (0V) of the ESP8266.
  • OUT pin: the analog output. It must go to A0 through a voltage divider, never directly.
  • IP+ and IP- screw terminals: must be placed in series with the load. Cut one supply wire of the load and put the terminal in the gap. Current that flows from IP+ to IP- gives a positive value. On some modules, these two screws have no label.

The module also has a red power LED that turns on when VCC is connected.

※ NOTE THAT:

The pin order of the 3-pin header is not the same on every module. Always read the labels printed on your own board before wiring.

How the ACS712 Output Turns into Amps

With no current, OUT sits at the zero voltage (near 2.5V). Current in one direction pushes OUT up, and current in the other direction pulls it down, by 66 mV for each amp. So the formula is:

current_A = (Vout - Vzero) / 0.066

For example, if Vzero is 2.40V and Vout is 2.47V, the current is 0.07 / 0.066 ≈ 1.06A.

Why the ESP8266 Needs a Voltage Divider and Averaging

The A0 pin of the NodeMCU board accepts 0V to 3.3V and gives a 10-bit value from 0 to 1023. The ACS712 OUT pin can rise to about 4.5V, which is too high. Two resistors fix this: OUT → 10kΩ → A0 → 20kΩ → GND. The A0 pin then sees only 2/3 of the OUT voltage (4.5V becomes 3.0V), and the code multiplies the value back by 1.5.

One A0 step is about 3.2 mV. After the divider, it is about 4.8 mV on OUT, which equals about 73 mA. So the 30A sensor is a coarse tool. It is good for loads of about 0.5A and up, such as motors, lamps, LED strips, heaters and chargers, but not for a single small LED. On top of that, the ESP8266 ADC is quite noisy, and the WiFi radio adds more noise. A jump of ±50 to ±100 mA at 0A is normal. That is why the code reads A0 hundreds of times and uses the average. On the ESP8266, averaging is not optional, it is the main trick that makes the readings usable.

※ NOTE THAT:

Mains AC (110V/220V) is dangerous. Beginners should practice with a low-voltage DC load like the 12V DC device in this tutorial. The screw terminal and the copper side of the module carry the full load voltage. Never touch them while a mains circuit is live.

Wiring Diagram

The ACS712 gets 5V from the VIN pin of the NodeMCU, and its OUT pin reaches A0 through the 10kΩ/20kΩ divider. The 12V DC device (such as a DC motor, LED strip or lamp), the 12V adapter and the screw terminal of the ACS712 form a separate loop.

The wiring diagram between ESP8266 NodeMCU and ACS712 current sensor

This image is created using Fritzing. Click to enlarge image

See more in ESP8266's pinout and how to supply power to the ESP8266 and other components.

ACS712 Module ESP8266 NodeMCU
VCC VIN (5V)
GND GND
OUT 10kΩ resistor to A0, then 20kΩ resistor from A0 to GND
Load circuit Connection
12V adapter (+) DC power jack (+), then IP+ of the ACS712
IP- of the ACS712 DC device (+) wire
DC device (-) wire DC power jack (-), back to the adapter (-)

※ NOTE THAT:

VIN gets its 5V from the USB cable. Do not connect the 12V adapter to VIN. The 12V supply only feeds the DC device through the screw terminal.

How To Program For ACS712 Current Sensor

  • The first step is to define the A0 pin and the numbers needed for the conversion:
#define SENSOR_PIN A0 #define REF_VOLTAGE 3.3 // NodeMCU A0 range: 0 to 3.3V #define ADC_RESOLUTION 1024.0 // 10-bit ADC #define DIVIDER_FACTOR 1.5 // 10k + 20k divider #define SENSITIVITY 0.066 // 66 mV per amp (30A version)
  • Read A0 many times, average the result, and change it to the voltage on the OUT pin:
long sum = 0; for (int i = 0; i < samples; i++) { sum += analogRead(SENSOR_PIN); delayMicroseconds(200); } float pinVoltage = (float)sum / samples * REF_VOLTAGE / ADC_RESOLUTION; float sensorVoltage = pinVoltage * DIVIDER_FACTOR;
  • In setup(), while the load is still OFF, save the average voltage as the zero point (1000 readings).
  • In loop(), apply the formula:
float current = (sensorVoltage - zeroVoltage) / SENSITIVITY;

ESP8266 Code for ACS712 - Measure DC Current

The code below finds the zero point at startup, then prints the OUT voltage and the current every 500 ms. Each printed value is the average of 300 readings.

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-acs712-current-sensor */ /* * ESP8266 NodeMCU - measure DC current with the ACS712 30A current sensor * * Wiring: * ACS712 VCC -> VIN (5V from USB; some boards label it VU) * ACS712 GND -> GND * ACS712 OUT -> 10k resistor -> A0 -> 20k resistor -> GND (voltage divider) * Screw terminal IP+ / IP- -> in series with the load (e.g. a 12V DC motor) * * IMPORTANT: switch the load OFF while the ESP8266 starts, so the zero point * is measured with no current flowing. */ #define SENSOR_PIN A0 // The only analog pin of the ESP8266 NodeMCU #define REF_VOLTAGE 3.3 // NodeMCU A0 range: 0 to 3.3V #define ADC_RESOLUTION 1024.0 // 10-bit ADC: 0 to 1023 #define DIVIDER_FACTOR 1.5 // 10k + 20k divider: OUT voltage = A0 voltage x 1.5 #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV per amp #define ZERO_SAMPLES 1000 // readings used to find the zero point #define AVG_SAMPLES 300 // readings averaged for each printed value float zeroVoltage = 0; // sensor output voltage when no current flows // Read A0 many times and return the average voltage at the ACS712 OUT pin float readSensorVoltage(int samples) { long sum = 0; for (int i = 0; i < samples; i++) { sum += analogRead(SENSOR_PIN); delayMicroseconds(200); } float adcAverage = (float)sum / samples; float pinVoltage = adcAverage * REF_VOLTAGE / ADC_RESOLUTION; // voltage on A0 return pinVoltage * DIVIDER_FACTOR; // voltage on OUT } void setup() { Serial.begin(9600); delay(500); Serial.println("Calibrating zero point, keep the load OFF..."); zeroVoltage = readSensorVoltage(ZERO_SAMPLES); Serial.print("Zero voltage: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } void loop() { float sensorVoltage = readSensorVoltage(AVG_SAMPLES); // current (A) = (output voltage - zero voltage) / sensitivity float current = (sensorVoltage - zeroVoltage) / SENSITIVITY; Serial.print("Sensor output: "); Serial.print(sensorVoltage, 3); Serial.print(" V | Current: "); Serial.print(current, 2); Serial.println(" A"); delay(500); }

Detailed Instructions

To get started with ESP8266 on Arduino IDE, follow these steps:

  • Check out the how to setup environment for ESP8266 on Arduino IDE tutorial if this is your first time using ESP8266.
  • Wire the components as shown in the diagram. Leave the 12V adapter unplugged for now.
  • Connect the ESP8266 board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
  • Copy the code above and open it with the Arduino IDE. No library is needed.
  • Click the Upload button in the Arduino IDE to compile and upload the code to the ESP8266.
  • Open the Serial Monitor. Wait until the zero voltage is printed. The load must be OFF during this time.
  • Now plug in the 12V adapter so the DC device turns on, and watch the current.
  • If the DC device is a motor, hold its shaft lightly with your fingers. The motor works harder and the current goes up.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
Calibrating zero point, keep the load OFF... Zero voltage: 2.364 V Sensor output: 2.367 V | Current: 0.05 A Sensor output: 2.361 V | Current: -0.05 A Sensor output: 2.366 V | Current: 0.03 A Sensor output: 2.421 V | Current: 0.86 A Sensor output: 2.418 V | Current: 0.82 A Sensor output: 2.424 V | Current: 0.91 A Sensor output: 2.446 V | Current: 1.24 A Sensor output: 2.451 V | Current: 1.32 A Sensor output: 2.420 V | Current: 0.85 A
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2

This run uses a 12V DC motor as the DC device. The first lines show the load OFF. The small values around 0.05A are noise, not real current. The middle lines are the motor running freely. The higher lines appear when the shaft is held.

※ NOTE THAT:

If the current is negative while the DC device runs, the current flows from IP- to IP+. Swap the two wires on the screw terminal, or just ignore the minus sign.

Measuring AC Current

AC current changes direction many times every second (50 or 60 times, depending on your country). So the OUT pin swings above and below the zero point, and a simple average would give almost 0A. Instead, we measure the RMS value, which is the number a multimeter shows for AC.

The code samples A0 as fast as it can during a 200 ms window. This covers 10 full cycles at 50 Hz, or 12 cycles at 60 Hz. For each sample, it takes the difference from the zero voltage and squares it. Then:

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

※ NOTE THAT:

Again: mains AC can kill. If you are not trained to work with mains wiring, do not connect the ACS712 to a mains circuit. Never touch the screw terminal while the circuit is live.

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-acs712-current-sensor */ /* * ESP8266 NodeMCU - measure AC current (RMS) with the ACS712 30A current sensor * * Wiring: same as the DC example * ACS712 VCC -> VIN (5V), GND -> GND * ACS712 OUT -> 10k resistor -> A0 -> 20k resistor -> GND * * WARNING: mains voltage (110V/220V) can kill. Only an experienced person * should wire the screw terminal into a mains circuit. Never touch it while live. * Keep the load OFF while the ESP8266 starts (zero calibration). */ #define SENSOR_PIN A0 #define REF_VOLTAGE 3.3 // NodeMCU A0 range: 0 to 3.3V #define ADC_RESOLUTION 1024.0 // 10-bit ADC #define DIVIDER_FACTOR 1.5 // 10k + 20k divider #define SENSITIVITY 0.066 // 66 mV per amp (30A version) #define WINDOW_MS 200 // 200 ms = 10 cycles at 50 Hz, 12 cycles at 60 Hz float zeroVoltage = 0; // Convert one ADC reading to the voltage at the ACS712 OUT pin float toSensorVoltage(float adcValue) { return adcValue * REF_VOLTAGE / ADC_RESOLUTION * DIVIDER_FACTOR; } void setup() { Serial.begin(9600); delay(500); // Find the zero point (no current flowing) long sum = 0; for (int i = 0; i < 1000; i++) { sum += analogRead(SENSOR_PIN); delayMicroseconds(200); } zeroVoltage = toSensorVoltage((float)sum / 1000); Serial.print("Zero voltage: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } void loop() { float sumOfSquares = 0; long count = 0; unsigned long startTime = millis(); // Sample the wave during the whole time window while (millis() - startTime < WINDOW_MS) { float diff = toSensorVoltage(analogRead(SENSOR_PIN)) - zeroVoltage; sumOfSquares += diff * diff; count++; } // RMS voltage -> RMS current float rmsVoltage = sqrt(sumOfSquares / count); float rmsCurrent = rmsVoltage / SENSITIVITY; Serial.print("AC current (RMS): "); Serial.print(rmsCurrent, 2); Serial.print(" A ("); Serial.print(count); Serial.println(" samples)"); delay(500); }

Upload it in the same way, with the load OFF at startup. Then switch on an AC device, for example a small heater:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
Zero voltage: 2.358 V AC current (RMS): 0.08 A (1871 samples) AC current (RMS): 0.09 A (1866 samples) AC current (RMS): 3.62 A (1869 samples) AC current (RMS): 3.58 A (1870 samples) AC current (RMS): 3.65 A (1868 samples)
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2

With no load, the RMS value is not exactly 0A. This is the ADC noise again. Values below about 0.1A should be treated as 0A.

Video Tutorial

Additional Knowledge

A few things affect the accuracy of the ESP8266 + ACS712 setup:

  • VIN is not exactly 5V. When the NodeMCU runs from USB, VIN often reads a little lower (for example around 4.7V), because of a protection diode on the board. The zero calibration fixes the offset. The sensitivity also drops a little, to about 0.066 × (VIN / 5). If you measure VIN with a multimeter, you can put that value into SENSITIVITY.
  • The NodeMCU board has its own resistor divider on A0 (it is how A0 accepts 3.3V). It loads our 20kΩ resistor a little, so the readings can be about 2% low. If you compare with a multimeter, you can raise DIVIDER_FACTOR slightly, for example to 1.53.
  • For small currents (below 5A), a 5A version of the ACS712 gives about 3 times more signal per amp.

Let's compare the ACS712 with the voltage sensor used in the ESP8266 - Measure Voltage tutorial.

ACS712 30A Voltage Sensor
What it measures current (A) voltage (V)
How it is connected in series with the load in parallel with the source
AC or DC both DC only
Isolated from the ESP8266 yes (Hall effect) no (resistor divider)
Power needed 5V none

It is evident that the two modules work as a pair: the voltage sensor tells you the voltage, the ACS712 tells you the current, and by multiplying them you can calculate the power of a DC load in watts.

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