Measure AC current by interfacing ACS712 sensor with ESP32

Measure AC current by interfacing ACS712 sensor with ESP32 Measure AC current by interfacing ACS712 sensor with ESP32

Overview:

In this Project let learn how to interface an ACS712 current sensor module with ESP32 microcontroller board to measure the AC current of the load and display the current in Amperes and power consumption in Wattage of it on 16X2 LCD display module.

So, by using this project you can build a power monitor or AC power consumption monitoring system. You can also implement IOT to get the data over the internet or cloud. This ACS712 sensor comes in 3 version, which you can choose according to your need. 5A, 20A and 30A versions of ACS712 are available in the market.

Related Project: Measure AC current using ACS712 sensor with Arduino

Required components:

Product NameQuantityamazon logoamazon logo india
ESP32 Microcontroller1https://amzn.to/3s0Sut6https://amzn.to/3Kw2np2
ACS712 current sensor module1https://amzn.to/3v4ok8yhttps://amzn.to/3EaJ9Dz
LCD 16X2 module with or without I2C adapter1https://amzn.to/3BNSRuphttps://amzn.to/363ki7F
5V power supply (Micro USB or External).1https://amzn.to/3s1a8g3https://amzn.to/364yInH
Few Connecting Wireshttps://amzn.to/3H2BV4ehttps://amzn.to/3J0WVu2
You can buy the required components from the given best buy links. We choose the components according to value for money.

ACS712 current sensor module:

ACS712 IC uses hall effect principle to measure the current which is developed by Allegro Micro SystemsACS712 IC consists of a low-offset, precise and linear Hall sensor circuit with a copper conduction path at the surface of the die.

ACS712 Current sensor module application circuit

ACS712 modules has 3 versions with different sensitivities.

You need to choose the right module according to your requirement, as higher the capacity of the sensor lower the accuracy.

5A Module 20A Module 30A Module
185mV/Amp 100mV/Amp 66mV per Amp

From the above table you can see the higher the measuring capacity the sensitivity of measuring the Milli Volts per Amp decreases. To measure smaller currents using smaller range module gives more accurate results than using high range module.

For more details about the ACS712, Please refer ACS712 datasheet : here

ACS712 current sensor module Specifications

  • Measures both AC and DC current
  • Very small in size
  • Available in 5A, 20A and 30A modules
  • 66 to 185 mV/A output sensitivity
  • Outputs analog voltage, so its easy to connect with most of the Microcontrollers.

For Principle, pinout diagrams and Working of ACS712 module in detail please refer our previous article: ACS712 Principle, working and pinout.

Interfacing ACS712 Current sensor with ESP32 to display result over LCD display.

 

ACS712 current sensor with ESP32 circuit diagram with voltage divider

As you can see from the above circuit diagram the LCD display and ACS 712 current sensor VCC and GND pins are powered through the VIN and GND pins of ESP32. If you are not getting 5volts voltage from the VIN pin of ESP32 connect an external 5V power supply to ACS712 module as it requires exact 5volts for calculations.

The Data pin OUT of ACS712 outputs analog voltage between 0 to 5v which is not compatible with ESP32 ADC as it takes between 0 to 3.3v. When no load is connected the OUT pin gives 2.5volts, the voltage increases when the load is increased if in positive polarity and decreases to zero in negative polarity.

To make it compatible with ESP32 a stepdown voltage divider is created with 2 resistors 1k ohm and 2k ohms is connected to Analog pin D34 of ESP32 as shown image with dotted box. The I2C communication pins SDA and SCL pins of LCD display are connected to D21 and D22 pins respectively.

voltage divider formula

If you want to use an LCD display with out I2c refer this article: Interfacing 16X2 LCD Module with ESP32 without I2C

After connecting everything its time to upload the program code.

Connect the AC load to ACS712 module only after uploading the code to ESP32, as AC current has high voltage which can electric shock us.

Program code:

Connect the ESP32 microcontroller board to the PC where Arduino IDE is installed through USB cable. Choose the correct port and board as ESP32 Wrover Module  from Tools menu and install the required libraries from the Library manager or download from the below links and extract them in Arduino Libraries folder.

Required Libraries:

  • Download LiquidCrystal_I2C – Link

Next copy the below code and paste it in IDE workspace and press upload button. That’s it the code will be uploaded.

// Tested and compiled with no errors
// measuring AC current using ACS712 current sensor with ESP32 Microcontroller
// The ACS712 works with high voltage AC so be careful !
// source - /www.circuitschools.com
 
#include <LiquidCrystal_I2C.h>

const int sensorIn = 34;      // pin where the OUT pin from sensor is connected on Arduino
int mVperAmp = 185;           // this the 5A version of the ACS712 -use 100 for 20A Module and 66 for 30A Module
int Watt = 0;
double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;
 
// initialize the LCD library with I2C address and LCD size
LiquidCrystal_I2C lcd (0x27, 16,2); 
 
void setup() {
  Serial.begin (9600); 
  Serial.println ("ACS712 current sensor"); 
  // Initialize the LCD connected 
lcd. init ();
// Turn on the backlight on LCD. 
lcd. backlight ();
lcd.print ("ACS712 current");
lcd. setCursor (0, 1);
lcd.print ("sensor");
delay(1000);
lcd.clear();  
}
 
void loop() {
  Serial.println (""); 
  Voltage = getVPP();
  VRMS = (Voltage/2.0) *0.707;   //root 2 is 0.707
  AmpsRMS = ((VRMS * 1000)/mVperAmp)-0.3; //0.3 is the error I got for my sensor
 
  Serial.print(AmpsRMS);
  Serial.print(" Amps RMS  ---  ");
  Watt = (AmpsRMS*240/1.2);
  // note: 1.2 is my own empirically established calibration factor
// as the voltage measured at D34 depends on the length of the OUT-to-D34 wire
// 240 is the main AC power voltage – this parameter changes locally
  Serial.print(Watt);
  Serial.println(" Watts");
  lcd. setCursor (0, 0);
  lcd.print (AmpsRMS);
lcd.print (" Amps ");
//Here cursor is placed on first position (col: 0) of the second line (row: 1) 
lcd. setCursor (0, 1);
lcd.print (Watt);
lcd.print (" watt ");
delay (100);
}
 
// ***** function calls ******
float getVPP()
{
  float result;
  int readValue;                // value read from the sensor
  int maxValue = 0;             // store max value here
  int minValue = 4096;          // store min value here ESP32 ADC resolution
  
   uint32_t start_time = millis();
   while((millis()-start_time) < 1000) //sample for 1 Sec
   {
       readValue = analogRead(sensorIn);
       // see if you have a new maxValue
       if (readValue > maxValue) 
       {
           /*record the maximum sensor value*/
           maxValue = readValue;
       }
       if (readValue < minValue) 
       {
           /*record the minimum sensor value*/
           minValue = readValue;
       }
   }
   
   // Subtract min from max
   result = ((maxValue - minValue) * 3.3)/4096.0; //ESP32 ADC resolution 4096
      
   return result;
 }

After uploading the code open serial monitor at baud rate 9600 to check how the sensor is working. Serial monitor shows results as shown in the below output screenshot.

ACS712 current sensor with ESP32 output on serial monitor

Every ACS712 current sensor has some level of error, here I am using 30A version so the sensitivity is low, in the result there are some fluctuations.

Calibrating ACS712 current sensor:

At no load situation open serial monitor and check weither the amp values are near to Zero. If the values are not near to zero, and if the values are positive then substract the error value from the line 36, if the values are negative then add the error value till you reach the near zero level.

Calibration is important to get the nearly accurate results, You can also calibrate with some known current loads and correct the error through the code.

Outputs:

When no load is connected the LCD display outputs as below:

ACS712 current sensor with ESP32 lcd with noload

When a small load is connected the LCD display outputs as below image:

ACS712 current sensor with ESP32 lcd with load connected

If you like this project please subscribe to our YouTube Channel “Circuit Schools to encourage us to publish more interesting projects. If you have any doubts write to us from below comment section.

9 comments
  1. With the center voltage ( zero amps ) at 2.5v (half of the 5v input) calculations show that at full current on any of the sensors
    you are at or over the input voltage of the esp32 adc input, or am I wrong??
    5a = ( .185/a * 5a) = (.925v + 2.5V ) = 3.425v
    20a = (.100/a * 20a) = (2v + 2.5v) = 4.5v
    30a = (.066/a * 30a) = (1.98v + 2.5v) = 4.48v

    Full swing of the sensor output can be 5v with 0v being the negative current rating, 2.5v being 0a, and full rating would be 5v.
    Wouldn’t you need a divider on the input to be safe using the esp32?
    Inquiring as I am in the process of setting up an esp32 with 3*asc712 sensors to monitor a small solar system.

    1. If you are going to measure +5a then you would want a resistor divider to limit the output of the acs712 to 3.3v. However, if you are only measuring DC amperes then wire the ACS712 so that the current is negative and therefore the output voltage will max out at ~2.5v. Do the math to compensate.

      1. Hi. I am testing 13v DC current from a solar setup, using the 20a ACS712. I’m getting 2.4amp readout when using a test bulb that’s been multimeter-tested to draw 4.5 amp. I will try the above re; wire it with resistors so I get zero at zero load. Is there any other suggestion before I test a dozen resistors? Thanks.
        pd; yes I already modified the code to use 13v as basis, not 240AC.

  2. When you know that max. input Voltage of ESP32 is 3.3V, then you need to consider that in any case. Especially when you want to involve 5 volts. Your coding and the schematic quality is good, but you need to take into account that novices or people with less electronics knowledge rely on your explanation, for them the “project” has to be “idiot-safe approved” and complete with no hidden constraints (works in this way, but you should not do that… which is not obvious to the user and not told on this webpage, unless mentioned by another chat user – you can work like this on your own, but not when publishing on internet), so that they do not damage their electronic circuits. A voltage divider or an opamp circuit for D34 is a must in this project!

    bye
    Dieter
    an electronics engineer

      1. I tried using your code for esp32 to Ic2 LCD. But for some reason there are white boxes instead of text. I have tried twisting the potentiometer but it didn’t work.

  3. Remark #2:
    Concerning I2C bus signal for LCD, I would implement voltage translators with two MOSFETs with low gate voltage for interfacing 3.3V/5V. Very often I see schematics where wires are directly connected to transistors or ICs as if resistors are nice-to-have-circuits which could be neglected. Always look into data sheets for maximum allowed input currents and voltages before you start… or buy your electronic equipment several times, until you learn to use/read data sheets 🙂

  4. Hi.
    I want to measure current with ACS712, ESP32 and Blynk.
    What will the circuit diagram and code be like?

    Thanks

  5. #include

    const int sensorIn = 34; // pin where the OUT pin from sensor is connected on Arduino
    int mVperAmp = 185; // this the 5A version of the ACS712 -use 100 for 20A Module and 66 for 30A Module
    int Watt = 0;
    double Voltage = 0;
    double VRMS = 0;
    double AmpsRMS = 0;

    // initialize the LCD library with I2C address and LCD size
    LiquidCrystal_I2C lcd (0x27, 16,2);

    void setup() {
    Serial.begin (9600);
    Serial.println (“ACS712 current sensor”);
    // Initialize the LCD connected
    lcd.init();
    // Turn on the backlight on LCD.
    lcd.backlight();
    lcd.print(“ACS712 current”);
    lcd.setCursor(0, 1);
    lcd.print(“sensor”);
    delay(1000);
    lcd.clear();
    }

    void loop() {
    Serial.println(“”);
    Voltage = getVPP();
    VRMS = (Voltage/2.0) *0.707; //root 2 is 0.707
    AmpsRMS = ((VRMS * 1000)/mVperAmp)-0.3; //0.3 is the error I got for my sensor
    Serial.print(“Voltage: “);
    Serial.print(Voltage);
    Serial.print(“V “);
    Serial.print(“Current: “);
    Serial.print(AmpsRMS);
    Serial.print(“A “);
    Watt = (AmpsRMS*240/1.2);
    // note: 1.2 is my own empirically established calibration factor
    // as the voltage measured at D34 depends on the length of the OUT-to-D34 wire
    // 240 is the main AC power voltage – this parameter changes locally
    Serial.print(“Power: “);
    Serial.print(Watt);
    Serial.println(“W”);
    lcd.setCursor(0, 0);
    lcd.print(“V: “);
    lcd.print(Voltage);
    lcd.setCursor(0, 1);
    lcd.print(“I: “);
    lcd.print(AmpsRMS);
    lcd.print(“A “);
    delay(100);
    }

    // ***** function calls ******
    float getVPP()
    {
    float result;
    int readValue; // value read from the sensor
    int maxValue = 0; // store max value here
    int minValue = 4096; // store min value here ESP32 ADC resolution

    uint32_t start_time = millis();
    while((millis()-start_time) maxValue)
    {
    /*record the maximum sensor value*/
    maxValue = readValue;
    }
    if (readValue < minValue)
    {
    /*record the minimum sensor value*/
    minValue = readValue;
    }
    }

    // Subtract min from max
    result = ((maxValue – minValue) * 3.3)/4096.0; //ESP32 ADC resolution 4096

    return result;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *