Guest User

Untitled

a guest
Dec 23rd, 2025
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.92 KB | None | 0 0
  1. I have an ESP32-S3-1.69-LCD board and a 110mAh LiPo battery.
  2. 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.
  3. I could really do with some pointers from someone who knows what they're doing.
  4. Here's what I've found so far...
  5. 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.
  6. I tried adapting one of the ESP-IDF example programs to read the battery voltage. Here's my code:
  7. #include <stdio.h>
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "esp_log.h"
  11. #include "esp_adc/adc_oneshot.h"
  12. #include "esp_adc/adc_cali.h"
  13. #include "esp_adc/adc_cali_scheme.h"
  14.  
  15. static const char *TAG = "BAT";
  16.  
  17. void app_main(void)
  18. {
  19. adc_oneshot_unit_handle_t adc_handle;
  20. adc_oneshot_unit_init_cfg_t init_config = {
  21. .unit_id = ADC_UNIT_1,
  22. };
  23. adc_oneshot_new_unit(&init_config, &adc_handle);
  24.  
  25. adc_oneshot_chan_cfg_t config = {
  26. .atten = ADC_ATTEN_DB_12,
  27. .bitwidth = ADC_BITWIDTH_DEFAULT,
  28. };
  29. adc_oneshot_config_channel(adc_handle, ADC_CHANNEL_0, &config);
  30.  
  31. // Setup calibration
  32. adc_cali_handle_t cali_handle;
  33. adc_cali_curve_fitting_config_t cali_config = {
  34. .unit_id = ADC_UNIT_1,
  35. .chan = ADC_CHANNEL_0,
  36. .atten = ADC_ATTEN_DB_12,
  37. .bitwidth = ADC_BITWIDTH_DEFAULT,
  38. };
  39. adc_cali_create_scheme_curve_fitting(&cali_config, &cali_handle);
  40.  
  41. // Read loop
  42. while (1) {
  43. int raw, voltage_mv;
  44.  
  45. adc_oneshot_read(adc_handle, ADC_CHANNEL_0, &raw);
  46. adc_cali_raw_to_voltage(cali_handle, raw, &voltage_mv);
  47.  
  48. // Apply 3x voltage divider (200k + 100k resistors)
  49. int battery_mv = voltage_mv * 3;
  50.  
  51. ESP_LOGI(TAG, "Battery: %d mV (%.2f V)", battery_mv, battery_mv / 1000.0);
  52.  
  53. vTaskDelay(pdMS_TO_TICKS(1000));
  54. }
  55. }
  56. 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.
  57. I don't really understand the output from this program:
  58. I (20269) BAT: Battery: 309 mV (0.31 V)
  59. I (21269) BAT: Battery: 0 mV (0.00 V)
  60. I (22269) BAT: Battery: 0 mV (0.00 V)
  61. I (23269) BAT: Battery: 7 mV (0.01 V)
  62. I (24269) BAT: Battery: 293 mV (0.29 V)
  63. I (25269) BAT: Battery: 0 mV (0.00 V)
  64. I (26269) BAT: Battery: 0 mV (0.00 V)
  65. I (27269) BAT: Battery: 0 mV (0.00 V)
  66. I (28269) BAT: Battery: 246 mV (0.25 V)d
  67. I (29269) BAT: Battery: 0 mV (0.00 V)
  68. I (30269) BAT: Battery: 0 mV (0.00 V)
  69. I (31269) BAT: Battery: 0 mV (0.00 V)
  70. I (32269) BAT: Battery: 157 mV (0.16 V)
  71. I (33269) BAT: Battery: 165 mV (0.17 V)
  72. // -- battery unplugged --
  73. I (34269) BAT: Battery: 1392 mV (1.39 V)
  74. I (35269) BAT: Battery: 1393 mV (1.39 V)
  75. I (36269) BAT: Battery: 1391 mV (1.39 V)
  76. I (37269) BAT: Battery: 1391 mV (1.39 V)
  77. I (38269) BAT: Battery: 1391 mV (1.39 V)
  78. I (39269) BAT: Battery: 1391 mV (1.39 V)
  79. // -- battery plugged in --
  80. I (40269) BAT: Battery: 371 mV (0.37 V)
  81. I (41269) BAT: Battery: 0 mV (0.00 V)
  82. I (42269) BAT: Battery: 0 mV (0.00 V)
  83. I (43269) BAT: Battery: 106 mV (0.11 V)
  84. I (44269) BAT: Battery: 287 mV (0.29 V)
  85. I (45269) BAT: Battery: 0 mV (0.00 V)
  86. I (46269) BAT: Battery: 0 mV (0.00 V)
  87. // -- reset button pressed --
  88. --- Error: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
  89. --- Waiting for the device to reconnect.
  90. I (1279) BAT: Battery: 0 mV (0.00 V)
  91. I (2279) BAT: Battery: 83 mV (0.08 V)
  92. I (3279) BAT: Battery: 304 mV (0.30 V)
  93. I (4279) BAT: Battery: 0 mV (0.00 V)
  94. I (5279) BAT: Battery: 0 mV (0.00 V)
  95. // -- device unplugged & plugged back in --
  96. I (1269) BAT: Battery: 1385 mV (1.39 V)
  97. I (2269) BAT: Battery: 1385 mV (1.39 V)
  98. I (3269) BAT: Battery: 1385 mV (1.39 V)
  99. I (4269) BAT: Battery: 1385 mV (1.39 V)
  100. I (5269) BAT: Battery: 1385 mV (1.39 V)
  101. // -- battery unplugged --
  102. I (6269) BAT: Battery: 1384 mV (1.38 V)
  103. I (7269) BAT: Battery: 1384 mV (1.38 V)
  104. I (8269) BAT: Battery: 1384 mV (1.38 V)
  105. I (9269) BAT: Battery: 1384 mV (1.38 V)
  106. // -- battery plugged back in --
  107. I (10269) BAT: Battery: 1386 mV (1.39 V)
  108. I (11269) BAT: Battery: 1384 mV (1.38 V)
  109. I (12269) BAT: Battery: 1387 mV (1.39 V)
  110. I (13269) BAT: Battery: 1388 mV (1.39 V)
  111. I (14269) BAT: Battery: 1388 mV (1.39 V)
  112. // -- flashed again --
  113. I (269) BAT: Battery: 1391 mV (1.39 V)
  114. I (1269) BAT: Battery: 1391 mV (1.39 V)
  115. I (2269) BAT: Battery: 1391 mV (1.39 V)
  116. I (3269) BAT: Battery: 1391 mV (1.39 V)
  117. I can't make heads nor tails of this output... which indicates I've done something wrong and/or don't understand something properly.
  118. 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`:
  119. #include <lvgl.h>
  120. #include "Arduino_GFX_Library.h"
  121. #include "lv_conf.h"
  122. #include "demos/lv_demos.h"
  123. #include "pin_config.h"
  124.  
  125. /* Using LVGL with Arduino requires some extra steps:
  126. * Be sure to read the docs here: https://docs.lvgl.io/master/get-started/platforms/arduino.html */
  127.  
  128. #define EXAMPLE_LVGL_TICK_PERIOD_MS 2
  129.  
  130. /* Change to your screen resolution */
  131. static const uint16_t screenWidth = 240;
  132. static const uint16_t screenHeight = 280;
  133.  
  134. static lv_disp_draw_buf_t draw_buf;
  135. static lv_color_t buf[screenWidth * screenHeight / 10];
  136. const int voltageDividerPin = 1; // GPIO1 pin
  137. float vRef = 3.3; // ESP32-S3的供电电压(单位:伏特)
  138. float R1 = 200000.0; // 第一个电阻的阻值(单位:欧姆)
  139. float R2 = 100000.0; // 第二个电阻的阻值(单位:欧姆)
  140.  
  141. lv_obj_t *label; // Global label object
  142.  
  143. Arduino_DataBus *bus = new Arduino_ESP32SPI(LCD_DC, LCD_CS, LCD_SCK, LCD_MOSI);
  144.  
  145. Arduino_GFX *gfx = new Arduino_ST7789(bus, LCD_RST /* RST */,
  146. 0 /* rotation */, true /* IPS */, LCD_WIDTH, LCD_HEIGHT, 0, 20, 0, 0);
  147.  
  148. #if LV_USE_LOG != 0
  149. /* Serial debugging */
  150. void my_print(const char *buf) {
  151. Serial.printf(buf);
  152. Serial.flush();
  153. }
  154. #endif
  155.  
  156. /* Display flushing */
  157. void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  158. uint32_t w = (area->x2 - area->x1 + 1);
  159. uint32_t h = (area->y2 - area->y1 + 1);
  160.  
  161. #if (LV_COLOR_16_SWAP != 0)
  162. gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
  163. #else
  164. gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
  165. #endif
  166.  
  167. lv_disp_flush_ready(disp);
  168. }
  169.  
  170. void example_increase_lvgl_tick(void *arg) {
  171. /* Tell LVGL how many milliseconds has elapsed */
  172. lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS);
  173. }
  174.  
  175. static uint8_t count = 0;
  176. void example_increase_reboot(void *arg) {
  177. count++;
  178. if (count == 30) {
  179. esp_restart();
  180. }
  181. }
  182.  
  183. void setup() {
  184. Serial.begin(115200); /* prepare for possible serial debug */
  185. pinMode(voltageDividerPin, INPUT);
  186.  
  187. String LVGL_Arduino = "Hello Arduino! ";
  188. LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
  189.  
  190. Serial.println(LVGL_Arduino);
  191. Serial.println("I am LVGL_Arduino");
  192.  
  193. lv_init();
  194.  
  195. #if LV_USE_LOG != 0
  196. lv_log_register_print_cb(my_print); /* register print function for debugging */
  197. #endif
  198.  
  199. gfx->begin();
  200. pinMode(LCD_BL, OUTPUT);
  201. digitalWrite(LCD_BL, HIGH);
  202.  
  203. lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * screenHeight / 10);
  204.  
  205. /* Initialize the display */
  206. static lv_disp_drv_t disp_drv;
  207. lv_disp_drv_init(&disp_drv);
  208. /* Change the following line to your display resolution */
  209. disp_drv.hor_res = screenWidth;
  210. disp_drv.ver_res = screenHeight;
  211. disp_drv.flush_cb = my_disp_flush;
  212. disp_drv.draw_buf = &draw_buf;
  213. lv_disp_drv_register(&disp_drv);
  214.  
  215. const esp_timer_create_args_t lvgl_tick_timer_args = {
  216. .callback = &example_increase_lvgl_tick,
  217. .name = "lvgl_tick"
  218. };
  219.  
  220. const esp_timer_create_args_t reboot_timer_args = {
  221. .callback = &example_increase_reboot,
  222. .name = "reboot"
  223. };
  224.  
  225. esp_timer_handle_t lvgl_tick_timer = NULL;
  226. esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer);
  227. esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000);
  228.  
  229. // esp_timer_handle_t reboot_timer = NULL;
  230. // esp_timer_create(&reboot_timer_args, &reboot_timer);
  231. // esp_timer_start_periodic(reboot_timer, 2000 * 1000);
  232.  
  233. /* Create label */
  234. label = lv_label_create(lv_scr_act());
  235. lv_label_set_text(label, "Initializing...");
  236. lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
  237.  
  238. Serial.println("Setup done");
  239. }
  240.  
  241. void loop() {
  242. lv_timer_handler(); /* let the GUI do its work */
  243. delay(5);
  244.  
  245. // 读取ADC值
  246. int adcValue = analogRead(voltageDividerPin);
  247.  
  248. // 转换为电压
  249. float voltage = (float)adcValue * (vRef / 4095.0);
  250.  
  251. // 应用分压公式来计算实际电压
  252. float actualVoltage = voltage * ((R1 + R2) / R2);
  253.  
  254. // 打印实际电压
  255. Serial.print("Actual Voltage: ");
  256. Serial.print(actualVoltage);
  257. Serial.println(" V");
  258.  
  259. // 更新标签内容
  260. String voltageStr = "Actual Voltage: " + String(actualVoltage) + " V";
  261. lv_label_set_text(label, voltageStr.c_str());
  262. }
  263. But I wasn't able to find much of use here other than the calculations for converting the voltage readings.
  264. What I'd like to do, is:
  265. Read the current charge of the battery
  266. Recharge the battery when the device is plugged in with USB-C
  267. Power the device from the battery when the device is not plugged in with USB-C
  268. 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:
  269. ESP32-S3-LCD-1.69 Schematic diagram-V2
  270. ESP32-S3 Datasheet
  271. ESP32-S3 Technical reference manual
  272. 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