Arduino Nano 33 IoT - ACS712 Current Sensor

How much current does your 12V motor really pull? Is that LED strip using as much as the label says? A multimeter can tell you once, but the Arduino Nano 33 IoT can watch it all the time. In this tutorial, the board reads an ACS712 30A Hall effect current sensor and prints the current in amps on the Serial Monitor. Here is the plan:

Arduino Nano 33 IoT ACS712 Current Sensor

Hardware Preparation

1×Arduino Nano 33 IoT
1×Micro USB Cable
1×ACS712 30A Current Sensor Module
1×Resistor Kit (10kΩ and 20kΩ)
1×12V DC Device (e.g. 12V DC Motor or 12V LED strip)
1×12V Power Adapter
1×DC Power Jack
1×Optionally, 5V Power Adapter for the sensor
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

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 Arduino Nano 33 IoT - Measure Voltage tutorial tells you how many volts a circuit has. The ACS712 answers the other question: how many amps flow through it. The trick is the Hall effect. The load current passes through a thick copper strip inside the chip. That current makes a small magnetic field, and a Hall sensor sitting next to the strip turns the field into a voltage. Since the copper strip never touches the measuring part, the load side is isolated from the Arduino Nano 33 IoT side (2.1 kV RMS). The strip is also only about 1.2 mΩ, so it barely changes the circuit you are measuring.

When no current flows, the OUT pin sits at half of the supply voltage, about 2.5V. Current in one direction pushes OUT above 2.5V, and current in the other direction pulls it below. The output is ratiometric: it follows the real supply voltage, so if the supply is 4.9V instead of 5V, the zero point moves a little too. This is the reason the code measures the zero point itself.

The ACS712 comes in three versions. They look the same, so check the text on the chip or on the shop page:

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

This tutorial uses the 30A version (chip ACS712ELCTR-30A-T). Its main numbers:

ACS712 30A
Supply voltage 5V (4.5V to 5.5V) - not 3.3V
Measuring range -30A to +30A, DC and AC
Sensitivity 66 mV per A
Output at 0A about 2.5V (half of the supply)
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 Pinout

ACS712 Current Sensor Module Pinout

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

  • VCC pin: must be connected to 5V. The chip does not work properly on 3.3V.
  • GND pin: must be connected to GND (0V) of the Arduino Nano 33 IoT.
  • OUT pin: the analog output voltage. On the Arduino Nano 33 IoT, it must go through a voltage divider before it reaches the analog pin (see the wiring section).
  • IP+ and IP- screw terminals: the current path. They must be placed in series with the load. In other words, cut one supply wire of the load and put the terminal in between. On some modules these two terminals have no labels. Current that flows from IP+ to IP- reads as a positive value.

There is also a small power LED. It turns on when VCC gets power.

※ NOTE THAT:

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

Is the 30A Version Right for Small Currents?

Not really. With the 66 mV per A sensitivity, a tiny current makes a tiny voltage change. On the Arduino Nano 33 IoT, one step of the 12-bit ADC is about 0.8 mV at the pin, which is about 1.2 mV at the sensor output after the divider. That is about 18 mA per step. On top of that, the sensor output has some noise, so a value that jumps between -0.08A and +0.08A with nothing connected is normal. Averaging many readings, as the code does, makes the result much calmer. The 30A module is a good fit for loads from about 0.5A and up: DC motors, 12V lamps, LED strips, heaters and battery chargers. For smaller loads, the 5A version gives better detail.

Wiring Diagram

Two things need care on this board, and both come from the fact that the Arduino Nano 33 IoT is a 3.3V board.

1. The OUT Pin Needs a Voltage Divider

The analog pins of the Arduino Nano 33 IoT accept 0V to 3.3V only, and they are NOT 5V tolerant. The ACS712 output can rise to about 4.5V at full current, which can damage the pin. So we never connect OUT straight to the board. Instead, we put two resistors in between:

  • OUT pin → 10kΩ resistor → pin A1 of the Arduino Nano 33 IoT
  • Pin A1 → 20kΩ resistor → GND

This divider gives the pin 2/3 of the sensor voltage. The highest output, 4.48V, becomes about 3.0V, which is safe. The zero point of 2.5V becomes about 1.67V. In the code, we multiply the measured voltage by 1.5 to get the real sensor voltage back.

2. Where Does the 5V for the Sensor Come From?

This is the tricky part on the Arduino Nano 33 IoT. The pin marked 5V on the header is really the VUSB pin. It is connected to the 5V of the USB port only through a small solder jumper on the bottom of the board, and this jumper is open from the factory. So, on a new board, the 5V pin gives no voltage at all. You have two choices:

  • Option A - close the VUSB jumper: bridge the two pads marked VUSB on the bottom side of the board with a drop of solder. After that, the 5V pin gives the USB 5V whenever the board is powered from USB. The ACS712 only needs about 10 mA, so this is fine for the sensor.
  • Option B - no soldering: power the sensor VCC from a separate 5V power adapter, and connect the GND of that adapter to the GND of the Arduino Nano 33 IoT.

Other tutorials for this board, such as the LCD one, talk about the VBUS pin. It is the same idea: that pin only carries USB power, and only when you power the board from USB. Do not use it for motors or other loads that need a lot of current. Here it only powers the small sensor chip.

The wiring diagram between Arduino Nano and 33 IoT ACS712 Current Sensor

This image is created using Fritzing. Click to enlarge image

ACS712 Module Connect to
VCC 5V (VUSB) pin with the jumper closed, or + of a 5V adapter
GND GND of the Arduino Nano 33 IoT
OUT 10kΩ resistor, then pin A1 (A1 also goes to GND through 20kΩ)
IP+ + of the 12V adapter (from the DC power jack)
IP- + wire of the 12V DC device

The - wire of the DC device goes back to the - of the 12V adapter. The 12V circuit does not need to share a ground with the Arduino Nano 33 IoT, because the sensor isolates it.

※ NOTE THAT:

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

How To Program For ACS712 Current Sensor

  • The first step is to set the ADC of the Arduino Nano 33 IoT to 12 bits, so the values go from 0 to 4095 (the default is only 10 bits):
analogReadResolution(12);
  • Turn a raw reading into the real sensor voltage. Divide by 4095, multiply by 3.3V, then multiply by 1.5 to undo the divider:
float pinVoltage = analogRead(A1) * 3.3 / 4095.0; float sensorVoltage = pinVoltage * 1.5;
  • Find the zero point in setup(). With the load switched off, average 1000 readings. This is the real "0A" voltage of your sensor, which is often a bit different from exactly 2.5V.
  • Calculate the current. Subtract the zero point and divide by the sensitivity (0.066V per A):
float current = (sensorVoltage - zeroVoltage) / 0.066;
  • In loop(), average a few hundred readings before each calculation, so the noise becomes smaller.

Arduino Nano 33 IoT Code for ACS712 DC Current

This code calibrates the zero point at start-up, then prints the sensor voltage and the DC current twice per second. Each result is the average of 200 readings.

/* * This Arduino Nano 33 IoT code was developed by newbiely.com * * This Arduino Nano 33 IoT code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-iot/arduino-nano-33-iot-acs712-current-sensor */ #define SENSOR_PIN A1 // The Arduino Nano 33 IoT pin connected to the divider (middle point) #define ADC_REF 3.3 // The Arduino Nano 33 IoT analog reference voltage #define ADC_MAX 4095.0 // 12-bit ADC: values from 0 to 4095 #define DIVIDER_RATIO 1.5 // 10k + 20k divider: OUT voltage = pin voltage x (30k / 20k) #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV per amp #define NUM_SAMPLES 200 // number of readings to average for each result float zeroVoltage = 2.5; // sensor output at 0 A, measured again in setup() // Read the analog pin many times and return the average ACS712 OUT voltage float readSensorVoltage(int samples) { long sum = 0; for (int i = 0; i < samples; i++) { sum += analogRead(SENSOR_PIN); delayMicroseconds(100); } float pinVoltage = (sum / (float)samples) * ADC_REF / ADC_MAX; return pinVoltage * DIVIDER_RATIO; // undo the divider to get the real OUT voltage } void setup() { Serial.begin(9600); while (!Serial) { delay(100); // wait for the Serial Monitor to open } analogReadResolution(12); // use the full 12-bit ADC of the Arduino Nano 33 IoT // Zero calibration: the load MUST be OFF now, so no current flows Serial.println("Calibrating... keep the load switched OFF"); zeroVoltage = readSensorVoltage(1000); Serial.print("Zero point: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); Serial.println("Done. You can switch the load ON now."); } void loop() { float voltage = readSensorVoltage(NUM_SAMPLES); float current = (voltage - zeroVoltage) / SENSITIVITY; Serial.print("Sensor output: "); Serial.print(voltage, 3); Serial.print(" V | Current: "); Serial.print(current, 2); Serial.println(" A"); delay(500); }

Detailed Instructions

If you are new to the Arduino Nano 33 IoT, be sure to check out our Getting Started with Arduino Nano 33 IoT tutorial. Then, follow these steps:

  • Wire the parts as shown in the diagram. Double-check the 10kΩ / 20kΩ divider: OUT must never touch A1 directly.
  • Switch the 12V load OFF (unplug the 12V adapter). The code measures the zero point at start-up, so no current may flow at that moment.
  • Connect the Arduino Nano 33 IoT board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Select the Arduino Nano 33 IoT board and its COM port.
  • Copy the code above and paste it into the Arduino IDE.
  • Click the Upload button to compile and send the code to the board.
  • Open the Serial Monitor and wait for the line "Done. You can switch the load ON now."
  • Plug in the 12V adapter to turn the DC device on, and watch the current.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Nano 33 IoT
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Nano 33 IoT' on 'COM15')
New Line
9600 baud
Calibrating... keep the load switched OFF Zero point: 2.493 V Done. You can switch the load ON now. Sensor output: 2.495 V | Current: 0.03 A Sensor output: 2.490 V | Current: -0.05 A Sensor output: 2.494 V | Current: 0.02 A Sensor output: 2.552 V | Current: 0.89 A Sensor output: 2.556 V | Current: 0.95 A Sensor output: 2.549 V | Current: 0.85 A Sensor output: 2.641 V | Current: 2.24 A Sensor output: 2.553 V | Current: 0.91 A
Ln 11, Col 1
Arduino Nano 33 IoT on COM15
2

The first three lines with the DC device off show the normal noise: a few hundredths of an amp around zero. In this run, the DC device is a 12V DC motor. With the motor running, the current stays near 0.9A. The 2.24A line is from holding the motor shaft with a finger for a moment: a slowed or stalled motor pulls much more current. If you see negative values with the DC device on, swap the two wires on the screw terminal, or just read the number without the minus sign.

Measuring AC Current

With AC, the current changes direction many times per second (50 or 60 times, depending on your country). The OUT pin swings above and below the zero point all the time, so a simple average would give almost 0A. Instead, we use the RMS (root mean square) value, which is what a normal AC meter shows.

The code reads the sensor as fast as it can for 200 ms. That is 10 full cycles at 50 Hz, or 12 at 60 Hz. For every reading, it takes the difference from the zero point and squares it. Then it takes the square root of the mean of all these squares, and divides it by 0.066:

float rmsCurrent = sqrt(sumOfSquares / count) / 0.066;

The wiring to the Arduino Nano 33 IoT stays the same: 5V, GND, and OUT through the 10kΩ / 20kΩ divider to A1. Only the load side changes: the screw terminal goes in series with one wire of the AC device.

※ NOTE THAT:

Again, mains voltage is dangerous. Only work on a mains circuit if you have the right skills, put the module in a closed box, and never touch the screw terminal while the power is on.

/* * This Arduino Nano 33 IoT code was developed by newbiely.com * * This Arduino Nano 33 IoT code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-iot/arduino-nano-33-iot-acs712-current-sensor */ #define SENSOR_PIN A1 // The Arduino Nano 33 IoT pin connected to the divider (middle point) #define ADC_REF 3.3 // The Arduino Nano 33 IoT analog reference voltage #define ADC_MAX 4095.0 // 12-bit ADC: values from 0 to 4095 #define DIVIDER_RATIO 1.5 // 10k + 20k divider: OUT voltage = pin voltage x (30k / 20k) #define SENSITIVITY 0.066 // ACS712 30A version: 66 mV per amp #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() // Convert one raw ADC reading to the ACS712 OUT voltage float toSensorVoltage(int adcValue) { return adcValue * ADC_REF / ADC_MAX * DIVIDER_RATIO; } void setup() { Serial.begin(9600); while (!Serial) { delay(100); // wait for the Serial Monitor to open } analogReadResolution(12); // use the full 12-bit ADC of the Arduino Nano 33 IoT // Zero calibration: the load MUST be OFF now, so no current flows Serial.println("Calibrating... keep the load switched OFF"); long sum = 0; for (int i = 0; i < 1000; i++) { sum += analogRead(SENSOR_PIN); delayMicroseconds(100); } zeroVoltage = toSensorVoltage(sum / 1000.0); Serial.print("Zero point: "); Serial.print(zeroVoltage, 3); Serial.println(" V"); } void loop() { // Sample as fast as possible during the time window double sumOfSquares = 0; long count = 0; unsigned long start = millis(); while (millis() - start < WINDOW_MS) { float diff = toSensorVoltage(analogRead(SENSOR_PIN)) - zeroVoltage; sumOfSquares += diff * diff; count++; } // RMS voltage around the zero point, then convert to amps float rmsVoltage = sqrt(sumOfSquares / count); float rmsCurrent = rmsVoltage / SENSITIVITY; Serial.print("AC current (RMS): "); Serial.print(rmsCurrent, 2); Serial.println(" A"); delay(300); }

Upload it the same way as the DC code, with the AC device switched off at start-up. Then switch the device on and open the Serial Monitor. In this example, a small fan heater runs on its low setting:

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

With nothing turned on, the RMS value is not exactly zero. The sensor noise is squared too, so a value of about 0.05A to 0.1A is normal. You can ignore readings below that level.

Additional Knowledge

How does the ACS712 compare with the voltage sensor used in the Arduino Nano 33 IoT - Measure Voltage tutorial?

ACS712 30A Voltage Sensor
What it measures current (amps) voltage (volts)
How it connects in series with the load in parallel with the load
DC and AC both DC only
Isolation from the board yes (Hall effect) no (simple resistor divider)
Power needed 5V none

It is evident that the two modules do different jobs and work well together. Read the voltage with one and the current with the other, then multiply them (power = voltage × current) to know how many watts your load uses.

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!