Hi all, I'm reading many old threads about voltage dividers needed to measure voltage to calculate the battery level of a lipo battery supply, and also noticed the problem and danger of over discharge a LiPo batt by current drain of a voltage divider, so I wonder if there is a way to read the voltage of a lipo battery directly on a digital pin, my arduino is powered by a step up converter so I can get an "stable" reference value of 3.3v, @ 15% accuracy is enogh to me (rough autonomy level) , but I don't know the real voltage limit of analog pin. Are the nano 33 IOT tolerant enough to read 4.2 volts (maybe a current limiter resistor) without a voltage divider? sorry for the basic question but I want to eliminate components and work as much as possible because the reduced espace left in my project. Other posibility is to use a "gate" to enable the voltage divider only when Arduino is running so the current drain of voltage divider is "under control" and the voltage divider will not drain off the battery if the device is not used for long periods. I don't know if battery internal protection circuits can stop slow drain discharges Many thanks for any help or comments on this if I can take in some way 4.2 volts by analog read I have everything solved ... maybe a 5V board will do the trick but the nano 33 has a lot more of possibilities Thanks for any Idea Ale
Have a look at the MKR WiFi 1010 circuit. It is like the Nano 33 IoT but with a LiPo circuit. You can find the schematic under DOCUMENTATION in the store.
There you will see they build a voltage divider with 330K and 1.2M resistors and a 100nF capacitor to measure the battery voltage.
- With a voltage of 4.2V you will get a current of 4.2 / 1.5M ~ 2.8uA.
- With a 100mAh LiPo (I just picked a small one I found as example) you get 100mAh / 2.8uA ~ 35k hours ~ 4 years. So, this circuit is no danger to your battery.
The capacitor is necessary because the input source resistance for the SAMD21 analog pins is 3.5kOhm maximum. The voltage divider resistance would be too large. The sampling capacitor is 3.5pF. So, the sampling capacitor can easily be charged from the 100nF capacitor.
Klaus_K Thanks a lot for your clear and straight explanation! You are right I should have thought on that! I have both nano33IoT and MKR1010WiFi and have seen the schematics sometimes for the built-in rgb led wiring and pins, but I didn't pay attention on the voltage divider, I'll take a deeper look again, no need to rediscover the wheel if Arduino guys have already done it for maker! silly brain of mine, I think I'm getting old, Fortunately there are always younger people willing to help! just for curiosity I'm not sure of analog reading voltage max limit of 3.3V I read some info about 3.3V+0,7v max but not very well documented and I always assumed that it was 3.3v but I'm just curious because Arduino is a whole new world to this old brain and that's why I prefer digital data readings when available... as its safer to and simpler to me to understand with barely basic electronics knowledge! Thanks again
@Klaus-K, hopping not to abuse of your kind help, just to compare readings between Nano33IoT and her big sister MKR1010 would it be right to assume that analog read pin32 will read the value @ PB09 in Mkr 1010 Wifi As it does in other MKR boards ? Many thanks again
analogRead(32);will Read the analog input on PB09 ?
Ale-X: just for curiosity I'm not sure of analog reading voltage max limit of 3.3V I read some info about 3.3V+0,7v max
The input structure of the I/O can withstand a little bit of overvoltage but that does not mean it is a good idea. The SAMD21 datasheets Absolute Maximum Rating for I/O pins is Vdd + 0.6V. It also states:
[quote author=DS40001882F-page 865]This is a stress rating only and functional operation of the device at these or other conditions beyond those indicated in the operational sections of this specification is not implied. Exposure to absolute maximum rating conditions for extended periods may affect device reliability.[/quote] So, the voltage at an analog pin should be between GND and VDD.
Ale-X: @Klaus-K, hopping not to abuse of your kind help,
Don't worry, I do this for fun. :)
Ale-X: would it be right to assume that analog read pin32 will read the value @ PB09 in Mkr 1010 Wifi As it does in other MKR boards ?
I think you are right. That is what the variant file suggests. Have a look here:
Many Thanks Again!!! from variant.h
//Battery #define ADC_BATTERY (32u)
now, its time of hardware tests!
Hi Alex-X, I’m struggling with the fact that a simple codeline such:
int adcReading = analogRead(ADC_BATTERY);
that is perfectly working with MKRWifi1010 doesn’t work with Nano 33 Iot despite the fact the two boards (MKR wifi 1010 and nano 33 iot "belong to the same SAMD family)
Would you so kind to provide me the code you are using to read the battery level on Nano 33 iot?
Thanks a lot
The Arduino Nano 33 IoT does not have the battery electronics that the MKRWifi1010 has. So, you cannot read the ADC_BATTERY voltage.
If I understand the variant files correctly you have an additional analog pin on the Arduino Nano 33 IoT over the MKRWifi. You can build your own external battery circuit and measure the voltage with that additional pin if you used all the other 7 analog pins.
Hi Klaus, thanks for your kind reply.
It’s a pity indeed, since by design Nano 33 iot is meant to collect data from things and to bring that data to a platform somewhere (for instance I use Thingspeak that is incredibly simple and easy to use). And for sure a normal usage of Nano 33 Iot is to power it with a battery, whose charge level becomes immediately a relevant data to be shared and managed.
I’ve obviously built my own voltage divider to read the battery level but is a waste of energy consumption, hardware, time, an additional potential point of failure… In the end not having ADC_BATTERY reading capability on nano 33 Iot is making me reconsider the option to go back to MKR Wifi 1010, maybe one of the best engineered Arduino boards so far (I’m an Arduino customer of several UNO, Uno Wifi, MKRWifi1010, Micro, 33BLE Sense, 33Iot, MKR Motor Carrier, MKR Iot Carrier.)
Why would your voltage divider be an additional point of failure? The MKRWifi1010 voltage divider has the same chance of breaking.
As for the waste of energy. The MKRWifi1010 uses a 1.2MOhm (100nF parallel to buffer the voltage) and 330kOhm. The voltage divider will draw a current of around 2.4uA (e.g., LiPo nominal 3.7V, 1.53MOhm). A 100mAh battery (which is small) will need more than 4 years to empty. No need to worry about that. The battery self-discharge is likely higher.
The Arduino Nano 33 IoT is almost half the price of the MKRWifi1010. Adding your own voltage divider, you are still saving some money.
sorry for the late answer, I’ve been out of forums for a while.
and yes as Klauss have said the way I use to read the battery level in a Nano 33 IOT is a voltage divider with the same values 1.2M+330K plus a capacitor to send a proportional voltage value to be compared with reference voltage. this is neither so complicated nor expensive…
the result is a really precise voltage measure that combined with “running median” or “running average” routines and “map” function can give you a reliable value of battery charge averaging the last readings to eliminate the small fluctuations of ADConverter
here the part of the code I use to draw a battery icon filled proportionally to the battery charge in a nano 33 IOT board with an oled display and running average libraries used
(sorry formy very basic level of programming techniques, I’m old but always newbie)
//inside loop function// delay(100); int battery = analogRead(Apin); delay(100); int batteryLevel = map(battery, 0, 1023, 0, 418); RunAvg2.addValue(batteryLevel); float volts = fmap(battery, 0, 1023, 0.0, 4.2); Serial.println(batteryLevel); Serial.println(battery); Serial.println(volts); int AVG2 = RunAvg2.getAverage(); int batfill= map(AVG2, 345, 416, 1, 17); u8g2.setDrawColor(0); u8g2.drawBox (0, 0, 128, 20); u8g2.setDrawColor(1); u8g2.drawHLine(0, 22, 128); u8g2.drawFrame(105,1, 21, 9); u8g2.drawFrame(127,3, 1, 5); u8g2.drawBox (107, 3,(batfill), 5); u8g2.sendBuffer();
hope this help
Hi Alex, sure it is interesting
One additional question about the resistor value in play.
Assuming we all are using the formula Vout=(R2/(R1+R2))Vin
and taking here the values you suggested as R1=1200 and R2=330
Vout=0.21Vin → Vout=1/5Vin
The question is: what are the values for Vin and Vout that you are considering? Sorry for the direct question but I thought the purpose was to get a Vout target of 3.3V to be read on an analog pin. And in that context the maximum 3.3 Volt level should be read by Arduino Nano as “1023”
you mixed up R1 and R2.
R1 = 330kOhm, R2 = 1.2MOhm, Vbat = 4.2V
Vpin = (1200/1530) * 4.2V → Vpin = 3.294V
Klaus is here with the fast answer!
just for info and to add my cup…
the reference value should be declared to compare with analog pin used to read battery
and its important to keep in mind that there are always slight differences in resistor real values and also battery full nominal readings, have say that, your readings may you lead to calibrate the actual values you’ll get, and also even the multimeters are not always well calibrated to be precise enough @ absolute 0.05v…so you can change the ‘map’ function values to match your readings
and get an acceptable prediction of battery remaining charge.
thanks for your answer, now it’s clear .
Thanks for your cup as well, Ale-X , will try to build a voltage divider accordingly, even tough in my case Vbat will be 5V, therefore I’ve to adjust resistor values accordingly.