Files
xiaozhi-esp32/main/boards/common/adc_battery_monitor.cc
Xiaoxia 3ced7709c6 Update to v1.9.4 (#1374)
* fix: Corrected the inverted touch screen parameter configuration of lichuang_S3_dev, which caused touch offset. (#1209)

* ci: support multiple variants per board (#1036)

* fix release.py

* OTTO 左右腿反了 (#1239)

* Change the button array to ADC buttons as in the board for esp32s3-korv2 (#1256)

* Change the button array to ADC buttons as in the board for esp32s3-korv2

* Add MuteVol function to control audio volume

* Optimize AdcBatteryMonitor to work without charge detection pin. (#1276)

Co-authored-by: Yuv Zhao <admin@yuvcloud.com>

* 修复charging_pin为NC充电时Battery Level不更新的问题 (#1316)

Co-authored-by: Yuv Zhao <admin@yuvcloud.com>

* Bump to 1.9.4

---------

Co-authored-by: ZhouShaoYuan <cnfalcon@qq.com>
Co-authored-by: laride <198868291+laride@users.noreply.github.com>
Co-authored-by: Toby <naivetoby@gmail.com>
Co-authored-by: masc2008 <masc2008@gmail.com>
Co-authored-by: konglingboy <konglingboy@sina.com>
Co-authored-by: Yuv Zhao <admin@yuvcloud.com>
2025-11-04 05:03:40 +08:00

116 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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) {
// 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));
}
// Initialize ADC battery estimation
adc_battery_estimation_t adc_cfg = {
.internal = {
.adc_unit = adc_unit,
.adc_bitwidth = ADC_BITWIDTH_DEFAULT,
.adc_atten = ADC_ATTEN_DB_12,
},
.adc_channel = adc_channel,
.upper_resistor = upper_resistor,
.lower_resistor = lower_resistor
};
// 在ADC配置部分进行条件设置
if (charging_pin_ != GPIO_NUM_NC) {
adc_cfg.charging_detect_cb = [](void *user_data) -> bool {
AdcBatteryMonitor *self = (AdcBatteryMonitor *)user_data;
return gpio_get_level(self->charging_pin_) == 1;
};
adc_cfg.charging_detect_user_data = this;
} else {
// 不设置回调让adc_battery_estimation库使用软件估算
adc_cfg.charging_detect_cb = nullptr;
adc_cfg.charging_detect_user_data = nullptr;
}
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_));
}
if (timer_handle_) {
esp_timer_stop(timer_handle_);
esp_timer_delete(timer_handle_);
}
}
bool AdcBatteryMonitor::IsCharging() {
// 优先使用adc_battery_estimation库的功能
if (adc_battery_estimation_handle_ != nullptr) {
bool is_charging = false;
esp_err_t err = adc_battery_estimation_get_charging_state(adc_battery_estimation_handle_, &is_charging);
if (err == ESP_OK) {
return is_charging;
}
}
// 回退到GPIO读取或返回默认值
if (charging_pin_ != GPIO_NUM_NC) {
return gpio_get_level(charging_pin_) == 1;
}
return false;
}
bool AdcBatteryMonitor::IsDischarging() {
return !IsCharging();
}
uint8_t AdcBatteryMonitor::GetBatteryLevel() {
// 如果句柄无效,返回默认值
if (adc_battery_estimation_handle_ == nullptr) {
return 100;
}
float capacity = 0;
esp_err_t err = adc_battery_estimation_get_capacity(adc_battery_estimation_handle_, &capacity);
if (err != ESP_OK) {
return 100; // 出错时返回默认值
}
return (uint8_t)capacity;
}
void AdcBatteryMonitor::OnChargingStatusChanged(std::function<void(bool)> callback) {
on_charging_status_changed_ = callback;
}
void AdcBatteryMonitor::CheckBatteryStatus() {
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_);
}
}
}