Closed 369Martin369 closed 11 months ago
What value of resistors are you using for the voltage divider? As I'm sure you've heard...the ESP32 ADC is atrocious. If ADC is critical to your design might I suggest a discrete ADC? Like the Adafruit ADS1115 16-Bit ADC that communicates over i2c.
Dont bother with the ESP built in ADC. Its one of the worst out of all MCU's (NRF,STM,Atmegas). You should not expect better accuracy than +-50mV.
If you need high accuracy, use external ADC chip. For most projects I use ADS7828. I can get down to +-5mV accuracy with that one which is more than accurate for most projects
I tried working with the reference voltage on the LILYGO T-Display-S3 LCD along with the LM4040. I tried using a diode in both directions. I came to the conclusion that the external reference pin was always connected somehow, and I could measure current flow going in both directions. I gave up using an external reference, and instead used a hard coded value (const float referenceVoltageConst = 3.2804;). Using my own voltage divider (20K & 5K resistors), I could measure somewhat decent voltage values of hybrid battery modules (up to 9.0 volts, etc.). Also, I don't think the LM4040 was providing a voltage of 4.096 like it should have either.
What pin is the reference voltage? I am interested in what you are trying to do!
Oops... I was referring to the AREF pin on the Arduino boards. The LILYGO T-Display-S3 does not have an AREF pin. I worked on this 14 months ago and forgot that I switched to using the LILYGO T-Display-S3 LCD. Back then, I was using the Arduino NANO, which today I confirmed only supports an internal reference voltage, which explains what I experienced with the NANO board. https://support.arduino.cc/hc/en-us/articles/360018922239-About-the-AREF-pin Other Arduino boards do support an external AREF. Still, on the T-Display-S3 board, I find it beneficial to hard code the reference voltage to something like 3.2804. Every 10 seconds, my project tracks the voltage and amps of a single Panasonic Hybrid car module with the load of a single headlight (about 3.5 amps), and the battery voltage is usually between 6.9 and 8.40 volts. I use a voltage divider of 20K & 4K resistors which lets me track the voltage up to 13.2 volts (3.3 volts * 4). I use an ACS712 5A Hall Effect Current Sensor Modules to track up to 5 amps. I supply the ACS712 with 3.3v and measure the 3.3v analog value (using a hard coded voltage of 3.2804v) and 12 bits of ADC accuracy (4,096 values). The ACS712 module provides a voltage which you then convert to amps using a formula. I find that I need to keep this sensor away from other wires to get consistent values. I use it to captures amps, but use my voltage divider (20K & 5K) to capture voltage. I am thinking of using your suggestion to use the ADS1115 16-Bit ADC to capture more accurate ADC values. Here is my code for capturing ACS712 amp values. I floats and doubles in the calculations, which returns more refined results.
const float AnalogToDigitalResolution = 4096.0; // 10-Bits = 1024, 12-Bits = 4096 const float referenceVoltageConst = 3.2804; // 3.2804 3.28 3.38555 3.3888 const float ACS712_scale_factor = 0.181; // ACS712 5A current sensor 0.185 double ACS712_zeroPoint = referenceVoltageConst / 2.0; // The sensor voltage is 3.3 Volts, the ADC is 3.28 volts double resADC = referenceVoltageConst / AnalogToDigitalResolution;
double readAmperage(int analogPin) { int sampleSize = 100; long analogValue = 0; double avgAnalogValue = 0.0; double ACS712_Voltage = 0.0; double ACS712_Current = 0.0; float voltageDifference = 0.0;
for (int i=0; i < sampleSize; i++) { analogValue += analogRead(analogPin); delay(1); } avgAnalogValue = analogValue / float(sampleSize); // calculate avg analog value
ACS712_Voltage = avgAnalogValue * resADC; // convert analog value to voltage
voltageDifference = ACS712_Voltage - ACS712_zeroPoint; // report both negative amps and positive amps as positive values if (voltageDifference < 0.0) voltageDifference = voltageDifference * -1.0; // convert negative amp flow to positive amp flow
// Convert ACS712_Voltage into Current using Scale Factor ACS712_Current = voltageDifference / ACS712_scale_factor * 2.0; ACS712_Current -= 0.25; // fudge to zero when no current if (ACS712_Current < 0.0) { ACS712_Current = 0.0; }
return (ACS712_Current); }
Thanks for getting back. Cool project, the ADS1115 is well respected. -Terry
Hi, for a project I use now the built in ESP ADC. But I'm disappointed about its stability. Even with 1000 multisamples and dismissing 80% of extreme values, it is unstable as hell!
=> Seems that the reference voltage is not stable at all and flickers heavily depending on CPU load. A 100nF capacity from ADC Pin to Ground did not solve problem, so it must be therefore the reference voltage.
Can you give me hints where I can solder add'l 10uF and 100nF to stabilize ref voltage? Any schematics to offer??
Thanks a lot!