Documentation

ACS712 5A Current Sensor Module for Arduino & ESP32 | ShillehTek Product Manual
Documentation / ACS712 5A Current Sensor Module for Arduino & ESP32 | ShillehTek Product Manual

ACS712 5A Current Sensor Module for Arduino & ESP32 | ShillehTek Product Manual

manualshillehtek

Overview

The ACS712 5A module measures electrical current the clever way: instead of breaking into your circuit with a shunt resistor and measuring voltage drop, it routes the current through a tiny internal conductor and reads the magnetic field that current creates with a Hall-effect sensor. The result is a galvanically isolated measurement — 2.1 kV RMS of isolation between the current path and your microcontroller — with just 1.2 mΩ of resistance added to the circuit being measured.

Using it takes three wires and two screws: power the board with 5V, wire your load in series through the green screw terminal (IP+ and IP-), and read the OUT pin with an ADC. The output is a simple analog voltage centered at VCC/2: with nothing flowing, OUT sits at about 2.5V, and every amp moves it 185 mV — up for current in one direction, down for the other. That bidirectional behavior means the ACS712 reads DC current with polarity and AC current too (with a little RMS math in your code).

This is the ±5A version, the most sensitive of the ACS712 family, ideal for monitoring motors, solar and battery charging, LED strips, bench power experiments, and overcurrent protection in robotics. The Arduino reads it directly; the ESP32 and Pico need a two-resistor divider on OUT (it can swing past 3.3V), and the Raspberry Pi reads it through an external ADC like the ADS1115.

At a Glance

Current Range
±5A (AC or DC)
Sensitivity
185 mV per amp
Zero-Current Output
VCC/2 (≈2.5V)
Supply Voltage
4.5 - 5.5V DC
Isolation
2.1 kV RMS
Pins
VCC, OUT, GND + IP± terminal

Specifications

Parameter Value
Sensor IC Allegro ACS712ELCTR-05B (Hall-effect, linear)
Measurement Range -5A to +5A, AC or DC
Sensitivity 185 mV/A
Output at Zero Current VCC/2 (≈ 2.5V at 5V supply)
Output Swing (±5A) ≈ 1.575V to 3.425V
Supply Voltage 4.5 - 5.5V DC
Supply Current ~10 mA
Total Output Error ±1.5% typical at 25°C
Bandwidth 80 kHz
Internal Conductor Resistance 1.2 mΩ
Isolation 2.1 kV RMS (current path to sensor pins)
Connections 3-pin header (VCC, OUT, GND) + 2-position screw terminal (IP+, IP-)

Pinout Diagram

The three header pins are the sensor side: VCC takes 5V, GND goes to ground, and OUT is the analog output you read with an ADC. The green screw terminal is the measurement side — break your circuit and route the load current in through IP+ and out through IP-, exactly like inserting an ammeter in series. The two sides are electrically isolated from each other, which is the whole magic of Hall-effect sensing.

ACS712 5A current sensor module pinout diagram showing GND, OUT analog output, and VCC 5V pins with load screw terminal

Wiring Guide

Arduino Wiring

The Arduino is the natural partner for the ACS712: both run at 5V, so OUT connects straight to an analog input with no extra parts.

ACS712 Pin Arduino Pin Details
VCC 5V
GND GND
OUT A0 0-5V analog, direct
IP+ / IP- Load circuit in series Screw terminal
Warning: This module is best kept to low-voltage DC and isolated AC experiments. Do not wire mains (120V/230V) through a breadboarded module unless you genuinely know what you are doing — the chip is isolated, but exposed screw terminals and jumper wires at mains voltage are dangerous.
Tip: Calibrate at startup: with no load current flowing, average a few hundred readings of OUT and store that as your zero point. Subtracting a measured zero instead of assuming exactly 2.5V removes most of the offset error.

ESP32 Wiring

The module still needs 5V power (VIN), but OUT can reach ~3.4V at full current plus headroom — too close to the ESP32's 3.3V limit for comfort. Scale it with a 10k/20k divider.

ACS712 Pin ESP32 Pin Details
VCC VIN (5V) Sensor needs 5V supply
GND GND
OUT GPIO 34 Via 10k/20k divider; ADC1 input-only pin
IP+ / IP- Load circuit in series Screw terminal
Warning: Wire the divider as 10k from OUT to GPIO 34, then 20k from GPIO 34 to GND. That scales 0-5V down to 0-3.33V; the code multiplies by 1.5 to recover the true voltage. Skipping the divider risks the pin at high current readings.
Tip: The ESP32 ADC is noisy — average 50-100 samples per reading and calibrate the zero point at boot. For small currents, every millivolt of noise is 5 mA of apparent current, so averaging pays off quickly.

Raspberry Pi Wiring

The Pi has no analog inputs, so an ADS1115 I2C ADC does the reading. Divide OUT down to the 3.3V range first, then feed it to the ADS1115 running on the Pi's 3.3V rail.

Wire / Pin Connects To Details
ACS712 VCC Pin 2 (5V)
ACS712 GND Pin 6 (GND)
ACS712 OUT ADS1115 A0 Via 10k/20k divider
ADS1115 VDD Pin 1 (3.3V)
ADS1115 GND Pin 6 (GND)
ADS1115 SDA Pin 3 (GPIO 2) I2C data
ADS1115 SCL Pin 5 (GPIO 3) I2C clock
IP+ / IP- Load circuit in series Screw terminal
Tip: Enable I2C with sudo raspi-config, then confirm the ADS1115 shows at address 0x48 with i2cdetect -y 1 before running the code.

Raspberry Pi Pico Wiring

The Pico's built-in ADC reads the divided signal on ADC0. Power the sensor from VBUS while on USB.

ACS712 Pin Pico Pin Details
VCC VBUS (pin 40) 5V from USB
GND GND (pin 38)
OUT GP26 (pin 31) Via 10k/20k divider; ADC0
IP+ / IP- Load circuit in series Screw terminal
Warning: Pico GPIO and ADC pins are 3.3V only — always use the 10k/20k divider on OUT (10k in series, 20k to ground), and multiply readings by 1.5 in code.

Code Examples

All examples measure DC current: read the output voltage, subtract the calibrated zero point, and divide by 0.185 V/A. Each program calibrates its own zero at startup — make sure no load current is flowing for the first two seconds after reset.

Arduino

acs712_arduino.ino
// ACS712 5A Current Sensor - Arduino Example (DC current)
// OUT -> A0, VCC -> 5V, GND -> GND, load in series through IP+/IP-

const int sensorPin = A0;
const float SENSITIVITY = 0.185;   // volts per amp (5A version)
float zeroVolts = 2.5;             // measured at startup

float readVolts(int samples) {
  long total = 0;
  for (int i = 0; i < samples; i++) {
    total += analogRead(sensorPin);
    delay(1);
  }
  return (total / (float)samples) * (5.0 / 1023.0);
}

void setup() {
  Serial.begin(9600);

  // Calibrate the zero point - no load current for these 2 seconds!
  Serial.println("Calibrating zero point, keep load OFF...");
  zeroVolts = readVolts(500);
  Serial.print("Zero = ");
  Serial.print(zeroVolts, 3);
  Serial.println(" V. Measuring...");
}

void loop() {
  float volts = readVolts(100);
  float amps = (volts - zeroVolts) / SENSITIVITY;

  Serial.print("OUT: ");
  Serial.print(volts, 3);
  Serial.print(" V | Current: ");
  Serial.print(amps, 3);
  Serial.println(" A");

  delay(500);
}

ESP32 (MicroPython)

acs712_esp32.py
# ACS712 5A Current Sensor - ESP32 MicroPython Example (DC current)
# OUT -> 10k/20k divider -> GPIO 34, VCC -> VIN (5V)
# Divider scales 5V -> 3.33V, so multiply measured volts by 1.5

from machine import ADC, Pin
import time

adc = ADC(Pin(34))
adc.atten(ADC.ATTN_11DB)      # full 0-3.3V range

SENSITIVITY = 0.185           # volts per amp (5A version)
DIVIDER = 1.5                 # (10k + 20k) / 20k

def read_volts(samples):
    total = 0
    for _ in range(samples):
        total += adc.read_uv()
        time.sleep_ms(1)
    return total / samples / 1_000_000 * DIVIDER

# Calibrate the zero point - no load current for these 2 seconds!
print("Calibrating zero point, keep load OFF...")
zero = read_volts(500)
print("Zero = {:.3f} V. Measuring...".format(zero))

while True:
    volts = read_volts(100)
    amps = (volts - zero) / SENSITIVITY
    print("OUT: {:.3f} V | Current: {:.3f} A".format(volts, amps))
    time.sleep(0.5)

Raspberry Pi (Python + ADS1115)

acs712_rpi.py
#!/usr/bin/env python3
# ACS712 5A Current Sensor - Raspberry Pi + ADS1115 Example (DC current)
# OUT -> 10k/20k divider -> ADS1115 A0, SDA/SCL -> GPIO 2/3
# Install: pip3 install adafruit-circuitpython-ads1x15

import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

SENSITIVITY = 0.185    # volts per amp (5A version)
DIVIDER = 1.5          # (10k + 20k) / 20k

i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
ads.gain = 1           # +/-4.096V range
channel = AnalogIn(ads, ADS.P0)

def read_volts(samples):
    total = 0.0
    for _ in range(samples):
        total += channel.voltage
        time.sleep(0.002)
    return total / samples * DIVIDER

print("Calibrating zero point, keep load OFF...")
zero = read_volts(300)
print("Zero = {:.3f} V. Measuring...".format(zero))

try:
    while True:
        volts = read_volts(100)
        amps = (volts - zero) / SENSITIVITY
        print("OUT: {:.3f} V | Current: {:.3f} A".format(volts, amps))
        time.sleep(0.5)
except KeyboardInterrupt:
    print("Stopped by user")

Raspberry Pi Pico (MicroPython)

acs712_pico.py
# ACS712 5A Current Sensor - Pico MicroPython Example (DC current)
# OUT -> 10k/20k divider -> GP26 (ADC0), VCC -> VBUS (5V)

from machine import ADC
import time

adc = ADC(26)
CONVERSION = 3.3 / 65535
SENSITIVITY = 0.185        # volts per amp (5A version)
DIVIDER = 1.5              # (10k + 20k) / 20k

def read_volts(samples):
    total = 0
    for _ in range(samples):
        total += adc.read_u16()
        time.sleep_ms(1)
    return total / samples * CONVERSION * DIVIDER

print("Calibrating zero point, keep load OFF...")
zero = read_volts(500)
print("Zero = {:.3f} V. Measuring...".format(zero))

while True:
    volts = read_volts(100)
    amps = (volts - zero) / SENSITIVITY
    print("OUT: {:.3f} V | Current: {:.3f} A".format(volts, amps))
    time.sleep(0.5)

Frequently Asked Questions

Why does the sensor output 2.5V when no current is flowing?
Because the ACS712 is bidirectional. The output idles at half the supply voltage and moves up or down 185 mV per amp depending on which direction current flows through IP+/IP-. That is why the code subtracts the zero point first — current is proportional to the difference from 2.5V, not the absolute voltage.
How do I wire the load — does the sensor go in parallel or in series?
Always in series, like an ammeter. Break one wire of the circuit you want to measure and route it in through IP+ and out through IP-. Nothing about your load connects to the VCC/OUT/GND side — those only go to your microcontroller.
Can it measure AC current?
Yes — with 80 kHz of bandwidth it follows 50/60 Hz easily. The output swings above and below 2.5V each cycle, so a simple average reads zero; instead, sample fast for a full cycle or more and compute RMS from the samples. For safety, practice on low-voltage AC (like a 12V transformer) rather than mains.
Is it safe to measure mains (120V/230V) current?
The chip itself provides 2.1 kV RMS isolation between the current path and the sensor pins, so the principle is sound — commercial energy monitors use this exact part. In practice, mains work demands proper enclosures, insulated terminals, strain relief, and experience. If any of that is unfamiliar, keep this module on low-voltage projects or use a clamp-style non-contact sensor for mains.
My readings jump around by tens of milliamps. Is the module broken?
No — that is the nature of a 185 mV/A sensor on a noisy ADC: every millivolt of noise reads as ~5 mA. The fixes are averaging many samples (all the code examples do), calibrating the zero at startup, keeping sensor wires short, and powering from a clean 5V rail. For currents below ~100 mA, consider a shunt + INA219 style sensor instead, which resolves small currents far better.
What is the difference between the 5A, 20A, and 30A versions?
Range and sensitivity trade off: the 5A version outputs 185 mV/A, the 20A version 100 mV/A, and the 30A version 66 mV/A. This 5A board gives the finest resolution, so use it whenever your load stays within ±5A; pick a higher-range version only if you genuinely need the headroom. The same wiring and code work for all three — just change the sensitivity constant.
Why does my current read negative?
Current is flowing "backwards" relative to the IP+/IP- orientation — completely harmless. Either swap the two screw-terminal wires or just take the absolute value in code if you only care about magnitude. The sign is actually useful in battery projects, where it distinguishes charging from discharging automatically.

Related Tutorials