Add Battery Sensor functionality and integrate with display and app
- Implement BatterySensor class to monitor battery voltage and status. - Update App to initialize and loop BatterySensor. - Modify FaceRenderer to display battery status on the screen. - Enhance Display class with a method to draw battery icon. - Update WebUI to include battery status in the interface. - Refactor WiFiManager to improve connection handling and logging. - Adjust Settings to include factory reset functionality. - Improve HTML structure and styling in WebUI for better user experience.
This commit is contained in:
100
src/sensors/BatterySensor.cpp
Normal file
100
src/sensors/BatterySensor.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "BatterySensor.h"
|
||||
|
||||
void BatterySensor::begin() {
|
||||
pinMode(PIN_BATTERY_ADC, INPUT);
|
||||
pinMode(PIN_LBO, INPUT);
|
||||
|
||||
analogReadResolution(12); // 12-bit ADC (0-4095)
|
||||
|
||||
Serial.println("[Battery] Initialized");
|
||||
Serial.println("[Battery] ADC on GPIO 2, LBO on GPIO 5");
|
||||
|
||||
// Initial reading
|
||||
_voltage = readBatteryVoltage();
|
||||
_percent = voltageToPercent(_voltage);
|
||||
_isLow = (_voltage < VOLTAGE_LOW);
|
||||
|
||||
Serial.print("[Battery] Initial voltage: ");
|
||||
Serial.print(_voltage);
|
||||
Serial.print("V, ");
|
||||
Serial.print(_percent);
|
||||
Serial.println("%");
|
||||
}
|
||||
|
||||
void BatterySensor::loop() {
|
||||
unsigned long now = millis();
|
||||
if (now - _lastCheckMs < CHECK_INTERVAL_MS) return;
|
||||
_lastCheckMs = now;
|
||||
|
||||
float prevVoltage = _voltage;
|
||||
int prevPercent = _percent;
|
||||
bool wasLow = _isLow;
|
||||
|
||||
// Read battery voltage via ADC
|
||||
_voltage = readBatteryVoltage();
|
||||
_percent = voltageToPercent(_voltage);
|
||||
|
||||
// Check LBO pin as backup confirmation
|
||||
bool lboHigh = digitalRead(PIN_LBO);
|
||||
bool lboIndicatesLow = !lboHigh;
|
||||
|
||||
// Battery is low if either voltage is low OR LBO pin indicates low
|
||||
_isLow = (_voltage < VOLTAGE_LOW) || lboIndicatesLow;
|
||||
|
||||
// Log significant changes
|
||||
if (abs(_percent - prevPercent) >= 5 || _isLow != wasLow) {
|
||||
Serial.print("[Battery] Voltage: ");
|
||||
Serial.print(_voltage, 2);
|
||||
Serial.print("V (");
|
||||
Serial.print(_percent);
|
||||
Serial.print("%) LBO: ");
|
||||
Serial.println(lboHigh ? "OK" : "LOW");
|
||||
|
||||
if (_isLow && !wasLow) {
|
||||
Serial.println("[Battery] ⚠️ LOW BATTERY WARNING - Please recharge!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float BatterySensor::readBatteryVoltage() {
|
||||
// Take multiple samples and average them for stability
|
||||
long sum = 0;
|
||||
for (int i = 0; i < SAMPLES; i++) {
|
||||
sum += analogRead(PIN_BATTERY_ADC);
|
||||
delay(5);
|
||||
}
|
||||
int avgRaw = sum / SAMPLES;
|
||||
|
||||
// Convert ADC value to voltage at the pin
|
||||
// ESP32-C3 ADC: 12-bit (0-4095) maps to 0-3.3V
|
||||
float adcVoltage = (avgRaw / 4095.0) * 3.3;
|
||||
|
||||
// Multiply by divider ratio to get actual battery voltage
|
||||
float batteryVoltage = adcVoltage * DIVIDER_RATIO;
|
||||
|
||||
return batteryVoltage;
|
||||
}
|
||||
|
||||
int BatterySensor::voltageToPercent(float voltage) {
|
||||
// Clamp voltage to valid range
|
||||
if (voltage >= VOLTAGE_MAX) return 100;
|
||||
if (voltage <= VOLTAGE_MIN) return 0;
|
||||
|
||||
// Linear mapping from voltage to percentage
|
||||
// This is a simplified model; LiPo discharge curves are non-linear
|
||||
// For better accuracy, you could use a lookup table
|
||||
float percent = ((voltage - VOLTAGE_MIN) / (VOLTAGE_MAX - VOLTAGE_MIN)) * 100.0;
|
||||
|
||||
return constrain((int)percent, 0, 100);
|
||||
}
|
||||
|
||||
bool BatterySensor::shouldBlink() const {
|
||||
// Blink every 500ms when battery is low (< 20%)
|
||||
return (_percent < 20) && ((millis() / 500) % 2 == 0);
|
||||
}
|
||||
|
||||
int BatterySensor::iconFillWidth(int maxWidth) const {
|
||||
// Calculate fill width for battery icon
|
||||
// Returns 0 to maxWidth based on percentage
|
||||
return (_percent * maxWidth) / 100;
|
||||
}
|
||||
Reference in New Issue
Block a user