I'm currently doing a project on how to measure AC current using ACS712 and Arduino Mega 2560. The problem here is the result i got from my coding is not tally with the result I got from measuring the current using multimeter
const int CurrentIn1 = A0;
int mVperAmp = 66; // use 100 for 20A Module and 66 for 30A Module
float CurrentL1 = 0;
double VRMS1 = 0;
double Voltage1 = 0;
void loop()
{
Voltage1 = getVPP1();
VRMS1 = (Voltage1/2.0) *0.707;
CurrentL1 = ((VRMS1 * 1000)/mVperAmp)-0.07;
Serial.println(" Zone 1:");
Serial.print(CurrentL1);
Serial.println("A");
}
float getVPP1()
{
float result1;
int readCurrent1; //value read from the sensor
int maxValue1 = 0; // store max value here
int minValue1 = 1024; // store min value here
uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readCurrent1 = analogRead(CurrentIn1);
// see if you have a new maxValue
if (readCurrent1 > maxValue1)
{
/*record the maximum sensor value*/
maxValue1 = readCurrent1;
}
if (readCurrent1 < minValue1)
{
/*record the maximum sensor value*/
minValue1 = readCurrent1;
}
}
You do understand what AC is, right? It goes positive & negative and it crosses-through zero twice per cycle. So... The minimum is zero and there's no need to "find" the minimum. The ACS712 puts-out a positive voltage but it's still zero twice per cycle.
If you simply read the values (like the Analog Read Serial Example) the values will look "random" because you are sampling a continuously-varying voltage.
You can take several readings in a "fast loop" over s short period of time and then find the maximum (ignoring everything else). Then, multiply by 0.707 to get the RMS. That 0.707 factor is only valid for sine waves (like the power line).
There is more than one version of the ACS712 and you'll have to look at the sensitivity spec (mV/A) to find the amps-to-volts conversion factor. And of course, you'll need to include the 5/1024 factor.
The result I get on my multimeter is around 0.29A but on the serial monitor it print 0.97. So, do i need to remove the line "minimum sensor value" from my coding? but the formula that I do look almost the same like what you just told me.
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial mySerial (19,18);
/*
Measuring AC Current Using ACS712
*/
const int CurrentIn1 = A0;
const int CurrentIn2 = A1;
const int CurrentIn3 = A2;
int mVperAmp = 66; // use 100 for 20A Module and 66 for 30A Module
double Voltage1 = 0;
double Voltage2 = 0;
double Voltage3 = 0;
double VRMS1 = 0;
double VRMS2 = 0;
double VRMS3 = 0;
float CurrentL1 = 0;
float CurrentL2 = 0;
float CurrentL3 = 0;
void setup(){
Serial.begin(9600);
Wire.begin();
mySerial.begin (9600);
delay(1000);
}
void loop(){
/*Reading current sensor 1*/
Voltage1 = getVPP1();
VRMS1 = (Voltage1/2.0) *0.707;
CurrentL1 = ((VRMS1 * 1000)/mVperAmp)-0.07;
Serial.println(" Zone 1:");
Serial.print(CurrentL1);
Serial.println("A");
/*Reading current sensor 2*/
Voltage2 = getVPP2();
VRMS2 = (Voltage2/2.0) *0.707;
CurrentL2 = ((VRMS2 * 1000)/mVperAmp)-0.07;
Serial.println(" Zone 2:");
Serial.print(CurrentL2);
Serial.println("A");
/*Reading current sensor 3*/
Voltage3 = getVPP3();
VRMS3 = (Voltage3/2.0) *0.707;
CurrentL3 = ((VRMS3 * 1000)/mVperAmp)-0.07;
Serial.println(" Zone 3:");
Serial.print(CurrentL3);
Serial.println("A");
mySerial.print("Current:");
mySerial.print(CurrentL1);
mySerial.print("A");
mySerial.print("|");
mySerial.print("Current:");
mySerial.print(CurrentL2);
mySerial.print("A");
mySerial.print("|");
mySerial.print("Current:");
mySerial.print(CurrentL3);
mySerial.println("A");
delay (1000);
/*Display for under current Zone 1*/
if ((0.67 < CurrentL1) && (CurrentL1 < 0.74))
{
Serial.println("Lamp 1 Zone 1 need attention. Under current");
}
else if ((0.74 < CurrentL1) && (CurrentL1 < 0.79))
{
Serial.println("Lamp 2 Zone 1 need attention. Under current");
}
else if ((0.79 < CurrentL1) && (CurrentL1 < 0.84))
{
Serial.println("Lamp 3 Zone 1 need attention. Under current");
}
else if ((0.49 < CurrentL1) && (CurrentL1 < 0.54))
{
Serial.println ("Lamp 1 and 2 Zone 1 need attention. Under current.");
}
else if ((0.54 < CurrentL1) && (CurrentL1 < 0.59))
{
Serial.println ("Lamp 1 and 3 Zone 1 need attention. Under current.");
}
else if ((0.59 < CurrentL1) && (CurrentL1 < 0.64))
{
Serial.println ("Lamp 2 and 3 Zone 1 need attention. Under current");
}
else if (CurrentL1 < 0.44)
{
Serial.println ("All lamp in Zone 1 need attention. Under current");
}
/*Display for under current Zone 2*/
if ((0.67 < CurrentL2) && (CurrentL2 < 0.74))
{
Serial.println("Lamp 1 Zone 2 need attention. Under current");
}
else if ((0.74 < CurrentL2) && (CurrentL2 < 0.79))
{
Serial.println("Lamp 2 Zone 2 need attention. Under current");
}
else if ((0.79 < CurrentL2) && (CurrentL2 < 0.84))
{
Serial.println("Lamp 3 Zone 2 need attention. Under current");
}
else if ((0.49 < CurrentL2) && (CurrentL2 < 0.54))
{
Serial.println ("Lamp 1 and 2 Zone 2 need attention. Under current.");
}
else if ((0.54 < CurrentL2) && (CurrentL2 < 0.59))
{
Serial.println ("Lamp 1 and 3 Zone 2 need attention. Under current.");
}
else if ((0.59 < CurrentL2) && (CurrentL2 < 0.64))
{
Serial.println ("Lamp 2 and 3 Zone 2 need attention. Under current");
}
else if (CurrentL2 < 0.44)
{
Serial.println ("All lamp in Zone 2 need attention. Under current");
}
/*Display for under current Zone 3*/
if ((0.67 < CurrentL3) && (CurrentL3 < 0.74))
{
Serial.println("Lamp 1 Zone 3 need attention. Under current");
}
else if ((0.74 < CurrentL3) && (CurrentL3 < 0.79))
{
Serial.println("Lamp 2 Zone 3 need attention. Under current");
}
else if ((0.79 < CurrentL3) && (CurrentL3 < 0.84))
{
Serial.println("Lamp 3 Zone 3 need attention. Under current");
}
else if ((0.49 < CurrentL3) && (CurrentL3 < 0.54))
{
Serial.println ("Lamp 1 and 2 Zone 3 need attention. Under current.");
}
else if ((0.54 < CurrentL3) && (CurrentL3 < 0.59))
{
Serial.println ("Lamp 1 and 3 Zone 3 need attention. Under current.");
}
else if ((0.59 < CurrentL3) && (CurrentL3 < 0.64))
{
Serial.println ("Lamp 2 and 3 Zone 3 need attention. Under current");
}
else if (CurrentL3 < 0.44)
{
Serial.println ("All lamp in Zone 3 need attention. Under current");
}
}
float getVPP1()
{
float result1;
int readCurrent1; //value read from the sensor
int maxValue1 = 0; // store max value here
int minValue1 = 1024; // store min value here
uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readCurrent1 = analogRead(CurrentIn1);
// see if you have a new maxValue
if (readCurrent1 > maxValue1)
{
/*record the maximum sensor value*/
maxValue1 = readCurrent1;
}
if (readCurrent1 < minValue1)
{
/*record the maximum sensor value*/
minValue1 = readCurrent1;
}
}
// Subtract min from max
result1 = ((maxValue1 - minValue1) * 5.0)/1024.0;
return result1;
}
float getVPP2()
{
float result2;
int readCurrent2; //value read from the sensor
int maxValue2 = 0; // store max value here
int minValue2 = 1024; // store min value here
uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readCurrent2 = analogRead(CurrentIn2);
// see if you have a new maxValue
if (readCurrent2 > maxValue2)
{
/*record the maximum sensor value*/
maxValue2 = readCurrent2;
}
if (readCurrent2 < minValue2)
{
/*record the maximum sensor value*/
minValue2 = readCurrent2;
}
}
// Subtract min from max
result2 = ((maxValue2 - minValue2) * 5.0)/1024.0;
return result2;
}
float getVPP3()
{
float result3;
int readCurrent3; //value read from the sensor
int maxValue3 = 0; // store max value here
int minValue3 = 1024; // store min value here
uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readCurrent3 = analogRead(CurrentIn3);
// see if you have a new maxValue
if (readCurrent3 > maxValue3)
{
/*record the maximum sensor value*/
maxValue3 = readCurrent3;
}
if (readCurrent3 < minValue3)
{
/*record the maximum sensor value*/
minValue3 = readCurrent3;
}
}
// Subtract min from max
result3 = ((maxValue3 - minValue3) * 5.0)/1024.0;
return result3;
}
Hi, I'm using ACS712 current sensor 30A module. The data sheet of the module is as in the link below. I'm using 66mV/A for the conversion. I'm sorry for the (-0.07), I'm just trying to change the value on the monitor
Method is indeed correct, but the code could be more compact if you had used arrays.
Don't know why the original program is using such a long sampling time (1sec).
Long delays if you're measuring more than one ACS. I think 250ms (like a DMM) should be long enough.
What are you measuring.
Complex loads, like low energy lightbulbs (LED, spiral), could throw off the readings.
You must try these things with a resistive load (heater, incandescent lightbulb).
Remember that you only have a resolution of 1024/2*0.7= 358 steps across that 30Amp range.
The last digit of 0.97Amp is largely made up.
Leo..
You obviously didn't read the forum rules about how to post.
That leaves us with a lot of questions.
SoftwareSerial mySerial (19,18); // which Arduino...
Is it a 5volt Arduino, and how are you powering the sensors.
A 0.29A DMM readout for a 240volt/25watt incadescent lightbulb doesn't make sense.
It should be 25/240= ~0.1Amp.
Are you sure it isn't a 75watt bulb.
Wrote this short test sketch that gets rid of the multi-stage way of calculating current.
And only a few lines are needed to calculate current for all three sensors when arrays are used.
If you need to calibrate, use the biggest resistive load you have (> 2000watt).
Post back the results.
Leo..
unsigned long startTime;
int rawValue, maxValue, minValue;
float current[3]; // for three sensors
float calFactor = 0.0259; // change last digit(s) to calibrate
void setup() {
Serial.begin(9600);
}
void loop() {
rawValues();
// rest of the code here
// current[0] holds the value for the first sensor
}
void rawValues() {
for (int i = 0; i < 3; i++) {
maxValue = 0;
minValue = 1023;
startTime = millis();
while ((millis() - startTime) < 500) {
rawValue = analogRead(i);
if (rawValue > maxValue) maxValue = rawValue;
if (rawValue < minValue) minValue = rawValue;
}
current[i] = (maxValue - minValue) * calFactor;
Serial.print("Sensor");
Serial.print(i + 1);
Serial.print(": ");
Serial.print(current[i], 1);
Serial.print(" Amp");
if (i < 2) Serial.print("\t");
else Serial.println("");
}
}