There is a mismatch between the actual voltage and measured voltage of the connected battery.
Especially when the battery is not charging.
Results
while charging:
Measured with voltage meter: 3,75v
Computed from the analogRead measurement: 3,8v
without charging:
Measured with voltage meter: 3,73v
Computed from the analogRead measurement: 3,42v
Formula:
expected voltage: (raw/1023)3,3(1+0,51)/0,51
With:
- 1023: 2^10-1
- 3,3: reference voltage
- (1+0,51)/0,51: the voltage divider (1M ohm and 510k ohm)
Measurements
Without BLE connected (while charging):
- Terminal: 398
- Volt meter: 3.75v
BLE connected (while charging):
BLE connected (while not charging):
Code
int BatteryController::getBatteryVoltage()
{
// Enable divider
pinMode(VBAT_ENABLE, OUTPUT);
digitalWrite(VBAT_ENABLE, LOW);
delay(5); // allow voltage to stabilize
// Read ADC
int raw = analogRead(PIN_VBAT);
// Disable divider to save power
pinMode(VBAT_ENABLE, INPUT);
Serial.println(raw);
return raw;
}
variants hpp file (Seeed_XIAO_nRF52840_Sense):
#define PIN_VBAT (32)
#define VBAT_ENABLE (14)
Please verify the connection to the battery pad on the back of the board. Are you measuring the voltage at the pad?
Try this schetch.
//----------------------------------------------------------------------------------------------
//Board Library : Seeed nRF52 Borads 1.1.8
//Board Select : Seeed nRF52 Borads / Seeed XIAO nRF52840 Sense
//----------------------------------------------------------------------------------------------
#include <Arduino.h>
#include <Adafruit_TinyUSB.h> // for Serial.print()
//Arduino15\packages\Seeeduino\hardware\nrf52\1.1.8\variants\Seeed_XIAO_nRF52840_Sense\variant.cpp
#define PIN_VBAT (32) // D32 battery voltage
#define PIN_VBAT_ENABLE (14) // D14 LOW:read anable
#define PIN_HICHG (22) // D22 charge current setting LOW:100mA OPEN:50mA
#define PIN_CHG (23) // D23 charge indicatore LOW:charge HIGH:no charge
void setup()
{
Serial.begin(115200);
while(!Serial);
pinMode(PIN_VBAT_ENABLE, OUTPUT);
digitalWrite(PIN_VBAT_ENABLE, LOW); // VBAT read enable
// pinMode(PIN_HICHG, OUTPUT); // charge current 100mA
// digitalWrite(PIN_HICHG, LOW); // charge current 100mA
pinMode(PIN_HICHG, INPUT); // charge current 50mA
pinMode(PIN_CHG, INPUT); // charge indicatore LOW:charge HIGH:discharge
// initialise ADC wireing_analog_nRF52.c:73
analogReference(AR_DEFAULT); // default 0.6V*6=3.6V wireing_analog_nRF52.c:73
analogReadResolution(12); // wireing_analog_nRF52.c:39
}
void loop()
{
int vbatt = analogRead(PIN_VBAT);
Serial.print(vbatt, HEX);
Serial.print(" ");
Serial.print(2.961 * 3.6 * vbatt / 4096); // Resistance ratio 2.961, Vref = 3.6V
Serial.print(" ");
Serial.println(digitalRead(PIN_CHG)); // 0:charge, 1:discharge
delay(1000);
}
Thanks,
However, the issue persists
Measured 4,07v at the battery pads on the back.
Serial output:
5F7 3.97 0
5F1 3.96 0
5F4 3.97 0
5F8 3.98 0
5FA 3.98 0
5F8 3.98 0
5F5 3.97 0
5F9 3.98 0
5FA 3.98 0
5F8 3.98 0
5F4 3.97 0
5F3 3.96 0
5FC 3.99 0
5F8 3.98 0
5F8 3.98 0
Both the AD converter and the voltage divider resistors have errors. The voltmeter also has errors. I use a voltmeter with 0.5% accuracy as a reference, but there can be a difference of up to about 50mV. Generally, I think it’s best to trust the voltmeter reading and use the AD conversion value after correcting it.
The AD conversion values seem to have a variation of about 30mV. What happens if you average about 100 readings?
Thanks Msfujino
I noticed that the issue is largely due to a voltage drop (300mV) on the 3.3V pin caused by a 20 mA LED. When I remove all the external components, the measurement gets closer to the expected value.
Is there a way to measure the voltage drop specifically due to the load?
The issue was that the voltage at the battery pad on the back of the board differed from the ADC value and the value measured with a voltmeter, right?
Where is the 20mA LED connected? It seems unrelated to this issue.
Indeed.
I assume that a voltage drop on the internal regulator could cause a voltage drop on on the internal ref voltage.
The LED was directly connected to the 3.3v pin, not a GPIO pin.
In the sketch I provided, the reference voltage for the AD converter uses an internally generated reference voltage that is unaffected by VDD=3.3V.