Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- I have an ESP32-S3-1.69-LCD board and a 110mAh LiPo battery.
- Presumably naively, I had assumed that if I plug the battery into the board, leave it plugged in via USB-C for a while, then unplug the USB-C, the board would continue to be powered by the battery... This did not happen.
- I could really do with some pointers from someone who knows what they're doing.
- Here's what I've found so far...
- The schematic diagram shows GPIO1 is BAT_ADC, which I'm guessing is short for "Battery Analog to Digital Converter". My understanding is that this would allow me to read the battery voltage.
- I tried adapting one of the ESP-IDF example programs to read the battery voltage. Here's my code:
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "esp_log.h"
- #include "esp_adc/adc_oneshot.h"
- #include "esp_adc/adc_cali.h"
- #include "esp_adc/adc_cali_scheme.h"
- static const char *TAG = "BAT";
- void app_main(void)
- {
- adc_oneshot_unit_handle_t adc_handle;
- adc_oneshot_unit_init_cfg_t init_config = {
- .unit_id = ADC_UNIT_1,
- };
- adc_oneshot_new_unit(&init_config, &adc_handle);
- adc_oneshot_chan_cfg_t config = {
- .atten = ADC_ATTEN_DB_12,
- .bitwidth = ADC_BITWIDTH_DEFAULT,
- };
- adc_oneshot_config_channel(adc_handle, ADC_CHANNEL_0, &config);
- // Setup calibration
- adc_cali_handle_t cali_handle;
- adc_cali_curve_fitting_config_t cali_config = {
- .unit_id = ADC_UNIT_1,
- .chan = ADC_CHANNEL_0,
- .atten = ADC_ATTEN_DB_12,
- .bitwidth = ADC_BITWIDTH_DEFAULT,
- };
- adc_cali_create_scheme_curve_fitting(&cali_config, &cali_handle);
- // Read loop
- while (1) {
- int raw, voltage_mv;
- adc_oneshot_read(adc_handle, ADC_CHANNEL_0, &raw);
- adc_cali_raw_to_voltage(cali_handle, raw, &voltage_mv);
- // Apply 3x voltage divider (200k + 100k resistors)
- int battery_mv = voltage_mv * 3;
- ESP_LOGI(TAG, "Battery: %d mV (%.2f V)", battery_mv, battery_mv / 1000.0);
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- }
- Based on the ESP32-S3 datasheet ADC1_CH0 corresponds to GPIO1 (BAT_ADC), hence in the above code I've set ADC_UNIUT_1 and ADC_CHANNEL_0.
- I don't really understand the output from this program:
- I (20269) BAT: Battery: 309 mV (0.31 V)
- I (21269) BAT: Battery: 0 mV (0.00 V)
- I (22269) BAT: Battery: 0 mV (0.00 V)
- I (23269) BAT: Battery: 7 mV (0.01 V)
- I (24269) BAT: Battery: 293 mV (0.29 V)
- I (25269) BAT: Battery: 0 mV (0.00 V)
- I (26269) BAT: Battery: 0 mV (0.00 V)
- I (27269) BAT: Battery: 0 mV (0.00 V)
- I (28269) BAT: Battery: 246 mV (0.25 V)d
- I (29269) BAT: Battery: 0 mV (0.00 V)
- I (30269) BAT: Battery: 0 mV (0.00 V)
- I (31269) BAT: Battery: 0 mV (0.00 V)
- I (32269) BAT: Battery: 157 mV (0.16 V)
- I (33269) BAT: Battery: 165 mV (0.17 V)
- // -- battery unplugged --
- I (34269) BAT: Battery: 1392 mV (1.39 V)
- I (35269) BAT: Battery: 1393 mV (1.39 V)
- I (36269) BAT: Battery: 1391 mV (1.39 V)
- I (37269) BAT: Battery: 1391 mV (1.39 V)
- I (38269) BAT: Battery: 1391 mV (1.39 V)
- I (39269) BAT: Battery: 1391 mV (1.39 V)
- // -- battery plugged in --
- I (40269) BAT: Battery: 371 mV (0.37 V)
- I (41269) BAT: Battery: 0 mV (0.00 V)
- I (42269) BAT: Battery: 0 mV (0.00 V)
- I (43269) BAT: Battery: 106 mV (0.11 V)
- I (44269) BAT: Battery: 287 mV (0.29 V)
- I (45269) BAT: Battery: 0 mV (0.00 V)
- I (46269) BAT: Battery: 0 mV (0.00 V)
- // -- reset button pressed --
- --- Error: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
- --- Waiting for the device to reconnect.
- I (1279) BAT: Battery: 0 mV (0.00 V)
- I (2279) BAT: Battery: 83 mV (0.08 V)
- I (3279) BAT: Battery: 304 mV (0.30 V)
- I (4279) BAT: Battery: 0 mV (0.00 V)
- I (5279) BAT: Battery: 0 mV (0.00 V)
- // -- device unplugged & plugged back in --
- I (1269) BAT: Battery: 1385 mV (1.39 V)
- I (2269) BAT: Battery: 1385 mV (1.39 V)
- I (3269) BAT: Battery: 1385 mV (1.39 V)
- I (4269) BAT: Battery: 1385 mV (1.39 V)
- I (5269) BAT: Battery: 1385 mV (1.39 V)
- // -- battery unplugged --
- I (6269) BAT: Battery: 1384 mV (1.38 V)
- I (7269) BAT: Battery: 1384 mV (1.38 V)
- I (8269) BAT: Battery: 1384 mV (1.38 V)
- I (9269) BAT: Battery: 1384 mV (1.38 V)
- // -- battery plugged back in --
- I (10269) BAT: Battery: 1386 mV (1.39 V)
- I (11269) BAT: Battery: 1384 mV (1.38 V)
- I (12269) BAT: Battery: 1387 mV (1.39 V)
- I (13269) BAT: Battery: 1388 mV (1.39 V)
- I (14269) BAT: Battery: 1388 mV (1.39 V)
- // -- flashed again --
- I (269) BAT: Battery: 1391 mV (1.39 V)
- I (1269) BAT: Battery: 1391 mV (1.39 V)
- I (2269) BAT: Battery: 1391 mV (1.39 V)
- I (3269) BAT: Battery: 1391 mV (1.39 V)
- I can't make heads nor tails of this output... which indicates I've done something wrong and/or don't understand something properly.
- I've also reviewed the code in `ESP32-S3-LCD-1.69_DemoCode/Arduino-v3.0.5/example/06_LVGL_Measuring_voltage/06_LVGL_Measuring_voltage.ino`:
- #include <lvgl.h>
- #include "Arduino_GFX_Library.h"
- #include "lv_conf.h"
- #include "demos/lv_demos.h"
- #include "pin_config.h"
- /* Using LVGL with Arduino requires some extra steps:
- * Be sure to read the docs here: https://docs.lvgl.io/master/get-started/platforms/arduino.html */
- #define EXAMPLE_LVGL_TICK_PERIOD_MS 2
- /* Change to your screen resolution */
- static const uint16_t screenWidth = 240;
- static const uint16_t screenHeight = 280;
- static lv_disp_draw_buf_t draw_buf;
- static lv_color_t buf[screenWidth * screenHeight / 10];
- const int voltageDividerPin = 1; // GPIO1 pin
- float vRef = 3.3; // ESP32-S3的供电电压(单位:伏特)
- float R1 = 200000.0; // 第一个电阻的阻值(单位:欧姆)
- float R2 = 100000.0; // 第二个电阻的阻值(单位:欧姆)
- lv_obj_t *label; // Global label object
- Arduino_DataBus *bus = new Arduino_ESP32SPI(LCD_DC, LCD_CS, LCD_SCK, LCD_MOSI);
- Arduino_GFX *gfx = new Arduino_ST7789(bus, LCD_RST /* RST */,
- 0 /* rotation */, true /* IPS */, LCD_WIDTH, LCD_HEIGHT, 0, 20, 0, 0);
- #if LV_USE_LOG != 0
- /* Serial debugging */
- void my_print(const char *buf) {
- Serial.printf(buf);
- Serial.flush();
- }
- #endif
- /* Display flushing */
- void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
- uint32_t w = (area->x2 - area->x1 + 1);
- uint32_t h = (area->y2 - area->y1 + 1);
- #if (LV_COLOR_16_SWAP != 0)
- gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
- #else
- gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
- #endif
- lv_disp_flush_ready(disp);
- }
- void example_increase_lvgl_tick(void *arg) {
- /* Tell LVGL how many milliseconds has elapsed */
- lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS);
- }
- static uint8_t count = 0;
- void example_increase_reboot(void *arg) {
- count++;
- if (count == 30) {
- esp_restart();
- }
- }
- void setup() {
- Serial.begin(115200); /* prepare for possible serial debug */
- pinMode(voltageDividerPin, INPUT);
- String LVGL_Arduino = "Hello Arduino! ";
- LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
- Serial.println(LVGL_Arduino);
- Serial.println("I am LVGL_Arduino");
- lv_init();
- #if LV_USE_LOG != 0
- lv_log_register_print_cb(my_print); /* register print function for debugging */
- #endif
- gfx->begin();
- pinMode(LCD_BL, OUTPUT);
- digitalWrite(LCD_BL, HIGH);
- lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * screenHeight / 10);
- /* Initialize the display */
- static lv_disp_drv_t disp_drv;
- lv_disp_drv_init(&disp_drv);
- /* Change the following line to your display resolution */
- disp_drv.hor_res = screenWidth;
- disp_drv.ver_res = screenHeight;
- disp_drv.flush_cb = my_disp_flush;
- disp_drv.draw_buf = &draw_buf;
- lv_disp_drv_register(&disp_drv);
- const esp_timer_create_args_t lvgl_tick_timer_args = {
- .callback = &example_increase_lvgl_tick,
- .name = "lvgl_tick"
- };
- const esp_timer_create_args_t reboot_timer_args = {
- .callback = &example_increase_reboot,
- .name = "reboot"
- };
- esp_timer_handle_t lvgl_tick_timer = NULL;
- esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer);
- esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000);
- // esp_timer_handle_t reboot_timer = NULL;
- // esp_timer_create(&reboot_timer_args, &reboot_timer);
- // esp_timer_start_periodic(reboot_timer, 2000 * 1000);
- /* Create label */
- label = lv_label_create(lv_scr_act());
- lv_label_set_text(label, "Initializing...");
- lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
- Serial.println("Setup done");
- }
- void loop() {
- lv_timer_handler(); /* let the GUI do its work */
- delay(5);
- // 读取ADC值
- int adcValue = analogRead(voltageDividerPin);
- // 转换为电压
- float voltage = (float)adcValue * (vRef / 4095.0);
- // 应用分压公式来计算实际电压
- float actualVoltage = voltage * ((R1 + R2) / R2);
- // 打印实际电压
- Serial.print("Actual Voltage: ");
- Serial.print(actualVoltage);
- Serial.println(" V");
- // 更新标签内容
- String voltageStr = "Actual Voltage: " + String(actualVoltage) + " V";
- lv_label_set_text(label, voltageStr.c_str());
- }
- But I wasn't able to find much of use here other than the calculations for converting the voltage readings.
- What I'd like to do, is:
- Read the current charge of the battery
- Recharge the battery when the device is plugged in with USB-C
- Power the device from the battery when the device is not plugged in with USB-C
- The product listing states that the board includes a "3.7V MX1.25 lithium battery recharge/discharge header", which implies 2 and 3 should be possible, but as far as I can tell, there is no documentation for how to do this. I've checked:
- ESP32-S3-LCD-1.69 Schematic diagram-V2
- ESP32-S3 Datasheet
- ESP32-S3 Technical reference manual
- I'd be very grateful if anyone can point me in the right direction, as I'm pretty stumped.
Advertisement
Add Comment
Please, Sign In to add comment