2025-07-19 22:45:22 +08:00
|
|
|
|
#include "adc_battery_monitor.h"
|
|
|
|
|
|
|
|
|
|
|
|
AdcBatteryMonitor::AdcBatteryMonitor(adc_unit_t adc_unit, adc_channel_t adc_channel, float upper_resistor, float lower_resistor, gpio_num_t charging_pin)
|
|
|
|
|
|
: charging_pin_(charging_pin) {
|
|
|
|
|
|
|
2025-10-11 21:11:30 +08:00
|
|
|
|
// Initialize charging pin (only if it's not NC)
|
|
|
|
|
|
if (charging_pin_ != GPIO_NUM_NC) {
|
|
|
|
|
|
gpio_config_t gpio_cfg = {
|
|
|
|
|
|
.pin_bit_mask = 1ULL << charging_pin,
|
|
|
|
|
|
.mode = GPIO_MODE_INPUT,
|
|
|
|
|
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
|
|
|
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
|
|
|
|
.intr_type = GPIO_INTR_DISABLE,
|
|
|
|
|
|
};
|
|
|
|
|
|
ESP_ERROR_CHECK(gpio_config(&gpio_cfg));
|
|
|
|
|
|
}
|
2025-07-19 22:45:22 +08:00
|
|
|
|
|
|
|
|
|
|
// Initialize ADC battery estimation
|
|
|
|
|
|
adc_battery_estimation_t adc_cfg = {
|
|
|
|
|
|
.internal = {
|
|
|
|
|
|
.adc_unit = adc_unit,
|
2025-10-11 21:11:30 +08:00
|
|
|
|
.adc_bitwidth = ADC_BITWIDTH_DEFAULT,
|
2025-07-19 22:45:22 +08:00
|
|
|
|
.adc_atten = ADC_ATTEN_DB_12,
|
|
|
|
|
|
},
|
|
|
|
|
|
.adc_channel = adc_channel,
|
|
|
|
|
|
.upper_resistor = upper_resistor,
|
|
|
|
|
|
.lower_resistor = lower_resistor
|
|
|
|
|
|
};
|
|
|
|
|
|
adc_cfg.charging_detect_cb = [](void *user_data) -> bool {
|
|
|
|
|
|
AdcBatteryMonitor *self = (AdcBatteryMonitor *)user_data;
|
2025-10-11 21:11:30 +08:00
|
|
|
|
if(self->charging_pin_ == GPIO_NUM_NC)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
else
|
|
|
|
|
|
return gpio_get_level(self->charging_pin_) == 1;
|
2025-07-19 22:45:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
adc_cfg.charging_detect_user_data = this;
|
|
|
|
|
|
adc_battery_estimation_handle_ = adc_battery_estimation_create(&adc_cfg);
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize timer
|
|
|
|
|
|
esp_timer_create_args_t timer_cfg = {
|
|
|
|
|
|
.callback = [](void *arg) {
|
|
|
|
|
|
AdcBatteryMonitor *self = (AdcBatteryMonitor *)arg;
|
|
|
|
|
|
self->CheckBatteryStatus();
|
|
|
|
|
|
},
|
|
|
|
|
|
.arg = this,
|
|
|
|
|
|
.name = "adc_battery_monitor",
|
|
|
|
|
|
};
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_timer_create(&timer_cfg, &timer_handle_));
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle_, 1000000));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AdcBatteryMonitor::~AdcBatteryMonitor() {
|
|
|
|
|
|
if (adc_battery_estimation_handle_) {
|
|
|
|
|
|
ESP_ERROR_CHECK(adc_battery_estimation_destroy(adc_battery_estimation_handle_));
|
|
|
|
|
|
}
|
2025-10-11 21:11:30 +08:00
|
|
|
|
|
|
|
|
|
|
if (timer_handle_) {
|
|
|
|
|
|
esp_timer_stop(timer_handle_);
|
|
|
|
|
|
esp_timer_delete(timer_handle_);
|
|
|
|
|
|
}
|
2025-07-19 22:45:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AdcBatteryMonitor::IsCharging() {
|
2025-10-11 21:11:30 +08:00
|
|
|
|
// 如果没有充电检测引脚,直接返回false
|
|
|
|
|
|
if (charging_pin_ == GPIO_NUM_NC) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果句柄无效,回退到直接读取GPIO
|
|
|
|
|
|
if (adc_battery_estimation_handle_ == nullptr) {
|
|
|
|
|
|
return gpio_get_level(charging_pin_) == 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试通过adc_battery_estimation获取状态
|
2025-07-19 22:45:22 +08:00
|
|
|
|
bool is_charging = false;
|
2025-10-11 21:11:30 +08:00
|
|
|
|
esp_err_t err = adc_battery_estimation_get_charging_state(adc_battery_estimation_handle_, &is_charging);
|
|
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
|
|
// 如果调用失败,回退到直接读取GPIO引脚状态
|
|
|
|
|
|
return gpio_get_level(charging_pin_) == 1;
|
|
|
|
|
|
}
|
2025-07-19 22:45:22 +08:00
|
|
|
|
return is_charging;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AdcBatteryMonitor::IsDischarging() {
|
|
|
|
|
|
return !IsCharging();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t AdcBatteryMonitor::GetBatteryLevel() {
|
2025-10-11 21:11:30 +08:00
|
|
|
|
// 如果句柄无效,返回默认值
|
|
|
|
|
|
if (adc_battery_estimation_handle_ == nullptr) {
|
|
|
|
|
|
return 100;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-19 22:45:22 +08:00
|
|
|
|
float capacity = 0;
|
2025-10-11 21:11:30 +08:00
|
|
|
|
esp_err_t err = adc_battery_estimation_get_capacity(adc_battery_estimation_handle_, &capacity);
|
|
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
|
|
return 100; // 出错时返回默认值
|
|
|
|
|
|
}
|
|
|
|
|
|
return (uint8_t)capacity;
|
2025-07-19 22:45:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AdcBatteryMonitor::OnChargingStatusChanged(std::function<void(bool)> callback) {
|
|
|
|
|
|
on_charging_status_changed_ = callback;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AdcBatteryMonitor::CheckBatteryStatus() {
|
2025-10-11 21:11:30 +08:00
|
|
|
|
// 避免在GPIO_NUM_NC情况下进行检查
|
|
|
|
|
|
if (charging_pin_ == GPIO_NUM_NC) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-19 22:45:22 +08:00
|
|
|
|
bool new_charging_status = IsCharging();
|
|
|
|
|
|
if (new_charging_status != is_charging_) {
|
|
|
|
|
|
is_charging_ = new_charging_status;
|
|
|
|
|
|
if (on_charging_status_changed_) {
|
|
|
|
|
|
on_charging_status_changed_(is_charging_);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|