Dan, the only way to truly get a capacity value is to monitor both voltage and load currents, but using voltage only does give a very good estimation u set most load conditions, I hope you find it useful. I gave up using s simple voltage measurement and straight/line estimate as I knew the results were wrong, now I get a much better value.
Hi Dave, very good to describe the discharge curve of the LiPo as 'non-linear' and its a good tool to estimate remaining capacity. However, it is load-dependent. More importantly, this method should never be used to determine when a battery is full - LiPo must always be charged in accordance with the manufacturer's recommendations (normally CC/CV).
Indeed, but this is principally for use with a micro-controller where loads are low. For my drones and Rx fixed wing aircraft and radios I’ve been using LiPo’s for about 10-years now and I agree there are few around who fully understand the charging regimes that need to be applied especially Boeing and their 787’s that caught on fire when someone thought they could replace a NiMh with a LiPo without changing the charging methods. For most development boards on the market they have a reasonable battery charger-management chip the TP4054 which is widely used to keep the batteries in good shape so most users of these devices will be well protected.
@@G6EJD Yes - lol even the 'big' boys screw it up. I was just wanting to flag up that its important to follow the charging guidelines before someone decides to change your code into a battery charger :)
@@G6EJD do you have any more information on why the batteries caught fire? I have converted an old cleaning robot to LiIon batteries and included a BMS/ protection board which cuts out a little earlier than the full charge voltage of the previously used NiMH Batteries.
I’m not sure if we’ll ever know the real reason why Boeing’s batteries caught fire, but my intuition is they did not understand the (then) novel use of LiPo batteries as a replacement/upgrade and the need for extensive battery monitoring. I can proudly say of all my 70+ high capacity LiPo’s I’ve never had a failure typically in the form of puffing (swollen) packs due to overheating during charge and discharge or over/charge. You must charge at constant voltage and not constant current but a constant current charger is perfectly ok if you employ good charge monitoring circuitry to check for over voltage or heating. At the lower end where the battery becomes depleted say to 3.2v when it can become chemically damaged is when most damage is caused, and then when charging recommences a chemically damaged cell can become excessively hot as it’s internal resistance rises as a result of the damage. It’s like John was pointing out, these batteries need careful handling during both charge and discharge but correctly implemented(Apple have this almost perfectly so in their products) the battery will be safe and last a long time. I hope this helps. Sounds like you’ve done the right thing in your installation.
When using higher-order polynomials, the precision of coefficients can potentially adversely affect the result. Is there an easy way to check that the rounding errors in your floating-point-arithmetic do not misrepresent the polynomial? For example - at 4:00 what does the coefficient "2808.3808" actually compile to? Is this enough?
On all the implementations (Arduino UNO, ESP8266 or ESP32) a 'float' is 4-bytes and can represent the values in the polynomial.In testing the results are as expected.If there was any doubt the data type could be changed to 'double' however on the UNO there is no difference between double and float. I'll test it now: Serial.begin(115200); float test = 2808.3808; Serial.println(test,6); Result:2808.380859 So it's maintaining the 4-places of precision adequately, but adding some lower order artefacts too, but as these are relatively small, there is little effect on the result.Good question, thanks.
So just to check I understand this, if using a Lipo on a lolin type board (with integrated lipo socket), the measurement is actually taken usning an internal ADC (despite referncing pin 35) and this will allow me to monitor voltage without any additional circutry? Thanks. (At about 3.45 on your video)
Yes OST boards have an on-board voltage divider which has a /2 ratio enabling 0-6v to be measured, actually 6.6v depending on linearity required. The Junction of the voltage divider is connected to pin 35, could be any pin in the ADC pin range and yes you can monitor battery voltage.
@@G6EJD I've hooked up a Lipo and tried running your code, but I'm not getting anything by reading pin 35. I have also tried substiuting several other pins, but to no avail. I did run a loop changing the pin number on every iteration and the first time round, pin 15 looked promising with 4+ volts showing (The lipo was charging via the USB connection), but since then, I only get a reading of 0.77v. Any ideas?
There are genuine Lolin D32 boards and fake Lolin 32 boards die it have a white silk screen LOLIN D32 label on it. If not it’s a fake and no on-board voltage divider and monitor is fitted. If a genuine board there must be a battery supply fitted to the batter SH terminal and it will use pin-35 in common with most other boards fitted with an on-board monitor. Where did you buy it from?
I am having trouble getting this to work on my lo lin 32 with the battery charge option. I think I am miss understanding the circut not the program or the math . when I plug in the battery should I get voltage directly between pin 35 and ground . I get 0 voltage I have 3.3 at the 3.3 pin so the battery is connected and I have charged the battery up thorough the board but cannot get any reading out of pin 35 through a meter or through the program. thanks Jim
Some boards don’t use pin 35 or more usually have no connection at all an you would need to make a wired connection between the battery + and a voltage divider and the chosen ADC input pin.
Hi Dave, I'm working on a project using Esp 32 and 3x18650 battery in series(12.6v) with a voltage divider to 3.3v for ADC. How can I calibrate it? 12.6 will be the 100% and 10.5 the 0% or i have to adjust the calibration value to 4.20 - 100% and 3.50 - 0%? Thank you in advance for your time and for the good job as well :)
Every ESP32 has a different ADC response depending on its reference voltage. This is why they need to be adjusted and compensated for. The voltage divider only improves range.
Would it be better to map the voltage to the percentage in an array and then estimate by aproximation? It could be faster i think. Great tutorial! Could you make a video on how to create a polynomial to use in projects? keep the good work
The advantage, if any would be marginal, as getting a battery capacity value need not be done in near real time and I expect it takes no more than a few masers to calculate the result. Creating a polynomial is a skill that has to be learnt and requires a high level of mathematics knowledge there are already a few videos and tutorials around that explain the process one very good one is Australian and comes up through a google search.
hi David, you really did a great job determining the polynomial function. I tried to do the same thing because I want to use 3.1V for 0% but without result .... my curve remains crooked !! Can you calculate me the function for 100% at 4.2v and 0% 3.1v
I can do, I use the tabular method. But with a standard voltage regulator with excellent drop-out specification do you think your ESP32 will still run reliably? 3.1 volts infers an output voltage of 3.0 or less, it will take me a while to do the maths, but watch this space!
Try this,, but I think battery voltage is going to fall away very quickly: y = -0.00000000001912x6 + 0.00000000451735x5 - 0.00000039128959x4 + 0.00001345348277x3 + 0.00002191577616x2 - 0.01698649053242x + 4.19959893330281
@@G6EJD Thank you very much David for this function, but it is to calculate the voltage according to the percentage so without abusing, is it possible to have reciprocity?
@@brunodelort3337 You can just multiply the % value by the chosen voltage range, for example 0-100% = 0 - 3.3v so % / 100 * voltage or for example at 50% = 50/100*3.3 achieves the same result as a new polynomial based on a 0-3.3 y scale.
The ADC is significantly non-linear between 0 and 0.6v and then 3 to 3.3v, which is why I chose s polynomial to follow the ADC response curve, a simple linear interpolation would not give acceptable results outside of the region 0.6 to 3 volts, however within that range the ADC is actually very linear.
Hey friend nice video! wondering if we could use 2 * 1 million ohms resistors instead 2 * 100K ohms? i need the lowest power consumption on my project.
You can but then that limits the input current to the ADC and results in noisy / variable readings, if you don’t need to take readings quickly you can add a 1.0uF capacitor across the ADC input and Ground to smooth the readings, but it will introduce a delay of 1-sec in reacting to change, you could try lowering the capacitor values to suit your application.
Great Video David, many thanks. I'm not getting the results expected. Using a Wemos D1, with the 100k in line. Looking at your code in the video you have float voltage = analogRead(A0) / 1023.0 * 4.24; and on github you have float voltage = analogRead(A0) / 4096.0 * 4.24; I'm guessing it should be the first one. I was pointed to this video as I was having issues getting correct readings, and with your code I'm still getting odd readings, they don't match. EG my the battery shows 3.42v on a meter, but the code is showing 3.63v. Any ideas? Thanks
Brian, the ESP ADC’s are variable as are the voltage dividers, so as you have surmised the / 1023 code line is correct for the 10-but ESP8266. Next adjust/calibrate your reading on the serial port by adjusting the multiplier 4.24 if too low compared with your meter increase it or too high decrease it.
Hello, nice work there. Thanks for the explanation. I have a question. How do you measure battery if you use 18650 battery shield? What probe do you use to connect to the voltage divider? Thanks.
You have to do the same as any other battery measurement and add a voltage divider if one isn’t fitted to the board, then wire it’s (divider) input to the battery + terminal there’s no other way of doing it, not neat but it’s the only way. It would be unlikely for the battery shield to have a Vbat terminal
@@G6EJD Im on the LOLIN LITE, and running it off a 18650 like above, can I solder a jumper strait from the positive terminal to pin 35 to get my voltage reading? do i need the 100k resister?
@@photobusta the ADC input maximum voltage is 3.3v, so you must fit a voltage divider to reduce the voltage say Vin--100K--ADC Pin--100K---Gnd then when you take your measurement it needs to be multiplied by 2 for the correct value
Yes, Li-ion 18650 3.8v nominal battery type, but could be modified for others. It’s meant for the Lolin D32 and others on-board battery input. I have not seen any other battery used.
Gracias, excelente video. Estuve buscando está información desde hace tiempo, solo me queda una duda. Tengo un D1 Mini ESP32 , por qué medios cargara la batería? Por la alimentación USB ?
I use WEMOS LOLIN32 V1.0.0 with a 3.7v polymer battery without resistors, I have used your code but the battery indicator only continues to show 100%, do you have a solution..thanks before.
The Wemos lolin32 v1 does not have an on board voltage divider it was a copy board. See my tn143 to see how to add a voltage divider, you’d need to use 2 x 470K resistors
@@G6EJD Hello, I make a project into school and I need to indicate when is battery low. I have also WEMOS LOLIN32 V1.0.0 so without an on board voltage divider. I do not know how to right connect the battery. Can I use built-in JST-PH-2 conector for battery power and still be able to put there a voltage divider and measure the power? Thank You for Your Response.
Is there a Vbat pin on that board? To measure voltage you will need to use a voltage divider made of two resistors of the same value. Wired like this Battery + terminal or Vbat pin, - - - - R1- - - - ADC pin - - - - - R2- - - Gnd R1 and R2 can be any two equal values say 100K is each or 470K or 220K or whatever even 1K but they will discharge the battery quickly if too low a value. Read the voltage with the standard ADC read function. If you use pin 36 then float voltage = readAnalog(36) / 4095.0 * 6.566;
Yes there is, knee voltage is 3.0 volts, I could produce a LifePO4 equation if you need it? But I’d need to know the absolute lower voltage, fully charged they are 3.6v and then discharged approximately 3.0, if needed let me know.
percentage=4984.6172x3 - 48287.7528x2 + 155490.3329x - 166375.8607 where x is measured voltage for a LifePO4 and assumes higher end of 3.4v and lower end 3.0v
Very useful explanation and I'm going to use this method in my project. I actually use 2s LiPo 18650 batteries to supply Arduino nano. What would be the calibration coefficient in this case. Please advise.
If your doubling the input voltage then reduce the multiplication factor by 2 by increasing the first series resistor by 2 otherwise the input voltage will exceed the ESP32 ADC capability
Hi thanks for the vidéo ;) I like it ! one question remains : if you mesure the battery under load what happens ? if the load is big ? if the load is small ? If the load is big i presume the voltage will drop, so your solution is not suitable for any device that uses power of the same battery that it mesures. Can you confirm that ? Thanks for the great explaination of polynomial curves again !
The ADC measures the literal voltage just like a DVM would do, so whether on light or heavy load the voltage measured is that across the battery. The on-board regulator has a drop out voltage of about 0.1v and the ESP32 stops working at about 2.8v so when the battery voltage reaches 2.9v the ESP32 will stop working.
ESP32 ADC mathematical corrections are great, but pow calculation on MCUs take just too many CPU cycles. Better way how to calculates polynomials is Horner algorithm. Its much faster.
If you mean via an ADC input pin then no. If you mean to supply power to an ESP32 then that sort of battery will destroy the ESP32 as the battery voltage is nominally 3.8v and the maximum ESP32 supply voltage is 3.3v. You can use a LiFePO4 battery for direct connection as it’s cell voltage is 3.2v
float voltage = analogRead(35) / 4096.0 * 7.23. Vary the value 7.23 until the value of voltage is correct, no other way of doing it. Use a ratio to get the exact value, example ESP32 voltage = 3 but actual voltage = 2.8 with a constant of 7.23 then new value = 7.23 * 2.8 / 3.0
Well you need an application that can upload data to which you add the single function I have provided here to read the voltage and then calculate battery capacity. It depends on what your cloud service is and what it’s API is, I have produced a video on Thingspeak uploads which is 95% of what’s required to upload the value.
@@G6EJD thank you sir for quick reply i am using firebase real-time database to upload my sensors data and fetch in iot app using api call.... So how can I send my device battery level to firbase..... I need only what variable should I send to firebase... Thank you
Follow the link to Github (in video description, add the function readBattery() to your programme, then String batteryPercent = readBattery(); You can then send batteryPercent or whatever you called it, it's your choice e.g. String batteryCapacity = readBattery(); or if you want to send an integer: int batteryPercent = readBattery().toInt();
One of best project on monitoring LiPo battery capacity. Thank you for sharing this useful gadget details.
Very useful information. A much better approach than I've been attempting. Thank you for you efforts.
Dan, the only way to truly get a capacity value is to monitor both voltage and load currents, but using voltage only does give a very good estimation u set most load conditions, I hope you find it useful. I gave up using s simple voltage measurement and straight/line estimate as I knew the results were wrong, now I get a much better value.
Many thanks - another useful piece of code and clear explanation of how it works.
Hi Dave, very good to describe the discharge curve of the LiPo as 'non-linear' and its a good tool to estimate remaining capacity. However, it is load-dependent. More importantly, this method should never be used to determine when a battery is full - LiPo must always be charged in accordance with the manufacturer's recommendations (normally CC/CV).
Indeed, but this is principally for use with a micro-controller where loads are low. For my drones and Rx fixed wing aircraft and radios I’ve been using LiPo’s for about 10-years now and I agree there are few around who fully understand the charging regimes that need to be applied especially Boeing and their 787’s that caught on fire when someone thought they could replace a NiMh with a LiPo without changing the charging methods. For most development boards on the market they have a reasonable battery charger-management chip the TP4054 which is widely used to keep the batteries in good shape so most users of these devices will be well protected.
@@G6EJD Yes - lol even the 'big' boys screw it up. I was just wanting to flag up that its important to follow the charging guidelines before someone decides to change your code into a battery charger :)
@@G6EJD do you have any more information on why the batteries caught fire? I have converted an old cleaning robot to LiIon batteries and included a BMS/ protection board which cuts out a little earlier than the full charge voltage of the previously used NiMH Batteries.
I’m not sure if we’ll ever know the real reason why Boeing’s batteries caught fire, but my intuition is they did not understand the (then) novel use of LiPo batteries as a replacement/upgrade and the need for extensive battery monitoring. I can proudly say of all my 70+ high capacity LiPo’s I’ve never had a failure typically in the form of puffing (swollen) packs due to overheating during charge and discharge or over/charge. You must charge at constant voltage and not constant current but a constant current charger is perfectly ok if you employ good charge monitoring circuitry to check for over voltage or heating. At the lower end where the battery becomes depleted say to 3.2v when it can become chemically damaged is when most damage is caused, and then when charging recommences a chemically damaged cell can become excessively hot as it’s internal resistance rises as a result of the damage. It’s like John was pointing out, these batteries need careful handling during both charge and discharge but correctly implemented(Apple have this almost perfectly so in their products) the battery will be safe and last a long time. I hope this helps. Sounds like you’ve done the right thing in your installation.
Thank you very much for your excellent video. This info will be most useful in my garden monitor devices.
Excelent explanation. Like allways.
Thanks for solving the problem I've been having.. cheers
Brilliant, thank you! I still use your ADC mathematical correction for the ESP32 (which isn't accurate at the extreme low and high end of the range)
Super video Thank you David!
When using higher-order polynomials, the precision of coefficients can potentially adversely affect the result. Is there an easy way to check that the rounding errors in your floating-point-arithmetic do not misrepresent the polynomial? For example - at 4:00 what does the coefficient "2808.3808" actually compile to? Is this enough?
On all the implementations (Arduino UNO, ESP8266 or ESP32) a 'float' is 4-bytes and can represent the values in the polynomial.In testing the results are as expected.If there was any doubt the data type could be changed to 'double' however on the UNO there is no difference between double and float. I'll test it now:
Serial.begin(115200);
float test = 2808.3808;
Serial.println(test,6);
Result:2808.380859
So it's maintaining the 4-places of precision adequately, but adding some lower order artefacts too, but as these are relatively small, there is little effect on the result.Good question, thanks.
@@G6EJD Perfect. Thanks!!
Thank You
So just to check I understand this, if using a Lipo on a lolin type board (with integrated lipo socket), the measurement is actually taken usning an internal ADC (despite referncing pin 35) and this will allow me to monitor voltage without any additional circutry? Thanks. (At about 3.45 on your video)
Yes OST boards have an on-board voltage divider which has a /2 ratio enabling 0-6v to be measured, actually 6.6v depending on linearity required. The Junction of the voltage divider is connected to pin 35, could be any pin in the ADC pin range and yes you can monitor battery voltage.
@@G6EJD thank you. I'll give that a try.
@@G6EJD I've hooked up a Lipo and tried running your code, but I'm not getting anything by reading pin 35. I have also tried substiuting several other pins, but to no avail. I did run a loop changing the pin number on every iteration and the first time round, pin 15 looked promising with 4+ volts showing (The lipo was charging via the USB connection), but since then, I only get a reading of 0.77v. Any ideas?
There are genuine Lolin D32 boards and fake Lolin 32 boards die it have a white silk screen LOLIN D32 label on it. If not it’s a fake and no on-board voltage divider and monitor is fitted. If a genuine board there must be a battery supply fitted to the batter SH terminal and it will use pin-35 in common with most other boards fitted with an on-board monitor. Where did you buy it from?
@@G6EJD I got it from Aliexpress. My guess is that being a copy, it probably doesn't then have this option.
..very clever thank you :)
I am having trouble getting this to work on my lo lin 32 with the battery charge option. I think I am miss understanding the circut not the program or the math . when I plug in the battery should I get voltage directly between pin 35 and ground . I get 0 voltage I have 3.3 at the 3.3 pin so the battery is connected and I have charged the battery up thorough the board but cannot get any reading out of pin 35 through a meter or through the program.
thanks Jim
I figured this out thanks
Some boards don’t use pin 35 or more usually have no connection at all an you would need to make a wired connection between the battery + and a voltage divider and the chosen ADC input pin.
Thank you very much!
Excellent video. 👍
I have a question. What difference would be if I use Li-ion (18650) cell?
No difference, identical characteristics.
Hi Dave,
I'm working on a project using Esp 32 and 3x18650 battery in series(12.6v) with a voltage divider to 3.3v for ADC. How can I calibrate it? 12.6 will be the 100% and 10.5 the 0% or i have to adjust the calibration value to 4.20 - 100% and 3.50 - 0%?
Thank you in advance for your time and for the good job as well :)
did the esp32 is showing the accurate adc value in your project by using the voltage divider
Every ESP32 has a different ADC response depending on its reference voltage. This is why they need to be adjusted and compensated for. The voltage divider only improves range.
Would it be better to map the voltage to the percentage in an array and then estimate by aproximation? It could be faster i think. Great tutorial!
Could you make a video on how to create a polynomial to use in projects? keep the good work
The advantage, if any would be marginal, as getting a battery capacity value need not be done in near real time and I expect it takes no more than a few masers to calculate the result. Creating a polynomial is a skill that has to be learnt and requires a high level of mathematics knowledge there are already a few videos and tutorials around that explain the process one very good one is Australian and comes up through a google search.
Does the same formula work for Lithium Ion batteries?
Yes they have identical characteristics
hi David, you really did a great job determining the polynomial function.
I tried to do the same thing because I want to use 3.1V for 0% but without result ....
my curve remains crooked !!
Can you calculate me the function for 100% at 4.2v and 0% 3.1v
I can do, I use the tabular method. But with a standard voltage regulator with excellent drop-out specification do you think your ESP32 will still run reliably? 3.1 volts infers an output voltage of 3.0 or less, it will take me a while to do the maths, but watch this space!
Try this,, but I think battery voltage is going to fall away very quickly: y = -0.00000000001912x6 + 0.00000000451735x5 - 0.00000039128959x4 + 0.00001345348277x3 + 0.00002191577616x2 - 0.01698649053242x + 4.19959893330281
@@G6EJD Thank you very much David for this function,
but it is to calculate the voltage according to the percentage
so without abusing, is it possible to have reciprocity?
@@brunodelort3337 So you want to achieve a linear voltage reading?
@@brunodelort3337 You can just multiply the % value by the chosen voltage range, for example 0-100% = 0 - 3.3v so % / 100 * voltage or for example at 50% = 50/100*3.3 achieves the same result as a new polynomial based on a 0-3.3 y scale.
Wouldn't a 3 point interpolation get you closer to actuals?
The ADC is significantly non-linear between 0 and 0.6v and then 3 to 3.3v, which is why I chose s polynomial to follow the ADC response curve, a simple linear interpolation would not give acceptable results outside of the region 0.6 to 3 volts, however within that range the ADC is actually very linear.
Hey friend nice video! wondering if we could use 2 * 1 million ohms resistors instead 2 * 100K ohms? i need the lowest power consumption on my project.
You can but then that limits the input current to the ADC and results in noisy / variable readings, if you don’t need to take readings quickly you can add a 1.0uF capacitor across the ADC input and Ground to smooth the readings, but it will introduce a delay of 1-sec in reacting to change, you could try lowering the capacitor values to suit your application.
Great Video David, many thanks.
I'm not getting the results expected. Using a Wemos D1, with the 100k in line.
Looking at your code in the video you have
float voltage = analogRead(A0) / 1023.0 * 4.24;
and on github you have
float voltage = analogRead(A0) / 4096.0 * 4.24;
I'm guessing it should be the first one.
I was pointed to this video as I was having issues getting correct readings, and with your code I'm still getting odd readings, they don't match.
EG my the battery shows 3.42v on a meter, but the code is showing 3.63v.
Any ideas?
Thanks
Brian, the ESP ADC’s are variable as are the voltage dividers, so as you have surmised the / 1023 code line is correct for the 10-but ESP8266. Next adjust/calibrate your reading on the serial port by adjusting the multiplier 4.24 if too low compared with your meter increase it or too high decrease it.
So you need 4.24 * 3.42/3.63 = 3.95
Hello, nice work there. Thanks for the explanation. I have a question. How do you measure battery if you use 18650 battery shield? What probe do you use to connect to the voltage divider? Thanks.
You have to do the same as any other battery measurement and add a voltage divider if one isn’t fitted to the board, then wire it’s (divider) input to the battery + terminal there’s no other way of doing it, not neat but it’s the only way. It would be unlikely for the battery shield to have a Vbat terminal
@@G6EJD Im on the LOLIN LITE, and running it off a 18650 like above, can I solder a jumper strait from the positive terminal to pin 35 to get my voltage reading? do i need the 100k resister?
@@photobusta the ADC input maximum voltage is 3.3v, so you must fit a voltage divider to reduce the voltage say Vin--100K--ADC Pin--100K---Gnd then when you take your measurement it needs to be multiplied by 2 for the correct value
@@G6EJD awesome! thanks
Is this for a 3.7 V LiPo battery or some other one? Thanks
Yes, Li-ion 18650 3.8v nominal battery type, but could be modified for others. It’s meant for the Lolin D32 and others on-board battery input. I have not seen any other battery used.
Gracias, excelente video. Estuve buscando está información desde hace tiempo, solo me queda una duda. Tengo un D1 Mini ESP32 , por qué medios cargara la batería? Por la alimentación USB ?
No puede, hay un cargador a bordo, por lo que estará listo para colocar uno externamente. son freeky disponibles
I use WEMOS LOLIN32 V1.0.0 with a 3.7v polymer battery without resistors, I have used your code but the battery indicator only continues to show 100%, do you have a solution..thanks before.
The Wemos lolin32 v1 does not have an on board voltage divider it was a copy board. See my tn143 to see how to add a voltage divider, you’d need to use 2 x 470K resistors
@@G6EJD thanks for your respond can I use 100k resistors?
Yes any two identical values gives you /2 to make the maths easier
@@G6EJD Hello, I make a project into school and I need to indicate when is battery low. I have also WEMOS LOLIN32 V1.0.0 so without an on board voltage divider. I do not know how to right connect the battery. Can I use built-in JST-PH-2 conector for battery power and still be able to put there a voltage divider and measure the power? Thank You for Your Response.
Is there a Vbat pin on that board? To measure voltage you will need to use a voltage divider made of two resistors of the same value. Wired like this Battery + terminal or Vbat pin, - - - - R1- - - - ADC pin - - - - - R2- - - Gnd
R1 and R2 can be any two equal values say 100K is each or 470K or 220K or whatever even 1K but they will discharge the battery quickly if too low a value.
Read the voltage with the standard ADC read function. If you use pin 36 then float voltage = readAnalog(36) / 4095.0 * 6.566;
I am using node MCU devkit 1.0 by Amica which voltage divider I should use
Depends on what voltage range you want to measure 0 to ? Volts
@@G6EJD i want to measure my battery voltage 4.2v to 3.0v
@@mr.techinventor3463 then use two 470K resistors or two 220K would do or any two same values wired like this +Battery-220K-ADC-pin--220K-Gnd
@@G6EJD thank you
Cool
Is there such a detailed discharge plot for LiFePO4 batteries?
Yes there is, knee voltage is 3.0 volts, I could produce a LifePO4 equation if you need it? But I’d need to know the absolute lower voltage, fully charged they are 3.6v and then discharged approximately 3.0, if needed let me know.
percentage=4984.6172x3 - 48287.7528x2 + 155490.3329x - 166375.8607 where x is measured voltage for a LifePO4 and assumes higher end of 3.4v and lower end 3.0v
@@G6EJD thank you for taking time out of your day to formulate the equation!
It's my pleasure, I'll add it to the library as an alternative version.
Very useful explanation and I'm going to use this method in my project. I actually use 2s LiPo 18650 batteries to supply Arduino nano. What would be the calibration coefficient in this case. Please advise.
If your doubling the input voltage then reduce the multiplication factor by 2 by increasing the first series resistor by 2 otherwise the input voltage will exceed the ESP32 ADC capability
@@G6EJD , Thank you very much, but I use Arduino nano, not the ESP32.
Alio Canter, well the same principle applies you will have to double or more the first series resistor of the input voltage divider
@@G6EJD It means that I'll have to provide 5V form 8.4 V at the ADC input of Arduino nano?
or 4.2V? Sorry but I am newbie.
Hi thanks for the vidéo ;) I like it ! one question remains : if you mesure the battery under load what happens ? if the load is big ? if the load is small ? If the load is big i presume the voltage will drop, so your solution is not suitable for any device that uses power of the same battery that it mesures. Can you confirm that ? Thanks for the great explaination of polynomial curves again !
The ADC measures the literal voltage just like a DVM would do, so whether on light or heavy load the voltage measured is that across the battery. The on-board regulator has a drop out voltage of about 0.1v and the ESP32 stops working at about 2.8v so when the battery voltage reaches 2.9v the ESP32 will stop working.
ESP32 ADC mathematical corrections are great, but pow calculation on MCUs take just too many CPU cycles. Better way how to calculates polynomials is Horner algorithm. Its much faster.
Is it dangerous i do direct connection lithium ion to esp32?
If you mean via an ADC input pin then no. If you mean to supply power to an ESP32 then that sort of battery will destroy the ESP32 as the battery voltage is nominally 3.8v and the maximum ESP32 supply voltage is 3.3v. You can use a LiFePO4 battery for direct connection as it’s cell voltage is 3.2v
@@G6EJD i just want to use esp32 to monitor the lipo4 battery percentage. Should be okay right by just adding two resistor for voltage divider
@@shakirsalam555 exactly that is required
@@G6EJD hi bro,i just eant to ask. Is there any way i can take the serial monitor value and display it on lcd or oled display?
@@shakirsalam555 when you say serial monitor value, do you mean the data value received?
How to perform calibration sir to get value
float voltage = analogRead(35) / 4096.0 * 7.23.
Vary the value 7.23 until the value of voltage is correct, no other way of doing it. Use a ratio to get the exact value, example ESP32 voltage = 3 but actual voltage = 2.8 with a constant of 7.23 then new value = 7.23 * 2.8 / 3.0
@@G6EJD many thanks sir you are very helpful glad to have teacher like you
Great sir ....how i can send my device battery level to cloud sir to send battery level in my iot app....
Well you need an application that can upload data to which you add the single function I have provided here to read the voltage and then calculate battery capacity. It depends on what your cloud service is and what it’s API is, I have produced a video on Thingspeak uploads which is 95% of what’s required to upload the value.
@@G6EJD thank you sir for quick reply i am using firebase real-time database to upload my sensors data and fetch in iot app using api call.... So how can I send my device battery level to firbase..... I need only what variable should I send to firebase... Thank you
Follow the link to Github (in video description, add the function readBattery() to your programme, then
String batteryPercent = readBattery();
You can then send batteryPercent or whatever you called it, it's your choice
e.g.
String batteryCapacity = readBattery();
or if you want to send an integer:
int batteryPercent = readBattery().toInt();