Lesson11: Reading Battery Voltage and Charging Status¶
1. Objectives¶
In this lesson, the ADC is used to read the voltage after it passes through the battery voltage divider. The battery voltage is then calculated based on the voltage-divider resistors shown in the schematic. The raw logic level of the charging status pin is also read to observe the status of the charging IC.
2. Prerequisites¶
- Complete the ESP32-S3 environment setup in Lesson01.
- This lesson uses the ADC and GPIO APIs built into Arduino-ESP32. No additional third-party libraries are required.
How to add the library files:
- No additional third-party libraries are required for this lesson. Use the ADC/GPIO APIs included with the ESP32 3.3.3 board package.
3. Arduino IDE Instructions¶
4. Hardware Instructions¶
- Connect the development board to the computer using a USB data cable, and then open Serial Monitor.
-
Observe the battery ADC value in millivolts, the calculated battery voltage, and the raw CHRG logic level.
-
Connect or disconnect the charging cable and observe whether the raw CHRG logic level changes.
-
If the voltage is clearly abnormal, first verify that the battery connection, power supply status, and ADC voltage-divider circuit are working properly.
5. Key Code Explained¶
constexpr float kUpperResistorKiloOhms = 100.0f;
constexpr float kLowerResistorKiloOhms = 137.0f;
constexpr float kDividerRatio =
kLowerResistorKiloOhms / (kUpperResistorKiloOhms + kLowerResistorKiloOhms);
The battery voltage cannot be applied directly to the ADC and must first pass through a resistor voltage divider. kDividerRatio represents the proportion of the battery voltage that the ADC actually receives. After measuring the voltage at the ADC input, the battery voltage can be calculated by dividing the measured voltage by this ratio.
uint32_t millivoltSum = 0;
for (uint8_t sample = 0; sample < kSampleCount; ++sample) {
millivoltSum += analogReadMilliVolts(kBatteryAdcPin);
delay(kSampleDelayMs);
}
adcMillivolts = static_cast<float>(millivoltSum) / kSampleCount;
ADC readings fluctuate slightly, so the program takes 20 consecutive readings and calculates their average. analogReadMilliVolts() returns a millivolt value calibrated by Arduino-ESP32, making it more suitable than the standard analogRead() for directly explaining voltage measurements.
analogReadResolution(12);
analogSetAttenuation(ADC_11db);
const int chargeStatusRaw = digitalRead(kChargeStatusPin);
analogReadResolution(12) sets the ADC resolution to 12 bits, while ADC_11db increases the measurable voltage range, making it suitable for reading the divided battery voltage. digitalRead() reads the raw logic level of the charging status pin. This lesson does not attempt to interpret the status of the charging IC; it simply allows students to observe the hardware signal first.




