3

I'm trying to measure current with acs712 30A current sensor connecting to NodeMCU-32S but I'm getting wrong and unstable values. For zero current the ADC pin should read value of 2048 (esp has 12 bit sensitivity) but instead I'm getting values about 2740-2760. So first I have problem with incorrect value and second is unstable reading. Basically the whole thing look like:

schematic

simulate this circuit – Schematic created using CircuitLab

My test code is:

enter dcode here

#include <stdint.h>
#include "esp_err.h"
#include "driver/adc.h"
const int analogIn = 34;
int mVperAmp = 66; // 66 mV/A output sensitivity
int RawValue= 0;
int ACSoffset = 5500/2; 
double Voltage = 0;
double Amps = 0;

void setup(){ 
  Serial.begin(115200);
  pinMode(analogIn, INPUT);
}

void loop(){
  RawValue = analogRead(analogIn); 
  Voltage = (RawValue / 4096.0) * 5000; // Gets you mV
  Amps = ((Voltage - ACSoffset) / mVperAmp);
  Serial.print("Raw Value = " ); // shows pre-scaled value 
  Serial.print(RawValue); 
  Serial.print("\t mV = "); // shows the voltage measured 
  Serial.print(Voltage,3); 
  Serial.print("\t Amps = "); 
  Serial.println(Amps,3); 
  delay(250); 
}

Thanks.

Electrician
  • 81
  • 1
  • 3
  • 6
  • How's your PCB layout? It looks like you're just getting noise. – Hearth Feb 13 '19 at 14:20
  • I don't have PCB layout. It's all connecting with wires. – Electrician Feb 13 '19 at 14:23
  • Well, there's your problem then. At least the unstable readout. If it's all just wired together I'm surprised you're getting only 20 counts variation. The offset is a different problem; these sensors are sensitive to magnetic fields, so that could be affecting it? – Hearth Feb 13 '19 at 14:26
  • I saw lot of guides show how to use acs712 and getting good results just with simple wires. Just want to test the issue before layout. I think it's something else beside the wires. Maybe need to calibrate esp pins or put a capacitor. Not sure yet, that's why I'm asking. – Electrician Feb 13 '19 at 14:30

3 Answers3

4

The ESP32 runs with a supply voltage of 3.3V. That's also the reference voltage for analog inputs.

The ACS712 requires 5V as Vcc and outputs 0.5 x Vcc at 0 A (no current), i.e. 2.5V. For the ESP32, that's 2.5V / 3.3V x 4093 units = 2703. So your measurement is not that far off.

Note however, the for higher currents the ACS712 will output a voltage of more than 3.3V. You won't be able to correctly read them as the ESP32 tops out.

To increase the accurracy, you probably need to improve several things:

  • Measure the ESP32 reference voltage and correct your readings accordingly (calibration)
  • Measure the ACS712 output voltage and correct your readings (calibration)
  • Add the capacitor as proposed by the ACS712 data sheet
  • Add the capacitor as proposed by the ESP32 data sheet
  • Improve the wiring to reduce noise
  • Use multi-sampling (i.e. use an average of several consecutive readings)

Update

The ESP-IDF programming guide contains a page about the Analog to Digital Converter with several ways to improve the accuracy. It will help to understand the overall architecture of the ESP32's ADC. And even though it's for the ESP-IDF environment, most of it should also work with the Arduino environment.

Codo
  • 2,038
  • 8
  • 14
  • +1; I had guessed something about voltage differences, but since the schematic had 5V coming from the ESP32 I assumed they were running on the same voltage. – Hearth Feb 13 '19 at 14:58
  • Well thanks for your reply. But it's 4096 units, and 2.5V / 3.3V x 4096 units = 3103. So the measurement is pretty far from the expected. It is make sense to calibrate manually with about 350 units to get the expected value? – Electrician Feb 15 '19 at 13:40
  • Indeed, my calculation is off. (Yours is almost correct: even though there are 4096 units, the maximum value is 4095. So you must multiply with 4095.) 350 units is indeed a lot and probably caused by several factors. Unfortunately, your design depends on the accurracy of the 5V supply, the ESP32's internal voltage reference, possibly the 3.3V voltage regular etc. Use a multimeter to measure the relevant voltages. Possibly there is some additional issue in the circuit. – Codo Feb 15 '19 at 14:07
  • 1
    The tolerances of the 5V supply and the 3.3Vref are not the main problem. The issue is the non-linearity of ESP32. Even if I'll calibrate it manually by adding some units to the analogRead reasult, it's won't be correct for different levels of voltage read by ADC. Couldn't find proper solution to the ADC non-linearity problem of ESP32. – Electrician Mar 26 '19 at 19:30
1

ESP32 has 12bit ADC, which has a resolution of 4095/3.3v. Now the best way to make ACS712 work with ESP32 is to supply the ACS712 with 3.3v pin of ESP32. You can also use 5v but you have to be very careful, as it can damage your ESP. I will explain how to do it both ways.

I'm getting values about 2740-2760.

Well this is a problem with your ACS712 module. Non-genuine modules tend to give values lower than Vcc/2. This makes things harder because you have to carefully calibrate the module to get accurate readings.

First Step would be to read zero current voltage of your ACS712 module. You can do that using Serial.println(analogRead(A0)*(3.3/4095)); and reading voltage values from serial monitor. This voltage should be 1.65 or 2.5v depending upon the power supply you are using. Or it could be lower, 1.52 or 2.21, as in your case. Lets call this value BaseVol

2nd Step Write your code

void setup()
{
  pinMode(A0, INPUT);
  Serial.begin(9600);
}
void loop()
{
  float ACSValue = 0.0, Samples = 0.0, AvgACS = 0.0, BaseVol = 1.52; //Change BaseVol as per your reading in the first step.
  for (int x = 0; x < 500; x++) { //This would take 500 Samples
    ACSValue = analogRead(A0);
    Samples = Samples + ACSValue;
    delay (3);
  }
  AvgACS = Samples/500;
  Serial.println((((AvgACS) * (3.3 / 4095.0)) - BaseVol ) / 0.066 ); //0.066V = 66mVol. This is sensitivity of your ACS module.
}

Now this should give you reading of upto 0.1A accuracy, and your zero voltage will not fluctuate.

Now if you are using 5v Vcc, you will not be able to measure more than 12 amps, because at 12 amps your voltage will be 3.3v and if you go higher, wou wil fry your ESP32. The solution to this problem is using reverse polarity. This way, you would be able to measure between -12 and +30 amps (ACS712 can measure from -30 to +30 with voltage 0.5 to 4.5). Just make sure you check the polarity first.

John Wick
  • 11
  • 1
0

I had a similar problem. I found it was the supply voltage not being exactly 3.3V, so the reference centre point moved around, thus changing the perceived current. My solution was to programatically turn off the current and read the reference point for comparison when switched on again. I do this once every few seconds. The other part of the problem, the non-linearity of the adc is best addressed using a lookup table which is created by running another bit of code ramping up the voltage and reading the adc to create the table and then pasting the output into the code. I'm trying to find if I can use a zener instead of the constant re-reading of the reference voltage, which is how I ended up here.