I use ESP32 and ACS712 5A, but the readings I get are fluctuating and inaccurate... here is the program I use. please help me where is the mistake. Thank You
#define def_frequency 50
uint16_t adc = 4095;
uint16_t cycle = 1;
uint8_t ACSpin = 32;
uint8_t noisemV = 21;
int midPoint;
float ACS_resolution = 185.0;
float maxVolt = 3.30;
float formFactor = (1.0 / sqrt(2));
float mVperStep;
float mAperStep;
bool suppresNoise = false;
void setup() {
Serial.begin(115200);
delay(100);
ACS712_init(maxVolt, adc, ACS_resolution);
autoMidpoint(def_frequency, cycle);
Serial.println("ACS Ready.....");
delay(2000);
}
void loop() {
float average = 0;
uint32_t start_time = millis();
for (int i = 0; i < 100; i++) {
average += readACS(def_frequency,cycle);
}
float mA = average / 100.0;
float mAmps = mA - 130.0;
uint32_t duration = millis() - start_time;
Serial.print("Time: ");
Serial.print(duration);
Serial.print(" mA: ");
Serial.println(mAmps);
delay(1000);
}
void ACS712_init(float volts, uint16_t maxADC, float mVperAmpere) {
// set in setADC()
// keep it here until after experimental.
mVperStep = 1000.0 * volts / maxADC; // 1x 1000 for V -> mV
mAperStep = 1000.0 * mVperStep / mVperAmpere;
midPoint = maxADC / 2;
}
uint16_t autoMidpoint(float frequency, uint16_t cycles) {
uint16_t twoPeriods = round(2000000UL / frequency);
if (cycles == 0) cycles = 1;
uint32_t total = 0;
for (uint16_t i = 0; i < cycles; i++)
{
uint32_t subTotal = 0;
uint32_t samples = 0;
uint32_t time_start = micros();
while (micros() - time_start < twoPeriods)
{
uint16_t reading = analogRead(ACSpin);
subTotal += reading;
samples++;
// Delaying prevents overflow
// since we'll perform a maximum of 40,000 reads @ 50 Hz.
delayMicroseconds(1);
}
total += (subTotal / samples);
}
midPoint = (total + (cycles / 2)) / cycles; // rounding.
return midPoint;
}
float readACS(float frequency, uint16_t cycles) {
uint16_t period = round(1000000UL / frequency);
if (cycles == 0) cycles = 1;
float sum = 0;
// remove float operation from loop.
uint16_t zeroLevel = round(noisemV / mVperStep);
for (uint16_t i = 0; i < cycles; i++)
{
uint16_t samples = 0;
uint16_t zeros = 0;
int minimum, maximum;
minimum = maximum = analogRead(ACSpin);
// find minimum and maximum and count the zero-level "percentage"
uint32_t time_start = micros();
while (micros() - time_start < period) // UNO ~180 samples...
{
samples++;
int adc_value = analogRead(ACSpin);
if (suppresNoise) // average 2 samples.
{
adc_value = (adc_value + analogRead(ACSpin)) / 2;
}
// determine extremes
if (adc_value < minimum) minimum = adc_value;
else if (adc_value > maximum) maximum = adc_value;
// count zeros
if (abs(adc_value - midPoint) <= zeroLevel ) zeros++;
}
int peak2peak = maximum - minimum;
// automatic determine _formFactor / crest factor
float D = 0;
float FF = 0;
if (zeros > samples * 0.025) // more than 2% zero's
{
D = 1.0 - (1.0 * zeros) / samples; // % SAMPLES NONE ZERO
FF = sqrt(D) * formFactor; // ASSUME NON ZERO PART ~ SINUS
}
else // # zeros is small => D --> 1 --> sqrt(D) --> 1
{
FF = formFactor;
}
// value could be partially pre-calculated: C = 1000.0 * 0.5 * _mVperStep / _mVperAmpere;
// return 1000.0 * 0.5 * peak2peak * _mVperStep * _formFactor / _mVperAmpere);
sum += peak2peak * FF;
}
float mA = 0.5 * sum * mAperStep;
if (cycles > 1) mA /= cycles;
return mA;
}
yes, I know that.. esp32 has 3.3V A/D
in the acs712 datasheet, it has a zero value of 2.5 volts, can I manipulate the program in the esp32 to still be able to read the acs712?
the current that I read is not up to 2A, in the datasheet the acs712 5A has a linearity of 185mV, if what I read is a maximum of 2A, it means that the analog reading of the esp32 is a maximum of 2.87 Volts... is there something wrong with my understanding? please correct, thank you
i was supply the ACS from Hi-Link power supply 220 VAC to 5 VDC, so supply in ACS not from usb pin of the ESP
but result still fluctuative and inaccurate if compare with ampere meter
It will be inaccurate untill you calibrate everything but there should not be any fluctuations if the sensor is wired correctly and you set up your code correctly.
Did you try the ACS712_20_AC_average.ino example?
Yes, I've tried it, but it's still fluctuating with quite a large error
is the current I read too small? When the power is off, my ammeter reads 12mA, and when it's on it's 253mA. whereas in this ACS library program, when the power is off it fluctuates from 0 - 77 mA
This is the PCB in my project. the load is a 12V led strip. So at the end there is a 12V 5A power supply which is used to supply the LED, I control the RGBW LED with PWM via the L298 driver, for controlling the RGBW LED there is no problem, the problem is only in the current reading. there are several sensors in it, namely ZMPT, ACS712, LDR, RTC and PIR
I use an ACS712 to measure the AC current, so the output will be on the power meter to estimate electricity costs.
isn't INA219/229 for DC current? sorry if my knowledge is lacking.
I use L298 because it needs 4 MOSFETs to control the red, green, blue and white led strip
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Can you please links to data/specs of the LED strip.