# How to measure AC current using ACS712 and interface with ESP32?

Actually, I want to measure the AC current using ACS712 connect with ESP32 module. I know this module only works under 3.3v. So, I used voltage divider circuit and step down 5v to 3.3v which is being come from the acs712 20A (You may consider any of your 5A/20A/30A chip). I also tested the "ACS712.h" Arduino library. Still, I do not get proper current which I compared with 2 multimeters. Maybe I need to change in hardware side means place op. amp in between circuit. So, Help me to resolve my issue. Thank's in advance.

• Have you heard of a voltage regulator? Jun 6, 2019 at 7:35
• Yes, but I had given a regulated 3.3V power supply.
– jems
Jun 7, 2019 at 8:11
• You said "I used voltage divider circuit and step down 5v to 3.3v" and that would generally be the wrong approach - use a voltage regulator. Jun 7, 2019 at 8:48
• @Andy, the ACS712's output is 0 - 5V (assuming its VCC is 5V) and it's this output signal that's being reduced via a voltage divider to 0 - 3.3V. I had to "read between the lines" a bit to understand the intended meaning of jems' message. Like you, I initially thought that a resistive voltage divider was being used to create 3V3 power from 5V power, which is not the case. Jun 10, 2019 at 19:07
• "I used voltage divider circuit" - what resistor values did you use? "I do not get proper current which I compared with 2 multimeters" - what was the difference between them? Jun 11, 2019 at 0:13

I think your statement about stepping down from 5v to 3.3v is confusing but it looks like your issue is solely with the output of the ACS712 AC current sensor which nominally outputs 0V-5V to a microcontroller ADC corresponding to a range of -20A to 20A through the sense inputs of the ACS712.

In a normal setup with ACS712 providing your current reading to a 0-5V ADC (on an Arduino), you'd expect a current of 0A to correspond to a voltage of 2.5V at the microcontroller ADC input.

The issue here is that the ESP32 ADC inputs only go up to 3.3V and would give an incorrect maxed out reading for anything over about 6.4A:

((3.3 - 2.5V) / 0.125 V/A) = 6.4A


So, if you only need to read less than 6.4A you could theoretically use the ACS712 as is shown in any example circuit for the arduino setup without any kind of extra op-amp, buffer or voltage divider.

The other alternative is if you need readings higher than +6.4A but you only care about polarity going in one direction you can reverse the polarity of your inputs through the current sensor so that instead of a range of -20A to +6.4 you get -6.4A to +20A.

Depending on specific issues of porting that arduino sample code to the ESP you may run into issues with the ESP ADC input trying to automatically rescale itself from the expected 0V to 5V on the arduino down to the ESP32 0V to 3.3V range but if you can read the raw voltages coming into the ESP32 you should be able to do a simple linear conversion yourself:

Input V to your ESP32 ADC = (Sensed A * 0.125 V/A) + 2.5

E.g.:
5V = ( 20 * 0.125 V/A) + 2.5
2.5V = (  0 * 0.125 V/A) + 2.5
0V = (-20 * 0.125 V/A) + 2.5


In other words (Input V to ADC - 2.5 ) / 0.125 = Sensed Current at ACS712 and then flip polarity/sign of the output as needed.

Note: You don't want to get yourself into a situation where you may accidentally damage a 3.3V ADC by providing a 5V input but the ESP32 seems to be fairly tolerant of the 3.3->5V overvoltage on the inputs and our intent is to not actually get close to that by providing anything from -6.4A to -20A after reversing the polarity of your ACS712 inputs.

As mentioned, you've used a resistor divider (R1 and R2) to level down the voltage, but did you check the datasheet for the burden resistor? So the resistor divider between Vout and the ground should have an equivalent resistance greater than or equal to the burden resistor

( R1 + R2 ≥ Rb )


I don't know why they have not mentioned the resistor in the typical application diagram.  • I didn't check it but I will check it. Can you share me acs712 with opamp circuit.
– jems
Jun 7, 2019 at 8:12
• if you want you can just add a buffer between the micro-controller and the output resistor (of the divider). Jun 7, 2019 at 10:07
• You are using the voltage divider on pin 7 right? if so, do tell Andy that, i think he misunderstood your question and he's taking about using a regulator for the supply of ESP module from the 5 V supply of the sensor, if that's not the case then i misunderstood it :P Jun 7, 2019 at 10:12
• I used a resistor which less than Rb. I clarify I want to get the proper output of ACS712 AC current. It is not related to the voltage regulation circuit. Divyam how to add a buffer between a micro controller and o/p resistor.pls share at least any reference circuit.
– jems
Jun 10, 2019 at 4:07
• yeah i added the buffer with negative feedback, but its just a basic example, in the schematic the OP07 is just shown as it is available in LTSpice by default, before using an op-amp as buffer do checkout its datasheet to look for bandwidth, slew rate, etc....according to your needs. Jun 10, 2019 at 13:55

Some suggestions.

1. Use only a pure sine wave signal when testing and calibrating an AC measurement system. As a general rule do not use arbitrary wave forms like triangle, square, powered/spinning motors, aperiodic signals, etc. for testing / calibration purposes.

2. Ensure your ADC sampling rate (samples per second) is high enough, ensure your circuit grounds are connected together, and use circuit and software designs that minimize ADC ghosting.

3. When measuring AC signals with a multimeter, know that the multimeter indicates RMS values and not peak or peak-to-peak values. If your software measures the peak current value $$\i_p\$$ or the peak-to-peak current value $$\i_{p-p}\$$, then your software must convert that value to RMS before checking whether your system and the multimeter are yielding the same measurement value.

$$i_{RMS} = \frac {i_{p}}{\sqrt{2}} = \frac {i_{p-p}}{2\sqrt{2}}$$

1. Digital multimeters (DMM) are usually one of two types: average responding, RMS indicating; or, RMS responding, RMS indicating (a.k.a., true RMS). An average responding DMM requires a purely sinusoidal input signal when measuring AC volts or AC current; non-sinusoidal waveforms produce incorrect RMS indications on the meter's display and therefore should not be measured. An RMS responding DMM, also known as a true RMS DMM, indicates the correct RMS value of any AC waveform as long as the AC signal does not contain harmonics that exceed the meter's rated maximum measurement frequency. For example, if the meter can measure AC signals up to 300 kHz, then the arbitrary shaped AC signal must not contain harmonics exceeding 300 kHz.

See also: What is true-RMS? (Fluke); What is the difference between a multimeter with RMS and one with True RMS? (EE.SE).

2. You'll probably need to use one or more calibration constants in your software calculations to fine tune your measurement system. For example, you might need to add a DC offset (a bias adjustment) $$\k_1\$$ and a scaling factor (gain or sensitivity adjustment) $$\k_2\$$.

$$i_{corrected}=k_2 \cdot i_{measured} + k_1$$

1. The easiest way to determine calibration factors like k1 and k2 is to generate a calibration table that maps applied current vs measured current values, and then use the curve fitting tools in MATLAB or Excel or whatever to determine these constants.

+---------+----------+
| Applied | Measured |
| Current | Current  |
| (A_RMS) | (A_RMS)  |
+---------+----------+
|   1.0   |          |
|   2.0   |          |
|   3.0   |          |
|   ...   |          |
+---------+----------+
Applied = Measured by the DMM (the reference standard)
Measured = Measured by your system (the device under test, or DUT)


Actually the issue is with ESP32 module as it has an inbuilt Hall effect sensor and ACS712 is also based on Hall effect. thus this is causing the incorrect result. I'm also having this problem and not able to resolve it. you can check the same code with NodeMCU, it will give you the desired result .

I would try running the sensor on 5volt, and use a (10k)resistor between sensor out and analogue in. No current would be 2.5volt, so ~75% on the A/D scale. With the 20A version of the ACS712 you probably won't have any clipping. Larger currents will clip the top of the sine wave. You could try reading only the negative half of the sinewave in software.