D1 mini pro v2 battery voltage reading

Hi!

I building a project with a LOLIN Wemos D1 mini pro v2.0.0 and a 3.7v 18650 lithium battery (max 4.2v) .

AFAIK this version (v2) has a built-in voltage divider, so if I connect SJ1 (BAT-A0) I can read battery voltage directly into analog input (A0). My questions are:

  1. Is this true? without soldering any external resistor? All schematics I have seen on the Internet adds external resistors, but any of them use a D1 mini pro v2

  2. At the moment this is working while my D1 mini pro v2 is running on battery. I get 1023 when the battery is fully charged and lower values when the battery is been discharged. But... when I connect a charger into the USB port I always read 1023 (the max value possible into A0), even if the battery is only 2.5v. Therefor I can monitor battery discharge process but I can not monitor battery charging process. Any solution to this?

Lots of thanks

First let's do the math:
The divider is 1/3*2.
The divider is 1/3.

V+ 200K, 100K, Gnd.
Battery voltage: 4.2 V ADC pin voltage = 4.2 /3 = 1.4.

ESP8266 ADC can accept voltages in the range of 0V to 1V only, or you will damage the ADC pin.

The ADC pin of the ESP8266, (D1 processor), supports 0 to 1V.

So, you have to actually place an external resistor to reduce this value from 1.4V to 1V.

The value of this resistor should be 120K, giving the divisor:
V+ 120K, 200K, 100K, Gnd.

Thus the current through the divider will be 0.01 mA and the vote in the ESP8266 ADC will be 0.01 mA x 100K = 1V. = 1023
If there is 3V on the battery, the ADC value will be: 0.714 V ~= 730.

This is D1 schematic :
look voltage divider at upper right .

2 Likes

However, in the D1 mini pro documentation, is said that A0 supports 3.2v

https://www.wemos.cc/en/latest/d1/d1_mini_pro.html

This is specs for D1, not for ESP8266.

D1 A0 pin = 3.2 V/ (220K + 100K) = 0,010700 mA.
0,010700 mA * 100K ~= 1V (at ESP8266 ADC pin).

" Analog input

The ESP8266 has a single analog input, with an input range of 0 - 1.0V. If you supply 3.3V, for example, you will damage the chip. Some boards like the NodeMCU have an on-board resistive voltage divider, to get an easier 0 - 3.3V range. You could also just use a trimpot as a voltage divider. "

Ref: A Beginner's Guide to the ESP8266

" As maximum voltage input is expected to be 1V only and because our Li-ion Cell fully charged voltage goes up to 4.2-4.3V it’s obviously that we need to find a way to “translate” the voltage domain between 0-4.3V to 0-1V. They are many different techniques available for doing that but the easiest one and the one that we will use here is the Resistive Voltage Divider (RVD)."

Ref: Internal ADC – ESP8266

1 Like

Thanks for the wonderful explanation @ruilviana. I understand perfectly what you have told me about ESP8266. Definitely ESP8266 support max 1.0v at ADC.

However I do not understand why D1 says it support 3.2v max in its A0 pin. Moreover D1 has a solder jumper (BAT-A0) which is dedicated to get battery voltage at A0. Should not it include all the electronics (resistor) if it is so easy connect battery voltage to A0?

I have solder that jumper (BAT-A0) and when battery is fully charged (4.2v) I get ~3.0v at A0 pin of the D1 mini pro, and analogRead(A0) gives me 1023.
When battery voltage is 3.23v pin A0 is receiving 2.10v and analogRead(A0) gives me 673. It looks it is working well, isn`t it? or Am I damaging my board applying 3v at D1 mini pro A0 pin?

If I apply 1.0v using a 120K resistor I will never get analogRead(A0) = 1023, isn't?

I know I am missed at some point, but I do not know where.

Lots of thanks

Okay, I'll explain it another way.

I don't know what your level of knowledge of basic electricity is.
To understand what I'm going to describe, you need to at least know Ohm's law and resistors in series.

E(V) = R(ohms) * I(Amp) OHM's Law
RT = R1 + R2 + R3. Resistors in series

Therefore, when the D1 manual says that the maximum voltage on pin A0 is 3.2 V (It should be 3V, but the difference will be within the tolerance of the ESP8266), it means that on the ADC pin of the ESP, you will have a maximum of 1 .07V.

Let's do the math:
D1 internally has a resistive divider with 2 resistors in series of 200K and 100K, totaling 300K.
The 100K resistor goes between ADC and GND.
When connecting 3V to A0, 0.000010 A will pass through this series circuit.

By Ohm's law, we will have on the 100K resistor:
V = R1 * I = 100,000 * 0.000010 = 1V.
So in ADC we will have 1V, the correct value for the ESP8266 ADC.

If you connect a 4.2 V battery to A0, then a current of 4.2/300000 = 0.000014 mA will pass through the divider.

Again using Ohm's law, we will have a 100K resistor:
V = R1 * I = 100,000 * 0.000014 = 1.4V.
So in ADC we will have 1.4V, an incorrect value for the ESP8266 ADC.

But if you add an additional 120K resistor to the circuit,
it will have 420K and if you connect a 4.2 V battery to the end of this resistor, then a current of 4.2/420000 = 0.000010 mA will pass through the new divider.

Again using Ohm's law, we will have a 100K resistor:
V = R1 * I = 100,000 * 0.000010 = 1.0V.
So in ADC we will have 1.0V, the correct value for the ESP8266 ADC.

Now let's talk about the ESP ADC values in 10-bit resolution.

If you connect a 4.2V battery and do not use the additional 120K resistor, when the battery is fully charged, the voltage at the ADC pin of the ESP will be 1.4V (Incorrect value for the pin), but if it does not burn the ESP8266, the ADC reading will be 1023.
The reading will only be below 1023, when the value on the ADC pin is less than 1V, that is, in this situation when the battery has 3V, and the ADC value will be 1023.
From this battery value to zero, the value will be the ratio of 1/1023 = 0.002932551 for each decrease in the ADC value.
But the reading will be technically wrong.

But if you use the divider with the additional 120K resistor, then, when connecting a 4.2V battery to the end of this resistor, you will have 3V on the A0 pin, and 1V on the ADC pin and the ADC will have the value of 1023.
So when the battery, for example, has 3.6 V, in A0 you will have
2.5714 V and the ADC will have 0.8571 V, showing an ADC = 876.

Attached drawing for better understanding.

image

1 Like

Another perfect explanation @ruilviana
I have understood perfectly what you mean.

However I have a doubt yet.

I have to double check it, but I think that analogRead(A0) gives me 1023 when battery is at ~4.20v and it goes down inmediately. It gives me ~980 when battery is ~3.9v. I mean I do not have to wait until 3.0v to get values below 1023.

EDIT: Double checked
Battery voltage 4.20v gives me analogRead(A0) = 975
Battery voltage 3.90v gives me analogRead(A0) = 848
Battery voltage 3.53v gives me analogRead(A0) = 775

So I think I am not applying more than 1v into ADC, even when battery is 4.2v, isn`t it?

Could it be that connecting BAT-A0 solder pad will add a third resistor?

Perhaps I could read voltage on ESP8266 ADC pin directly with a polymeter when battery is at 4.2v, but its pins are so tiny...

LOLIN Wemos D1 mini pro V2.0.0 schematic

In the schematic, Doesn't R17 (130K) do the function of the 120K @ruilvania proposed?

Why not just measure the voltage with DMM?
Anyway, I`m looking into D1 mini schematic, ADC connection is routed to pin 6.
So, if you want to measure VBAT, you have to short SJ1 jumper and than you have 350K / 100K attenuator, or this :
D1 mini attenuator
You can see voltages at different nodes, and with max Vbat voltage of 4.2V you have 933.3mV at ADC pin so everything is ok.
Btw , to make things easier, you could try analogReadMillivolts() function and compare the result with the values you measured with DMM.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.