Hi,
I am using the ACS712 (20A) sensor to measure 230V AC using Arduino IDE. I am using the code attached below, but I am not able to understand why the sensor is not giving me reliable current values.
const int currentPin = A0;
const unsigned long sampleTime = 100000UL; // sample over 100ms, it is an exact number of cycles for both 50Hz and 60Hz mains
const unsigned long numSamples = 250UL; // choose the number of samples to divide sampleTime exactly, but low enough for the ADC to keep up
const unsigned long sampleInterval = sampleTime/numSamples; // the sampling interval, must be longer than then ADC conversion time
// const int adc_zero = 522; // relative digital zero of the arudino input from ACS712 (could make this a variable and auto-adjust it)
int adc_zero; //autoadjusted relative digital zero
void setup()
{
Serial.begin(9600);
pinMode(currentPin, INPUT);
adc_zero = determineVQ(currentPin); //Quiscent output voltage - the average voltage ACS712 shows with no load (0 A)
delay(1000);
}
void loop(){
Serial.print("Current:");Serial.print(readCurrent(currentPin),3);Serial.println(" mA");
delay(150);
}
int determineVQ(int PIN) {
Serial.print("estimating avg. quiscent voltage:");
long VQ = 0;
//read 5000 samples to stabilise value
for (int i=0; i<5000; i++) {
VQ += analogRead(PIN);
delay(1);//depends on sampling (on filter capacitor), can be 1/80000 (80kHz) max.
}
VQ /= 5000;
Serial.print(map(VQ, 0, 1023, 0, 5000));Serial.println(" mV");
return int(VQ);
}
float readCurrent(int PIN)
{
unsigned long currentAcc = 0;
unsigned int count = 0;
unsigned long prevMicros = micros() - sampleInterval ;
while (count < numSamples)
{
if (micros() - prevMicros >= sampleInterval)
{
long adc_raw = analogRead(currentPin) - adc_zero;
currentAcc += (unsigned long)(adc_raw * adc_raw);
++count;
prevMicros += sampleInterval;
}
}
float rms = sqrt((float)currentAcc/(float)numSamples) * (100 / 1024.0);
return rms;
}
The code outputs under no load:
Current:0.081 mA
Current:0.082 mA
Current:0.081 mA
Current:0.083 mA
Current:0.082 mA
Current:0.080 mA
Current:0.075 mA
Current:0.082 mA
Current:0.083 mA
Current:0.087 mA
Next I tried this code,
/*
Measuring AC Current Using ACS712
*/
const int sensorIn = A0;
const int notifyPin = 2;
int mVperAmp = 100; // use 100 for 20A Module and 66 for 30A Module
double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;
void setup(){
Serial.begin(9600);
pinMode(notifyPin, OUTPUT);
}
void loop(){
Voltage = getVPP();
Serial.println(Voltage);
VRMS = (Voltage/2) *0.70710678;
AmpsRMS = (VRMS * 1000)/mVperAmp; // Current Sense Line
// AmpsRMS = (VRMS * 10000)/mVperAmp;
float mAmps = AmpsRMS;
Serial.print(AmpsRMS);
Serial.print(" A");
Serial.print(", ");
Serial.print(mAmps);
Serial.print(" A");
Serial.print(", ");
Serial.print( mAmps * 1000);
Serial.print(" mA");
Serial.println("");
delay(5000);
}
float getVPP()
{
float result;
int readValue; //value read from the sensor
int maxValue = 0; // store max value here
int minValue = 1024; // store min value here
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 maximum sensor value*/
minValue = readValue;
}
}
// Subtract min from max
result = ((maxValue - minValue) * 5)/1024.0;
return result;
}
The code outputs under no load:
0.09 A, 0.09 A, 86.32 mA
0.01
0.05 A, 0.05 A, 51.79 mA
0.02
0.07 A, 0.07 A, 69.05 mA
0.02
0.07 A, 0.07 A, 69.05 mA
0.02
0.07 A, 0.07 A, 69.05 mA
0.02
0.09 A, 0.09 A, 86.32 mA
Not sure why I am getting such a high current in both the code. Does anyone have any idea how to make the ACS712 (20A) work precisely? I have tried multiple codes and never received promising results.
Help would be appreciated.
Thanks.