The ACS712 is a Hall-effect current sensor: the current you measure flows through a copper path inside the chip, and the chip outputs a voltage proportional to it. The common red module comes in 5 A, 20 A and 30 A versions and costs about ₹150.
On the Uno it is one analog input. VCC goes to 5V, OUT to A0. The output sits at half the supply (about 2.5 V, 512 counts) at zero current and moves up or down with current — 185 mV per amp on the 5 A version. The current path, IP+ and IP−, goes in series with the + wire of the load. The sketch demonstrates it with a 12 V DC lamp or fan.
The sketch measures the zero point at start-up, then averages 200 readings for each value it prints. Read the quirks for what the Uno’s 10-bit ADC can and can’t resolve.
Wiring
| Arduino Uno R3 | ACS712 current sensor (5 A / 20 A / 30 A) | Wire | Notes |
|---|---|---|---|
| — | IP- | — | To Load + (e.g. 12 V lamp or fan); load − to the 12 V supply − (not drawn) |
| 5V | VCC | red | The output is ratiometric: zero sits at half of this supply. |
| A0 | OUT | yellow | |
| GND | GND | black | |
| 12 V DC supply for the load · + | IP+ | red | Current path. It is isolated from the sensor side, so the 12 V supply doesn’t need a common ground for this. |
5 V (4.5–5.5 V) part, 5 V board. OUT sits at VCC/2 (2.5 V) at zero current and swings towards 0 or 5 V. On ESP32/Pico, scale OUT with a divider (e.g. 10 kΩ / 20 kΩ) and account for it in code.
Board quirks
- Resolution on the Uno is coarse: one ADC step is 4.9 mV, which is about 26 mA on the 5 A version and 74 mA on the 30 A one. Averaging 200 readings, as the sketch does, smooths that out — but don’t expect to measure a 20 mA LED.
- Pick the version for your current: the 5 A board (chip marked 05B) for small motors and strips, 20 A or 30 A only when you need it, as they are less precise.
- Zero drifts with temperature and with the Uno’s 5V. The sketch measures zero at every start, so switch the load off while it resets.
- Mains (230 V): the chip isolates the current path, but the cheap module’s screw terminals and PCB gaps are small. Measuring a mains appliance is electrician-only work, inside a closed enclosure with an MCB/RCCB upstream — or use a clip-on split-core CT that never touches the live wire.
Code
// ACS712 current sensor module on an Arduino Uno R3 - DC current.
// VCC → 5V, OUT → A0, GND → GND. IP+ / IP- in series with the load (+ wire).
// Zero is measured at start-up, so switch the load OFF while the Uno resets.
const uint8_t SENSE_PIN = A0;
const float MV_PER_A = 185.0; // 5 A version: 185, 20 A: 100, 30 A: 66 (printed on the chip: 05B / 20A / 30A)
float zeroCounts = 512;
float averageCounts(uint16_t n) {
long sum = 0;
for (uint16_t i = 0; i < n; i++) sum += analogRead(SENSE_PIN);
return (float)sum / n;
}
void setup() {
Serial.begin(9600);
zeroCounts = averageCounts(500); // the output idles near VCC/2 (about 512 counts)
Serial.print(F("ACS712 zero at "));
Serial.print(zeroCounts, 1);
Serial.println(F(" counts - now switch the load on"));
}
void loop() {
float counts = averageCounts(200); // averaging hides the ~26 mA per count steps
float mv = (counts - zeroCounts) * 5000.0 / 1023.0;
float amps = mv / MV_PER_A;
Serial.print(F("Current "));
Serial.print(amps, 2);
Serial.println(F(" A"));
delay(500);
}// ACS712 current sensor module on an Arduino Uno R3 - DC current.
// VCC → 5V, OUT → A0, GND → GND. IP+ / IP- in series with the load (+ wire).
// Zero is measured at start-up, so switch the load OFF while the Uno resets.
const uint8_t SENSE_PIN = A0;
const float MV_PER_A = 185.0; // 5 A version: 185, 20 A: 100, 30 A: 66 (printed on the chip: 05B / 20A / 30A)
float zeroCounts = 512;
float averageCounts(uint16_t n) {
long sum = 0;
for (uint16_t i = 0; i < n; i++) sum += analogRead(SENSE_PIN);
return (float)sum / n;
}
void setup() {
Serial.begin(9600);
zeroCounts = averageCounts(500); // the output idles near VCC/2 (about 512 counts)
Serial.print(F("ACS712 zero at "));
Serial.print(zeroCounts, 1);
Serial.println(F(" counts - now switch the load on"));
}
void loop() {
float counts = averageCounts(200); // averaging hides the ~26 mA per count steps
float mv = (counts - zeroCounts) * 5000.0 / 1023.0;
float amps = mv / MV_PER_A;
Serial.print(F("Current "));
Serial.print(amps, 2);
Serial.println(F(" A"));
delay(500);
}Expected serial output
ACS712 zero at 511.6 counts - now switch the load on
Current 0.02 A
Current 1.21 A
Current 1.19 AACS712 zero at 511.6 counts - now switch the load on Current 0.02 A Current 1.21 A Current 1.19 A
Common errors
Reads about 0.1–0.2 A with nothing connected
Zero taken with the load on, or noise. Restart with the load off, and keep the A0 wire away from motor leads.
Current shows negative
Current flows from IP− to IP+. Swap the two load wires, or use the absolute value.
Readings jump by hundreds of mA
Motor or PWM noise. Average more samples, add 100 nF from OUT to GND, and power the Uno separately from the motor supply.