Welcome to Solarduino , A blog about DIY Solar PV and Arduino projects
acs712 module to measure dc current arduino

How to measure AC Current with Arduino ?

Arduino has the ability to measure current using analog input pin. For Arduino UNO, there are 6 analog input pins (A0-A5) where you can use one of the pins to measure AC current. Arduino NANO has 8 pins while Arduino MEGA has 16 input pins. The analog input pins will map input voltages between 0 and 5V into integer values between 0 and 1023 with resolution of 4.9mV per unit (5.00V / 1024 units).

Arduino UNO (compatible board)

If you still not yet own an Arduino Micro-controller Board, you can get it cheap at our affiliate link here !!!

Warning ! You are now dealing with high power source ! We assumed that you have the basic electrical knowledge and know what you are dealing with. You may need guidance from experienced guys if you are new to electrical work. Safety and Precaution must be always have in mind. We shall not be responsible for anything happening to you.

The current sensor that is widely used for Arduino is the ACS712 Current Sensor Module. It utilizing hall-effect phenomenon which voltage is produced from the movement of current within the region of magnetic field. The voltage produced by hall effect is directly proportional to the applied current making it suitable to estimate the applied current from the voltage sensed.

The sensor can measure current in 2 direction. Reverse current will not damage the sensor but the voltage produced will be in reduced. As we know, Arduino analog input only read positive integer values. In order to measure 2 direction, the zero point should be at half the total voltage range (0 to 5V) which is 2.5V. This is true if the supply voltage to the sensor is 5V. 

This sensor can be used to measure AC current and DC current. DC current is somehow straight forward. The output analog value will be stay at a constant value. DC current will just need to convert analog input which is equivalent to 0-5V voltage range and then convert into relative current value.

However, AC current is more complicated as the analog value will swing around the middle point (512 value). We need to collect data every point of its instantaneous point of the wave and calculate its average or Root Mean Square. The value then to convert to 0-5V range and find out the relative current value.

The standard ACS712 Current Sensor Module rated at 5A, 20A and 30A which are suitable to most applications. You may get them by our affiliate link here !!! The 5A module has the resolution of 185mV/ampere, 20A module has 100mV/ampere while 30A module has the resolution of 66mV/ampere.

Assume using 5V supply as standard, the 5A module will provide voltage within 2.5V +/- 0.925V, 20A module will provide voltage within 2.5V +/- 2.0V while 30A module will provide voltage within 2.5V +/- 2.0V. These modules require direct contact which I think is a major drawback. It has to be connected in series to the measured value.The wiring of the existing system need to be altered in order to fit the module into the existing system. 

If you are inexperience guy dealing with AC power, I personally don’t recommend this module. This module is acceptable for DC low voltage but it can be dangerous in AC power if care is not taking seriously

Fortunately, there is also a hall-effect sensor type with split core transformer type (as picture on left). It is the Hall-Effect Split-Core Sensor HSTS016L module. The model ranges from 10A up to 200A. With split core current sensor type, not alteration on the existing system required. You can get it via our affiliate link here !!! The output voltage of this sensor is 2.5V +/- 0.625V with decent accuracy. I highly recommend this sensor for measuring AC current.

Current sensor is a sensitive sensor. The output reading of the sensor produces electrical noises or fake current values even when there is no current detected. It is more obvious if the measurement is in a smaller time frame. In order to greatly reduce this phenomenon, multiple samples must be taken for averaging and initial offset must be done. 

Our code is designed to display a value which is derived from averaging 1000 samples in every second. Each sample is recorded every 1 milli second (0.001 second). Each single sample value is being squared initially and once the 1000 sample values are accumulated, the average value from the 1000 samples is then being square-rooted in order to come out the RMS current value which is to be displayed at Serial Monitor and LCD Display. With this averaging, the fluctuation of value is way lesser compare to taking 1 sample reading every second.

The second problem could be the false signal and accuracy problem. Each sensor has its own deviation error. When there is no current sensed, the sensor might not be 100% at middle point of voltage value. Some might be remaining at few milli voltages above / below the middle point even though after averaging. This might be due to voltage supplied not in exact 5V or due to the sensor itself.

So, the sensor requires initial offset setting. You may need to manually offset the value by checking the false current when no current draws during Arduino startup and then key in offset value in the code file. Secondly, make sure the sensor cables are tight because minor movement of wires might affects on the wire terminal connections thus affecting the accuracy reading.

Once the wave swing is calibrated to oscillate at exact middle point, after the calculation of squared, averaging and square root, there is still some minor false value existed even no voltage measurement. So our code included the second offset setting to eliminate this noise value. 

I recommend you to add a 16X2 LCD Display Shield which can be directly fit on to the top of the Arduino board without the need of extra wiring for the LCD Display. Without the LCD Display, you can only monitor the measured current value on PC via Serial Monitor. You can get the LCD Display board at our affiliate link here !!!. 

The good news is you do not need to manually calibrate the offset settings if you got the LCD Display Shield with you. Below we have attached the code that utilizes the button function that could automatically calibrate by itself when you pressed the SELECT Button. You may download from the end of this page below.  

Hardware Connection – ACS712 Current Module 

In order to connect wiring between Arduino board and ACS712 current module, you need the dupont line cables male to female. You can get it at our affiliate link here !!!

Hardware Connection – HSTS016L Split Core Current Module 

You may need to find a way to fit the sensor cable into the Arduino pin. The sensor cable that I purchased came with pre-soldered at the tip, making it easy to go into the Arduino pins. Open the Split Core current module and there will show an arrow symbol which signify the way of current flow. Once everything ready, make sure the split core is closed tightly.  

Software Codes

The final step would be adding source code onto Arduino board. I assume you have installed the Arduino Software. If you have not installed the software, the link here can bring you to the official download site. Once you have downloaded the software, you may download the code file (.ino) for this application below (right click save link). 

There is 2 source codes file attached which are source code with and without LCD display shield function. If you don’t have LCD Display shield with you, kindly choose the code that is without LCD Display Shield but you have to manually calibrate and key in the 2 offset values. However, I still highly recommend that you get a LCD Display Shield.

With LCD Display Shield, once the code is uploaded to the Arduino board, the current value will be shown on the LCD Display. We have added the auto calibrate function, once the SELECT button is pressed, the value returns to exact zero point. If first press is not satisfied, you may repeat by pressing it again.

Screw Shield / Expansion Shield

When there are a lot of wiring around especially more than 1 sensor, sharing pins will be difficult as existing pins (ground and 5V) are limited. This shield provides a lot of convenient terminals for each of the input and output pins. The shield can be mounted directly on top of the Arduino Uno board or in between the shields which made it very convenient to use. You can get it at our affiliate link here !!!

Datalogger Shield

If you plan to record the data in a proper way, you may consider this Datalogger Shield. It allows your arduino to record your data in SD Card. Datalogger shield is often installed together with LCD Display shield. Please find it at our affiliate link here !!! For more about this Datalogger Shield, kindly visit our post here.

Codes for AC Current Sensor with LCD Display Shield Note: the codes shown here may not be 100% correct due to translation error. For accurate code, kindly download the .ino file. 

// AC Current Sensor with LCD By Solarduino

// 0- General

int decimalPrecision = 2;

// 1- AC Current Measurement

int CurrentAnalogInputPin = A1;
float mVperAmpValue = 185;

float offsetSampleRead = 0;
float currentSampleRead = 0;
float currentLastSample = 0;
float currentSampleSum = 0;
float currentSampleCount = 0;
float currentMean ;
float RMSCurrentMean ;
float adjustRMSCurrentMean ;
float FinalRMSCurrent ;

//1.1 Offset AC Current

int OffsetRead = 0;
float currentOffset1 = 0;
float currentOffset2 = 0;
float offsetSampleSum =0;
float offsetCurrentMean = 0;
float offsetLastSample = 0;
float offsetSampleCount = 0;

//2 - LCD Display

#include LiquidCrystal LCD(8,9,4,5,6,7);
unsigned long startMillisLCD;
unsigned long currentMillisLCD;
const unsigned long periodLCD = 1000;

void setup()

{

// 0- General

Serial.begin(9600);

// 2 - LCD Display

LCD.begin(16,2);
LCD.setCursor(0,0);
startMillisLCD = millis();

}

void loop()
{

// 0- General

// 0.1- Button Function

int buttonRead;
buttonRead = analogRead (0);

//Right button is pressed
if (buttonRead < 60)
{ LCD.setCursor(0,0); LCD.print ("PRESS<select>"); }</select>

// Up button is pressed
else if (buttonRead &lt; 200)
{ LCD.setCursor(0,0); LCD.print ("PRESS<select>"); }</select>

// Down button is pressed
else if (buttonRead &lt; 400)
{ LCD.setCursor(0,0); LCD.print ("PRESS<select>"); }</select>

// Left button is pressed
else if (buttonRead &lt; 600)
{ LCD.setCursor(0,0); LCD.print ("PRESS<select>"); }</select>

// Select button is pressed
else if (buttonRead &lt; 800) { OffsetRead = 1; LCD.setCursor(0,0); LCD.print ("INITIALIZING..... "); LCD.setCursor(0,1); LCD.print ("WAIT 5 SEC ..... "); } // 1- AC Current Measurement if(millis() &gt;= currentLastSample + 1)
{
offsetSampleRead = analogRead(CurrentAnalogInputPin)-512;
offsetSampleSum = offsetSampleSum + offsetSampleRead;

currentSampleRead = analogRead(CurrentAnalogInputPin)-512 + currentOffset1;
currentSampleSum = currentSampleSum + sq(currentSampleRead) ;

currentSampleCount = currentSampleCount + 1;
currentLastSample = millis();
}

if(currentSampleCount == 1000)
{
offsetCurrentMean = offsetSampleSum /currentSampleCount;

currentMean = currentSampleSum/currentSampleCount;
RMSCurrentMean = sqrt(currentMean);
adjustRMSCurrentMean = RMSCurrentMean + currentOffset2;
FinalRMSCurrent = (((adjustRMSCurrentMean /1024) *5000) /mVperAmpValue);
Serial.print(" The Current RMS value is: ");
Serial.print(FinalRMSCurrent,decimalPrecision);
Serial.println(" A ");
offsetSampleSum = 0;
currentSampleSum =0;
currentSampleCount=0;
}

//1.1 - Offset AC Current

if(OffsetRead == 1)
{
currentOffset1 = 0;
if(millis()&gt;= offsetLastSample + 1)
{
offsetSampleCount = offsetSampleCount + 1;
offsetLastSample = millis();
}
if(offsetSampleCount == 1500)
{
currentOffset1 = - offsetCurrentMean;
OffsetRead = 2;
offsetSampleCount = 0;
}
}

if(OffsetRead == 2)
{
currentOffset2 = 0;
if(millis()&gt;= offsetLastSample + 1)
{
offsetSampleCount = offsetSampleCount + 1;
offsetLastSample = millis();
}

if(offsetSampleCount == 2500)
{
currentOffset2 = - RMSCurrentMean;
OffsetRead = 0;
offsetSampleCount = 0;
}
}

// 2 - LCD Display

currentMillisLCD = millis();
if (currentMillisLCD - startMillisLCD &gt;= periodLCD)
{
LCD.setCursor(0,0);
LCD.print("I=");
LCD.print(FinalRMSCurrent,decimalPrecision);
LCD.print("A                   ");
LCD.setCursor(0,1);
LCD.print("                      ");
startMillisLCD = currentMillisLCD ;
}

}

Before we end, we would like to give gratitude to you for taking the time to read the post. We would need readers like you to support us in order to keep growing. You can support us in the following ways :

Donate & Fund Raising

If you like my work, please send me a donation to encourage me to do more. Thanks

Aliexpress Affiliate

We are the member of Aliexpress affiliate marketing. Do support us by clicking the affiliate product links if you do wish to purchase them.

Like and Share

If you like our post, we need your support to like and share our posts or videos so that it can reach more and more people like you !!

Result – in Serial Monitor

Result – in LCD Display

 

For Arduino Code Files, Remember to Right Click > Save Link As … You may alter the internal code as you wish. Happy coding !! 

AC Current Sensor.ino
AC Current Sensor with LCD Display.ino