Hi all. I'm having some issues calculating the battery of my esp32 and was wondering if some of you smart people can help. I am using the esp32-C3-pico found here:C3 pico — WEMOS documentation
From the pinout you can see gpio pin3 should be VBAT. So in my code, I am doing an analogRead in setup and then saving the value to an integer called analogPinVolt. I am then passing it to a function called batteryLife to calculate the battery life as shown:
#define VOLTAGE_PIN 3
int batteryCharge;
// Calculate Battery Life
void batteryLife (int analogPinVolt){
float batteryVoltage;
float batteryLevel;
batteryVoltage = 2*3.3/4095*analogPinVolt;
if (batteryVoltage<3.5){
batteryVoltage = 3.5;
}
if (batteryVoltage>4.2){
batteryVoltage = 4.2;
}
batteryLevel = 3.5631457616E3*pow(batteryVoltage,4)-5.4787671494E4*pow(batteryVoltage,3)+3.1541375900E5*pow(batteryVoltage,2)-8.0559293115E5*batteryVoltage+7.7008357786E5;
batteryCharge = static_cast<int>(batteryLevel);
}
void setup() {
...
int analogPinVolt = analogRead(VOLTAGE_PIN);
batteryLife(analogPinVolt);
I started to troubleshoot and it seems the "int analogPinVolt = analogRead(VOLTAGE_PIN);" in the setup subroutine is giving me all sorts of values. Almost seems random. That pin is connected to a pushbutton but I do not set the pinMode until after the analogRead. The idea is I only need to know the battery power at startup or after waking from deep sleep. The question is...could having a pushbutton connected to pin 3 be messing with the voltage? Is there any way to fix this other than removing the bushbutton from pin3 (I have no free gpios).
Also, so doing things like unplugging the usb and plugging in the battery have an effect, but if I put it to sleep and then wake it up, it always shows full battery.
Fish
Hi jremington. If you look at the second photo (bottom of the board) there is a pad that is marked (Battery to IO# (A3). Is that the jumper? Do I put a 0 Ohm resistor across the chevron on the pad to jump it (or maybe a small dab of solder)? Sorry...kinda new to the hobby.
oh...so if after the anaolgRead, If I set pinMode(3, INPUT_PULLUP); then I could still use as a pushbutton? That's exactly what I wanted to use it for!
It isn't all over the place, so I think I am close. When I plug the battery in, I get a reasonable reading now and it is stable. However, when the esp32 goes into deep sleep and then wakes up, the reading I get is 4095. Why is it maxing out the read on wakeup?
I put the line analogPinVolt = analogRead(VOLTAGE_PIN); in my loop and it seems to be stuck on 4095. I have nothing connected to that pin and removed all references to it in my code. However, If I remove the usb and unplug the battery then plug it back in, I get a value of 2763ish but I see it updating. If I then put the module to sleep and wake it up, it goes to 4095 and stays there.
o.k. got this working. The issue is the esp32-C3 isn't the same as the esp32-Sx in terms of available wakeup pin bitmask options. On the C3 you have the ability to hold the pins high with a pullup resistor during deep sleep and wake up when one of the pins goes low which is what I was doing. However, this means once the module goes to sleep, the pin gets pulled up and stays high even after the controller awakens and runs through setup. So once it goes to sleep, you cannot do an analogRead i.e. the pin doesn't reset (pinMode (GPIO#, 0x03) doesn't work ). So I just took the pin in question out of the bitmask for the pins that can awaken the esp32 and that fixed it.
the ESP32-C3 has a dedicated function to read the voltage and give a results as millivolts.
Very usefull!
You only need to know your division factor and put it in the calculation!
To me the factor is 1,943, very close to "2" as I use 2 identical resistors to lower the voltage. The 1,943 was obtain by measuring the voltage with a multimeter at the exit of the battery, and after the resistor. Then I can include it in my code.
there is also a "blank" measure before the effective measure. Not sure if it is very usefull but it is an old habit from my previous arduino boards;
Pretty simple in my opinion. I hope you can use it!
void LECTURE_BATTERIE() {
// lecture analogique compensée sur A0: fournit la tension en millivolt
pinMode(Pin_batterie, INPUT); // lecture voltage batterie par pont diviseur
analogRead(Pin_batterie);
delay(2);
batterie = analogReadMilliVolts(Pin_batterie) * 1.943; // *1,943 = ration pont diviseur (=1/2)
}