Arduino - ACS712 Current Sensor

In this tutorial, we are going to learn:

Arduino ACS712 Current Sensor

A voltage sensor tells us how many volts a circuit has (see Arduino - Measure Voltage). The ACS712 answers a different question: how many amps flow through the wire. With it, Arduino can see if a motor works hard, if a lamp is on, or if a charger still pulls current.

Hardware Required

1×Official Arduino Uno
1×Alternatively, DIYables STEM V3, Fully Compatible with Arduino Uno R3
1×USB 2.0 cable type A/B (for USB-A PC)
1×USB 2.0 cable type C/B (for USB-C PC)
1×ACS712 30A Current Sensor Module
1×12V DC Device (e.g. 12V DC Motor)
1×Optionally, 12V DC Device (e.g. 12V LED Strip)
1×12V Power Adapter
1×DC Power Jack
1×Jumper Wires
1×Recommended: Screw Terminal Block Shield for Arduino Uno
1×Recommended: Sensors/Servo Expansion Shield for Arduino Uno
1×Recommended: Breadboard Shield for Arduino Uno
1×Recommended: Enclosure for Arduino Uno
1×Recommended: Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

1×DIYables STEM V3 Starter Kit (Arduino included)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some links in this section are Amazon affiliate links. If you make a purchase through these links, we may earn a commission at no extra cost to you.
Additionally, some links direct to products from our own brand, DIYables .

Any 12V DC device works as our test load, for example a 12V DC motor or LED strip. You only need one of them.

About ACS712 Current Sensor

The ACS712 is a current sensor chip made by Allegro. It uses the Hall effect. The current goes through a thick copper path inside the chip. This current makes a small magnetic field, and a Hall sensor next to the copper turns that field into a voltage. The copper path has a very low resistance (about 1.2 mΩ), so it almost does not change the circuit we measure. Also, the load side is isolated from the Arduino side (2.1 kV RMS), so the high-current wires never touch the Arduino pins.

ACS712 Current Sensor Pinout

The ACS712 comes in three versions. They look the same, but the sensitivity is different:

Version Range Sensitivity
ACS712 5A -5A to +5A 185 mV per amp
ACS712 20A -20A to +20A 100 mV per amp
ACS712 30A -30A to +30A 66 mV per amp

This tutorial uses the 30A version. Its main specs are:

ACS712 30A
Supply Voltage 5V (4.5V to 5.5V)
Current Range -30A to +30A (DC and AC)
Sensitivity 66 mV per amp
Output at 0A about 2.5V (half of VCC)
Output at +30A / -30A about 4.48V / 0.52V
Bandwidth 80 kHz
Total Output Error about ±1.5% at 25°C
Isolation 2.1 kV RMS

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

  • VCC pin: needs to be connected to 5V. The module does not work well at 3.3V
  • GND pin: needs to be connected to GND (0V)
  • OUT pin: the analog output. It needs to be connected to an analog input pin of Arduino
  • IP+ and IP- (the screw terminal): the current to be measured flows through here. It needs to be connected in series with the load. On some modules, these two screws have no label

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

When the current flows from IP+ to IP-, the output voltage goes above 2.5V and the reading is positive. When it flows the other way, the voltage goes below 2.5V and the reading is negative. The output is ratiometric: it follows the real 5V supply. If the 5V pin of Arduino gives 4.92V, the zero point will be about 2.46V, not 2.50V.

How the Voltage Becomes Current

The rule is simple: every 66 mV away from the zero point means 1 amp. So the formula is:

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

For example, if the zero point is 2.506V and OUT now shows 2.572V, the current is (2.572 - 2.506) / 0.066 = 1.0A.

※ NOTE THAT:

  • The 30A version is not for small currents. Arduino Uno has a 10-bit ADC with 5V reference, so one ADC step is about 4.9 mV, or about 74 mA. It is good for loads of about 0.5A and up: motors, lamps, LED strips, heaters and chargers.
  • Even with nothing connected, you may see a small current like ±0.05A to ±0.1A. This is normal noise. Reading many times and taking the average makes it smaller.
  • Do not trust 2.5V as the exact zero point. Measure it when no current flows. Our code does this when Arduino starts.

Wiring Diagram

The ACS712 is powered by the 5V pin of Arduino and its OUT pin goes straight to A0. Arduino Uno works at 5V, so we do not need a voltage divider. On the load side, cut the positive wire between the 12V adapter and the 12V DC device (such as a DC motor, LED strip or lamp) and put the screw terminal in between.

Arduino ACS712 current sensor wiring diagram

This image is created using Fritzing. Click to enlarge image

Wiring table of ACS712 Module and Arduino Uno

ACS712 Module Arduino Uno
VCC → 5V
GND → GND
OUT → A0

Wiring of the load side

From To
12V adapter (+) via DC power jack → IP+ of ACS712
IP- of ACS712 → DC device (+)
DC device (-) → 12V adapter (-) via DC power jack

※ NOTE THAT:

Safety first: Mains AC (110V/220V) is dangerous and can kill. Please practice with a low-voltage DC load like the 12V DC device in this tutorial. The screw terminal and its wires carry the full voltage of the load, so never touch them while a mains circuit is live.

How To Program For ACS712 Current Sensor

  • Define the analog pin and the sensitivity of the 30A version:
#define SENSOR_PIN A0 #define SENSITIVITY 0.066 // 66 mV per amp
  • Read the pin many times and take the average voltage. This removes a lot of noise:
long sum = 0; for (int i = 0; i < 200; i++) { sum += analogRead(SENSOR_PIN); } float voltage = (sum / 200.0) * 5.0 / 1024.0;
  • Measure the zero point once in setup(), when the load is OFF:
zeroVoltage = readSensorVoltage(1000);
  • Convert the voltage to current:
float current = (voltage - zeroVoltage) / SENSITIVITY;

Arduino Code - Measure DC Current

The below code finds the zero point when Arduino starts. After that, it prints the sensor voltage and the current every 500 ms.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-acs712-current-sensor */ // ACS712 30A current sensor: the OUT pin is connected to Arduino Uno pin A0 #define SENSOR_PIN A0 #define REF_VOLTAGE 5.0 // the analog reference of Arduino Uno is 5V #define ADC_RESOLUTION 1024.0 // Arduino Uno has a 10-bit ADC (0 to 1023) #define SENSITIVITY 0.066 // 30A version: 66 mV (0.066 V) per amp #define NUM_SAMPLES 200 // number of readings to average for one result float zeroVoltage = 2.5; // the sensor output at 0A, measured again in setup() // read the sensor many times and return the average voltage on the OUT pin float readSensorVoltage(int samples) { long sum = 0; for (int i = 0; i < samples; i++) { sum += analogRead(SENSOR_PIN); } float adcAverage = (float)sum / samples; return adcAverage * REF_VOLTAGE / ADC_RESOLUTION; } // the setup function runs once when you press reset or power the board void setup() { Serial.begin(9600); // calibrate the zero point: the load MUST be OFF now (no current flows) Serial.println("Calibrating... keep the load OFF"); zeroVoltage = readSensorVoltage(1000); Serial.print("Zero voltage = "); Serial.print(zeroVoltage, 3); Serial.println(" V"); Serial.println("Done. You can turn the load ON now."); } // the loop function runs over and over again forever void loop() { float voltage = readSensorVoltage(NUM_SAMPLES); // convert the voltage to current: every 0.066V away from the zero point = 1A float current = (voltage - zeroVoltage) / SENSITIVITY; Serial.print("Sensor voltage: "); Serial.print(voltage, 3); Serial.print(" V | Current: "); Serial.print(current, 2); Serial.println(" A"); delay(500); }

Quick Steps

  • Do the wiring as shown in the diagram above
  • Switch the load OFF (unplug the 12V adapter) before you power the board
  • Connect Arduino to PC via USB cable
  • Open Arduino IDE, select the right board and port
  • Copy the above code and open with Arduino IDE
  • Click Upload button on Arduino IDE to upload code to Arduino
  • Open the Serial Monitor and wait for the "Done" message
  • Plug in the 12V adapter to turn the DC device on
  • See the result on Serial Monitor
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
Calibrating... keep the load OFF Zero voltage = 2.506 V Done. You can turn the load ON now. Sensor voltage: 2.510 V | Current: 0.06 A Sensor voltage: 2.503 V | Current: -0.05 A Sensor voltage: 2.507 V | Current: 0.02 A Sensor voltage: 2.598 V | Current: 1.39 A Sensor voltage: 2.567 V | Current: 0.92 A Sensor voltage: 2.561 V | Current: 0.83 A Sensor voltage: 2.564 V | Current: 0.88 A Sensor voltage: 2.589 V | Current: 1.24 A
Ln 11, Col 1
Arduino Uno on COM15
2

The first three lines are the noise when no current flows. Here, a 12V DC motor is used as the DC device. When the motor starts, it pulls a short peak (1.39A), then runs at about 0.85A. If we hold the motor shaft with a finger, the current goes up (1.24A), because the motor has to work harder.

If the current shows a minus sign, the current goes from IP- to IP+. Swap the two wires on the screw terminal, or simply ignore the sign.

Measuring AC Current

AC current changes direction many times per second (50 or 60 times). If we read OUT only once, we may catch any point of the wave, so the result jumps around. Instead, we take many samples for 200 ms, which covers 10 cycles at 50Hz or 12 cycles at 60Hz. Then we calculate the RMS value, which is the number a multimeter shows for AC:

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

※ NOTE THAT:

To measure AC from the mains, the load wire goes through the screw terminal, and that terminal carries 110V/220V. Only do this if you know how to work with mains safely. Never touch the module while the circuit is live.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-acs712-current-sensor */ // ACS712 30A current sensor: the OUT pin is connected to Arduino Uno pin A0 #define SENSOR_PIN A0 #define REF_VOLTAGE 5.0 // the analog reference of Arduino Uno is 5V #define ADC_RESOLUTION 1024.0 // Arduino Uno has a 10-bit ADC (0 to 1023) #define SENSITIVITY 0.066 // 30A version: 66 mV (0.066 V) per amp #define WINDOW_MS 200 // 200 ms = 10 cycles at 50Hz, 12 cycles at 60Hz float zeroVoltage = 2.5; // the sensor output at 0A, measured again in setup() // convert one ADC reading to a voltage float toVoltage(int adcValue) { return adcValue * REF_VOLTAGE / ADC_RESOLUTION; } // the setup function runs once when you press reset or power the board void setup() { Serial.begin(9600); // calibrate the zero point: the load MUST be OFF now (no current flows) Serial.println("Calibrating... keep the load OFF"); long sum = 0; for (int i = 0; i < 1000; i++) { sum += analogRead(SENSOR_PIN); } zeroVoltage = toVoltage(sum / 1000.0); Serial.print("Zero voltage = "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } // the loop function runs over and over again forever void loop() { // sample the signal during the whole time window and sum the squares float sumOfSquares = 0; long count = 0; unsigned long startTime = millis(); while (millis() - startTime < WINDOW_MS) { float diff = toVoltage(analogRead(SENSOR_PIN)) - zeroVoltage; sumOfSquares += diff * diff; count++; } // RMS voltage around the zero point, then convert it to 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(300); }

Quick Steps

  • Keep the same 3-pin wiring between ACS712 and Arduino
  • Make sure the AC load is OFF when Arduino starts
  • Copy the above code and open with Arduino IDE
  • Click Upload button on Arduino IDE to upload code to Arduino
  • Turn on the AC load and see the result on Serial Monitor
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
Calibrating... keep the load OFF Zero voltage = 2.504 V AC current (RMS): 0.09 A (1293 samples) AC current (RMS): 0.08 A (1294 samples) AC current (RMS): 2.21 A (1293 samples) AC current (RMS): 2.18 A (1292 samples) AC current (RMS): 2.19 A (1293 samples)
Ln 11, Col 1
Arduino Uno on COM15
2

Here, a 500W heater on 230V is turned on and the sensor shows about 2.2A. With no load, the RMS value is not exactly 0 because the noise also counts. For small AC loads, the 5A version of the ACS712 gives much better results.

Video Tutorial

We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

Function References

The Best Arduino Starter Kit

※ OUR MESSAGES