Voltage monitor of battery

wet-bag-coder
Posts: 6
Joined: Wed Jan 13, 2021 5:05 pm

Voltage monitor of battery

Postby wet-bag-coder » Wed Jan 13, 2021 5:41 pm

So, I've read a ton of forum posts here and elsewhere - I get the non-linearity of the ADC, at below 0.5v and above 2.5v.
I know about the attenuation, etc.

But the voltages I'm reading from the ADCs are just wrong - and don't fit any of the details I've read about. I assume I *must* be doing something wrong, but for the life of me, I'm not sure what.

I'm using a cheap ESP32 D1 Mini board. It works for the other stuff I've tinkered with. I don't think it's a board problem.

Here's a sample of how I'm reading voltage. (The end intent is to monitor an 18650 - I know I'll need a voltage divider - and I've got that handled. However, I'm currently using a 10K POT to check the voltages I get from the ADC against a Fluke 189 DMM to ensure accuracy, etc. The pot is fed from the 18650, and I'm generally measuring voltages from 1v - 2.5v - which should be the sweet-spot for the ESP - since the ADC should be highly linear here.)

I've also tinkered with several different pins. (ADC 2-6, and ADC's ADC1-5,6,7) All produce pretty similar readings.

Here are some readings I've gotten.

Code: Select all

DMM -  ADC  - ADC/DMM (in percent)
2.5063	2.59		103.34%
2.4042	2.46		102.32%
2.299	2.35		102.22%
2.201	2.24		101.77%
2.1055	2.13		101.16%
2.0029	2.02		100.85%
1.9025	1.92		100.92%
1.8017	1.81		100.46%
1.7052	1.7		99.70%
1.6009	1.59		99.32%
1.5031	1.49		99.13%
1.403	1.37		97.65%
1.3009	1.27		97.62%
1.2076	1.17		96.89%
1.1061	1.06		95.83%
1.0059	0.95		94.44%
As you can see, the ADC doesn't match the DMM at all. At 1v, it's 0.0559v below the DMM, and at 2.5v, it's 0.0837 above. (This will be compounded when I use a voltage divider, since a 10K/10K divider will halve the voltage, so a 0.0837 error becomes an actual voltage error of 0.1674. And the total swing between 2.5v and 1v is 0.139v across that range - that's HUGE.

Some limitations.
I don't have a scope.
I don't know my DMM is accurate, but I have no reason to question it. It's also not a cheap POS, which makes me trust it.
I don't really know a lot about what I'm doing, so it's possible I'm making some stupid mistake.

Here's the "guts" of the code I'm using to read the ADC and calculate voltage.

Code: Select all

#define VOLTAGE_MON_PIN 14

analogSetAttenuation(ADC_11db);
//ADC_0db ADC_2_5db ADC_6db ADC_11db

adcAttachPin(VOLTAGE_MON_PIN);
analogReadResolution(12);
analogSetCycles(253);

avg_dig_voltage=0;

x=0;
//sample the ADC 20 times to get an average.
while (x<20)
	{
	cur_dig_voltage = analogRead(VOLTAGE_MON_PIN);
	avg_dig_voltage += cur_dig_voltage;
	x++;
	}
	
avg_dig_voltage= (avg_dig_voltage/20);

cur_voltage = ((3.3/4095)*cur_dig_voltage);
avg_voltage = ((3.3/4095)*avg_dig_voltage);

Serial.print("Current digital voltage level: ");
Serial.println(cur_dig_voltage);

Serial.print("Avg digital voltage level: ");
Serial.println(avg_dig_voltage);

Serial.print("Current Voltage: ");
Serial.println(cur_voltage);

Serial.print("Avg Voltage: ");
Serial.println(avg_voltage);
Any suggestions on what I'm doing wrong?

tommeyers
Posts: 132
Joined: Tue Apr 17, 2018 1:51 pm
Location: Santiago, Dominican Republic

Re: Voltage monitor of battery

Postby tommeyers » Wed Jan 13, 2021 10:51 pm

What is it you are measuring. 18650 planned. But what right now? A floating high?

I ask because i wonder what that signal looks like. It it is wiggling the two measurements could be different because of, for example, capacitance.

Thanks, tom
IT Professional, Maker
Santiago, Dominican Republic

wet-bag-coder
Posts: 6
Joined: Wed Jan 13, 2021 5:05 pm

Re: Voltage monitor of battery

Postby wet-bag-coder » Wed Jan 13, 2021 11:26 pm

I'm just using the raw non-voltage-divided 18650, but keeping the output range <3.3v.

18650 -- POT -- ESP

(If it was a fixed amount "off" in the whole range, I'd be happy.)

I also saw a post about measuring the ESP's own 3.3v output, with a voltage divider, and using it as an "adjust" reference.

With a 20k/20k divider, the ESP sees that as ~1815 (digital output) or 1.46-1.48v. The DMM shows it as 1.66v - which is _exactly_ where I'd expect it to be. [Multiple measurements on a single pin. 34, IIRC]

becorey
Posts: 65
Joined: Sat Mar 28, 2020 4:18 pm

Re: Voltage monitor of battery

Postby becorey » Thu Jan 14, 2021 3:17 pm

avg_voltage = ((3.3/4095)*avg_dig_voltage)
I think you need the vref from efuse, about 1.1V. You said it read 1.46 when you measured 1.6, that would explain the difference.

Also I think it should be 4096, 2^12, not 4095

wet-bag-coder
Posts: 6
Joined: Wed Jan 13, 2021 5:05 pm

Re: Voltage monitor of battery

Postby wet-bag-coder » Thu Jan 14, 2021 5:17 pm

I think you need the vref from efuse, about 1.1V. You said it read 1.46 when you measured 1.6, that would explain the difference.
Explain that to me, because it doesn't make any sense.

1) I thought efuse changed the voltage calibration, so that the output from the ADC's would be "corrected" when queried. (i.e. You'd get an accurate output from the ADC, not a wrong output that you'd have to manually/programmatically correct with the "adjustment" from efuse.)

2) As I understand efuse, it's a single point adjust. So, it can't correct the non-linearity, or the variable offset in the readings I've shown above, where the variance between the ADC and DMM readings is not constant.

So, I either really don't get what efuse is, or this doesn't solve any of the issues I'm seeing.

becorey
Posts: 65
Joined: Sat Mar 28, 2020 4:18 pm

Re: Voltage monitor of battery

Postby becorey » Fri Jan 15, 2021 12:55 am

Two point calibration will correct the offset and slope, thus you'll be more correct at both the low end and high end. Efuse vref can be single point or two point, obviously two point is a little better.
Two Point values represent each of the ADCs’ readings at 150 mV and 850 mV. To obtain more accurate calibration results these values should be measured by user and burned into eFuse BLOCK3.
https://docs.espressif.com/projects/esp ... s/adc.html

Try that TP calibration out first.
You're not seeing a non-linearity, you're seeing exactly a linearity. Your error goes from about +4% to -4% with a linear trend in-between. Non-linear would mean it can't be characterized with y=ax+b, requiring higher order terms x^2, x^3 etc.


When you measured 1815 from a 20K/20K resistor divider. If you take 1815/4096*3.3 = 1.46… the measurement looks wrong because your DMM says 1.66. Well 1.66/1.46= 1.14, I bet that is currently your efuse calibration value. It's typically 1.1 to 1.2 so it's right in the expected range.

*3.3 applies the attenuation, and *1.14 applies the vref. The measured digital value from 0-4096 represents a fraction of vref. That digital value does not "know" what vref is. So if you're looking to get an analog voltage value from your digital value, you need to multiply that fraction by the vref.
I think you're using arduino? You'd have to check how the adc read function is implemented, is it giving you just the digital value or is it also applying the calibration coefficients.

I'm not sure why your table of values is within -4% to +4%, but your single example of 20K/20K is 14% off.

wet-bag-coder
Posts: 6
Joined: Wed Jan 13, 2021 5:05 pm

Re: Voltage monitor of battery

Postby wet-bag-coder » Fri Jan 15, 2021 2:13 am

I guess, lets start over.

I've run the comparison of the ~1.66v output on three different esp32 boards.
The output is all quite close. 1.48/1.51/1.47.

Are all ESP boards this bad? I'd be more-or-less fine if they were a few hundredth's of a volt off. But 0.15v off? That's pretty bad, IMO.

I'm using the regular analog_read function on arduino - I can't tell if that uses the efuse value or not, but either way, it's not going to correct things. On the low voltage values it might get us close, but at 2.5v it's going to push things WAY WAY off.

So, lets just start here.
Are the ADC's on the ESP32 this bad, without individual calibration - where the voltage varies ~20% across the range from ~1-3v?
I've not seen any mentions of them being this bad. So I'm kind of surprised.

Anyone with first hand experience that matches mine?
I've done at least some of these measurements on three different esp32's (two mini's and one full-size dev TTGO board) and they are all pretty similar in their profile. I keep thinking I must be doing something wrong, but I can't see what.

becorey
Posts: 65
Joined: Sat Mar 28, 2020 4:18 pm

Re: Voltage monitor of battery

Postby becorey » Fri Jan 15, 2021 6:38 am

Read this post, it was published by espressif, you need to manually measure vref and then input it in your code as a calibration:

https://www.esp32.com/viewtopic.php?f=1 ... =20#p16166

The analog_read function is not applying calibration or anything. So if you use analog_read, you must convert it to voltage yourself applying the calibration.

Or you can use a different function like esp_adc_cal_raw_to_voltage(), that bundles in handling the conversion from digital value to analog voltage. But it's only accurate after first calling esp_adc_cal_get_characteristics() with the measured vref.

Either way, the calibration is critical for any kind of accuracy. You can't bypass the calibration then expect accuracy. It's a standard thing you need to deal with doing analog measurements, calibration is built into everything.

You're saying the output was 1.48/1.51/1.47 when the true value was 1.66, so it's off by 0.15v. But actually, it did not directly give you 1.48/1.51/1.47. It gave you a digital value which you then adjusted by value/4095*3.3. The error is coming in there when you multiply by 3.3, it's just not the right scaling factor.

wet-bag-coder
Posts: 6
Joined: Wed Jan 13, 2021 5:05 pm

Re: Voltage monitor of battery

Postby wet-bag-coder » Fri Jan 15, 2021 5:28 pm

1) That post is old. 2017.
Since then (sometime in 2018) as I understand it, Espressif started "calibrating" the ESP32, and putting in the calibration value in the Block 0 of efuse.
See: https://docs.espressif.com/projects/esp ... s/adc.html

The "default" 1100 (you keep harping about) should only be used if the 1-point block 0 calibration is missing AND there's no block 3, 2-point calibration. (Again see that adc reference above.)

2) I'm working on a product with mass distribution, and I simply can't do 2-point calibration on each esp32 - and it's nuts that it would be required to get the accuracy of an ADC (whos only purpose in life is to read voltages) to be more accurate than +/- 0.15v.

So, lets ask the question again, and this time, please answer the question I've asked. (If you want to put your oar in after answering the questions I've asked and offer material I've not asked for, that is fine. But I really want my question answered.)

Is it routine experience that the ESP is routinely 0.1v+ off when doing an analog read on an ADC, unless custom 2-point calibration is manually run?

Who is online

Users browsing this forum: Google [Bot] and 16 guests