So far, I had no luck in getting proper voltage readings from one of the ADC inputs. Since there is no documentation, I simply queried all ADC pins in a hope to get one with some voltage readings. Here's part of the code:
...
int pinCount = 11; int ADCpins[] = {2,12,13,32,33,34,35,36,37,38,39}; // these are the ADC pins
float VBAT; // battery voltage from ESP32 ADC read float ADC_divider = 250/30; // voltage divider proportions - hypothetical so far :-)
void setup(){
for (int thisPin = 0; thisPin < pinCount; thisPin++) {
Serial.print(thisPin, DEC); Serial.print(" = "); Serial.print(ADCpins[thisPin], DEC); Serial.print(" => ");
pinMode(ADCpins[thisPin], INPUT);
VBAT = ADC_divider * (float)(analogRead(ADCpins[thisPin])) / 1024.0; // LiPo battery voltage in volts Serial.print("Vbat = "); Serial.print(VBAT); Serial.println(" Volts"); }
}
And this is, what I get:
0 = 2 => Vbat = 0.00 Volts
1 = 12 => Vbat = 0.00 Volts
2 = 13 => Vbat = 0.00 Volts
3 = 32 => Vbat = 3.52 Volts
4 = 33 => Vbat = 1.16 Volts
5 = 34 => Vbat = 0.00 Volts
6 = 35 => Vbat = 0.00 Volts
7 = 36 => Vbat = 0.00 Volts
8 = 37 => Vbat = 0.00 Volts
9 = 38 => Vbat = 0.00 Volts
10 = 39 => Vbat = 0.00 Volts
So I do get some reading on ADC pin 32 and 33 but it does not really make sense so far.
The value remains more or less the same when I remove the battery...
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
I was able to get the example code running on my Heltec ESP32 LoRa board. It seems to work well, although it doesn't report the right values. It seems to be off by roughly 25%. Consistently so, however-- as if the multiplier value is wrong.
Anyway, here's a screenshot of the discharge and charge cycle. The gap in the middle is where the low voltage cutoff kicked in and brought the board offline.
Looks very much like any typical LiPo charge curve to me.
https://imgur.com/a/4GL4ajK.jpg
Are you sure? yes | no
This is super old but I just got one of these boards. In order to measure the voltage on the ADC you have to set pin 21 to low. This switches on the FET on the voltage divider.
Are you sure? yes | no
/*
* HelTec Automation(TM) Electricity detection example.
*
* Function summary:
*
* - Vext connected to 3.3V via a MOS-FET, the gate pin connected to GPIO21;
*
* - Battery power detection is achieved by detecting the voltage of GPIO13;
*
* - OLED display and PE4259(RF switch) use Vext as power supply;
*
* - WIFI Kit series V1 don't have Vext control function;
*
* HelTec AutoMation, Chengdu, China.
* 成都惠利特自动化科技有限公司
* https://heltec.org
* support@heltec.cn
*
* this project also release in GitHub:
* https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
*
*/
#include "Arduino.h"
#include <Wire.h>
#include "heltec.h"
#define Fbattery 3700 //The default battery is 3700mv when the battery is fully charged.
float XS = 0.00225; //The returned reading is multiplied by this XS to get the battery voltage.
uint16_t MUL = 1000;
uint16_t MMUL = 100;
void setup()
{
Heltec.begin(true /*DisplayEnable Enable*/, false /*LoRa Enable*/, true /*Serial Enable*/);
Heltec.display->init();
Heltec.display->flipScreenVertically();
Heltec.display->setFont(ArialMT_Plain_10);
Heltec.display->drawString(0, 0, "OLED Start");
Heltec.display->display();
delay(1000);
Heltec.display->clear();
adcAttachPin(13);
analogSetClockDiv(255); // 1338mS
Serial.begin(115200);
}
void loop()
{
//WiFi LoRa 32 -- hardare versrion ≥ 2.3
//WiFi Kit 32 -- hardare versrion ≥ 2
//Wireless Stick -- hardare versrion ≥ 2.3
//Wireless Stick Lite -- hardare versrion ≥ 2.3
//Battery voltage read pin changed from GPIO13 to GPI37
uint16_t c = analogRead(37)*XS*MUL;
Serial.println(analogRead(37));
// uint16_t c = analogRead(13)*XS*MUL;
// Serial.println(analogRead(13));
Heltec.display->drawString(0, 0, "Remaining battery still has:");
Heltec.display->drawString(0, 10, "VBAT:");
Heltec.display->drawString(35, 10, (String)c);
Heltec.display->drawString(60, 10, "(mV)");
Heltec.display->display();
delay(2000);
Heltec.display->clear();
}
Are you sure? yes | no
Hi @piat.jonathan
As you mentioned before, here is the schematic:
https://heltec-automation-docs.readthedocs.io/en/latest/esp32+arduino/frequently_asked_questions.html#vext-control
and its have an n-fet into the voltage divider as you mentioned, but I found this:
https://fettricks.blogspot.com/2014/01/reducing-voltage-divider-load-to-extend.html
which explains how to proceed when you have n-fet in the voltage divisor
Are you sure? yes | no
The heltec v2 schematic shows that pin 13 is to be used for vbat but i cannot get this to work. The schematic also shows that the voltage divider ties the adc pin to vbat through a 220kohm resistor and on my board the only pin that could match this is the one labelled 37. Unfortunately i cannot measure the bottom resistor of the volltage divider because it is tied to gnd through a MOSFET controled by pin 21.
It seems that i can get a measurement to work using the following code :
//setup
adcAttachPin(37);
analogSetClockDiv(255)
//read
float val = analogRead(37);
val = val * (3.3/4095) * ((220+100)/100) ;
the measurement is still off, and using a bottom resistor value of 82ohm in computation gives a more accurate result or you can calibrate the multiplier value.
val = val * (3.3/4095) * ((220+82)/82) ;
Are you sure? yes | no
Congrats, you have found two pins set to floating mode!
To read battery levels you will most likely want a voltage divider and input directly from the battery.
The math is also very wrong, by default the board uses 12-bit accuracy, with the upper limit at 3.3v (why we need a voltage divider). So the math for normal ADC is `analogRead(32) * (3.3 / 4095.0);`, if we use same value resistors for a voltage divider the 3.3 doubles, to `analogRead(32) * (6.6 / 4095.0);`
Are you sure? yes | no
What board do you have? heltec or TTGO? 433 or 868/915MHz?
Since there are different versions out now, can you perhaps post a photo?
Are you sure? yes | no
Same here - I wonder what the issue is?
Are you sure? yes | no