First of all, I’d like to thank msfujino for all his detective work with the power consumption. I’ve read a lot of your threads, and it’s been super helpful.
I have a question because of a difference in power consumption I’ve noticed between making the same project on xiao-c6 vs xiao-s3.
Here’s my project:
- 2x xiao-c6
- 2x xiao-s3
- Powered via 18650 in dumb holder, directly soldered to bat+, bat-
- Battery power being read via 220k ohm resistor voltage divider to ADC
- code runs every 20 minutes, then sleeps
- code reads temperature from max31855, wifi signal and power from ADC
- code then deep sleeps after values are sent
- code is esphome
- c6 is using external antennae instead of onboard. See on_boot on c6 yaml.
I suspect perhaps it’s the initialization of external antennae initialization, which is only done on the c6. It could be something else. I have no idea. Curious if deep sleep current could get tested with C6 using external wifi.
I’ve noticed that my s3’s are doing much better in battery life, and I don’t think this can simply be explained by deep sleep current, since it’s so small.
HomeAssistant battery usage graphs
I can’t upload so here’s a link
www.imgur [DOT] com/a/XoEoZDd
- Purple is an s3 with max31855
- Brown is an c6 with max31855
- Orange is an c6 but with PT100 & max31865
You’ll notice the battery on the c6’s goes down way faster than the s3. I’ve noticed this with both of my s3’s.
The purple s3 on the graph, has been running since Jan 24th (graph only shows it since the 29th).
Here are my esphome yaml’s
ESP32-C6
substitutions:
name: esp32c6-thermocouple
run_duration_time: 60s
sleep_duration_time: 20min
sensor_update_time: 5s
mac_address: 41a314
ip_address: 192.168.1.156
## Better Deep Sleep
# https://ncrmnt.org/2021/12/06/optimizing-esp8266-esphome-for-battery-power-and-making-an-ice-bath-thermometer-as-well/
# https://tatham.blog/2021/02/06/esphome-batteries-deep-sleep-and-over-the-air-updates/
# https://webbinaro.dev/blog/battery-powered-esp-sensors-esphome/
# https://community.home-assistant.io/t/esphome-api-vs-mqtt-for-deep-sleep-in-2022/440934
# https://community.home-assistant.io/t/loosing-my-mind-esphome-deep-sleep-and-mqtt-wont-work-together/298787
## LIGHT SLEEP
# https://github.com/esphome/feature-requests/issues/141
# https://gist.github.com/nagisa/8d3af3ff8bfd9563d673bb458dfd491d
esphome:
name: ${name}
name_add_mac_suffix: true
# Change from Internal WIFI Antennae to External
on_boot:
- priority: 700.0
then:
lambda: |-
gpio_set_direction(GPIO_NUM_3, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_3, 0);
vTaskDelay(pdMS_TO_TICKS(100));
gpio_set_direction(GPIO_NUM_14, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_14, 1);
- priority: -300
then:
- logger.log: 'START - Consider Deep Sleep'
- script.execute: consider_deep_sleep
- logger.log: 'FINISH - Consider Deep Sleep'
esp32:
board: esp32-c6-devkitc-1
variant: esp32c6
framework:
type: esp-idf
version: "5.3.1"
platform_version: 6.9.0
## https://github.com/esphome/esphome/pull/7942
external_components:
- source: github://pr#7942
refresh: 1d
components:
- adc
- source: github://pr#7988
refresh: 1d
components:
- mqtt
- source:
type: local
path: my_components
components: [ max31855 ]
# Wi-Fi configuration with WPA3
wifi:
power_save_mode: LIGHT # default
fast_connect: true
networks:
- ssid: "ASUS"
password: "XXXXXXXX"
manual_ip:
static_ip: ${ip_address}
gateway: 192.168.1.1
subnet: 255.255.255.0
dns1: 192.168.1.2
ap:
ap_timeout: 1min # default
# Enable logging
logger:
level: DEBUG
logs:
mqtt.component: DEBUG
mqtt.client: DEBUG
# Enable OTA updates
ota:
platform: esphome
on_end:
then:
- logger.log: "Finished OTA Update. Removing ota_mode"
- mqtt.publish:
topic: ${name}-${mac_address}/ota_mode
payload: 'OFF'
retain: true
- globals.set:
id: ota_mode
value: "false"
- delay: 5s
mqtt:
broker: 192.168.1.2
port: 1883
discovery_unique_id_generator: "mac"
discovery_object_id_generator: "device_name"
birth_message:
will_message:
on_message:
- topic: ${name}-${mac_address}/ota_mode
payload: 'ON'
then:
- logger.log: "OTA Mode - ON"
- globals.set:
id: ota_mode
value: "true"
- deep_sleep.prevent: deep_sleep_1
- topic: ${name}-${mac_address}/ota_mode
payload: 'OFF'
then:
- logger.log: "OTA Mode - OFF"
- globals.set:
id: ota_mode
value: "false"
- deep_sleep.allow: deep_sleep_1
deep_sleep:
id: deep_sleep_1
run_duration: ${run_duration_time}
sleep_duration: ${sleep_duration_time}
switch:
- platform: shutdown
id: switch_shutdown
name: "ESP Shutdown"
# max31855
spi:
id: spi_thermo
clk_pin: GPIO19 # SCK pin
miso_pin: GPIO20 # MISO pin
globals:
- id: updates
type: int
restore_value: no
initial_value: '0'
- id: ota_mode
type: bool
restore_value: yes
initial_value: "false"
sensor:
- platform: wifi_signal
name: "WiFi Signal"
id: wifi_signalzzz
update_interval: never
on_value:
- logger.log: 'UPDATED Wifi Signalzzz'
- lambda: |-
id(updates)++;
- platform: max31855
name: "K Thermocouple Temperature"
id: k_thermocouple
cs_pin: GPIO17
spi_id: spi_thermo
accuracy_decimals: 1
update_interval: never
on_value:
- logger.log: 'UPDATED Thermocouple'
- lambda: |-
id(updates)++;
reference_temperature:
name: "Reference Temp"
id: ref_temp
on_value:
- logger.log: 'UPDATED RefTemp'
- lambda: |-
id(updates)++;
- platform: adc
name: "Battery Voltage"
id: adc_vcc
attenuation: 12db
pin: GPIO0
accuracy_decimals: 2
samples: 16 # should be 16, default 1
update_interval: never
filters:
- multiply: 2.0
on_value:
- logger.log: 'UPDATED Battery Voltage'
- lambda: |-
id(updates)++;
## https://webbinaro.dev/blog/battery-powered-esp-sensors-esphome/
script:
- id: consider_deep_sleep
mode: queued
then:
- logger.log: 'Doing UPDATES'
- lambda: |-
id(updates) = 0;
id(k_thermocouple).update();
id(adc_vcc).update();
id(wifi_signalzzz).update();
- logger.log: 'Waiting for UPDATES'
- wait_until:
lambda: |-
return (id(updates) >= 4);
- logger.log: 'DONE Waiting for UPDATES'
- logger.log:
format: 'Batt: %3.2f, wifi: %3.2f, temp: %3.2f, ref_temp: %3.2f'
args: [ id(adc_vcc).state, id(wifi_signalzzz).state, id(k_thermocouple).state, id(ref_temp).state ]
- delay: 200ms
- if:
## It appears that id(vcc).state doesn't go through the multiplyer.
condition:
# On USB power is 3.7/2 1.34
lambda: 'return ((id(adc_vcc).state) < 3.0 && id(adc_vcc).state > 2.0);'
then:
- logger.log:
level: ERROR
format: 'Going to sleep. VOLTS under 3 %3.2f'
args: [ id(adc_vcc).state ]
- lambda: |-
id(switch_shutdown).turn_on();
else:
- logger.log:
format: 'Going to sleep for X amount of time. Prevent? %d'
args: [ id(ota_mode) ]
- lambda: |-
id(deep_sleep_1).begin_sleep(false);
## Can't use deep_sleep.enter, as it doesn't obey prevent_sleep
# - deep_sleep.enter:
# id: deep_sleep_1
# sleep_duration: ${sleep_duration_time}
ESP32-S3
substitutions:
name: esp32s3-thermocouple
run_duration_time: 60s
sleep_duration_time: 20min
sensor_update_time: 5s
mac_address: ed061c
ip_address: 192.168.1.159
## Better Deep Sleep
# https://ncrmnt.org/2021/12/06/optimizing-esp8266-esphome-for-battery-power-and-making-an-ice-bath-thermometer-as-well/
# https://tatham.blog/2021/02/06/esphome-batteries-deep-sleep-and-over-the-air-updates/
# https://webbinaro.dev/blog/battery-powered-esp-sensors-esphome/
# https://community.home-assistant.io/t/esphome-api-vs-mqtt-for-deep-sleep-in-2022/440934
# https://community.home-assistant.io/t/loosing-my-mind-esphome-deep-sleep-and-mqtt-wont-work-together/298787
## LIGHT SLEEP
# https://github.com/esphome/feature-requests/issues/141
# https://gist.github.com/nagisa/8d3af3ff8bfd9563d673bb458dfd491d
esphome:
name: ${name}
name_add_mac_suffix: true
platformio_options:
build_flags: -DBOARD_HAS_PSRAM
board_build.arduino.memory_type: qio_opi
board_build.f_flash: 80000000L
board_build.flash_mode: qio
on_boot:
- priority: -300
then:
- logger.log: 'START - Consider Deep Sleep'
- script.execute: consider_deep_sleep
- logger.log: 'FINISH - Consider Deep Sleep'
esp32:
board: seeed_xiao_esp32s3
variant: esp32s3
framework:
type: esp-idf
version: "5.3.1"
platform_version: 6.9.0
## https://github.com/esphome/esphome/pull/7942
external_components:
- source: github://pr#7942
refresh: 1d
components:
- adc
- source: github://pr#7988
refresh: 1d
components:
- mqtt
- source:
type: local
path: my_components
components: [ max31855 ]
# Wi-Fi configuration with WPA3
wifi:
power_save_mode: LIGHT # default
fast_connect: true
networks:
- ssid: "ASUS"
password: "XXXXXXXXXXXX"
manual_ip:
static_ip: ${ip_address}
gateway: 192.168.1.1
subnet: 255.255.255.0
dns1: 192.168.1.2
ap:
ap_timeout: 1min # default
# Enable logging
logger:
level: WARN
logs:
mqtt.component: WARN
mqtt.client: WARN
# Enable OTA updates
ota:
platform: esphome
on_end:
then:
- logger.log: "Finished OTA Update. Removing ota_mode"
- mqtt.publish:
topic: ${name}-${mac_address}/ota_mode
payload: 'OFF'
retain: true
- globals.set:
id: ota_mode
value: "false"
- delay: 5s
mqtt:
broker: 192.168.1.2
port: 1883
discovery_unique_id_generator: "mac"
discovery_object_id_generator: "device_name"
birth_message:
will_message:
on_message:
- topic: ${name}-${mac_address}/ota_mode
payload: 'ON'
then:
- logger.log: "OTA Mode - ON"
- globals.set:
id: ota_mode
value: "true"
- deep_sleep.prevent: deep_sleep_1
- topic: ${name}-${mac_address}/ota_mode
payload: 'OFF'
then:
- logger.log: "OTA Mode - OFF"
- globals.set:
id: ota_mode
value: "false"
- deep_sleep.allow: deep_sleep_1
deep_sleep:
id: deep_sleep_1
run_duration: ${run_duration_time}
sleep_duration: ${sleep_duration_time}
switch:
- platform: shutdown
id: switch_shutdown
name: "ESP Shutdown"
# max31855
spi:
id: spi_thermo
clk_pin: GPIO7 # SCK pin
miso_pin: GPIO8 # MISO pin
globals:
- id: updates
type: int
restore_value: no
initial_value: '0'
- id: ota_mode
type: bool
restore_value: yes
initial_value: "false"
sensor:
- platform: wifi_signal
name: "WiFi Signal"
id: wifi_signalzzz
update_interval: never
on_value:
- logger.log: 'UPDATED Wifi Signalzzz'
- lambda: |-
id(updates)++;
- platform: max31855
name: "K Thermocouple Temperature"
id: k_thermocouple
cs_pin: GPIO44
spi_id: spi_thermo
accuracy_decimals: 1
update_interval: never
on_value:
- logger.log: 'UPDATED Thermocouple'
- lambda: |-
id(updates)++;
reference_temperature:
name: "Reference Temp"
id: ref_temp
on_value:
- logger.log: 'UPDATED RefTemp'
- lambda: |-
id(updates)++;
- platform: adc
name: "Battery Voltage"
id: adc_vcc
attenuation: 12db
pin: GPIO1
accuracy_decimals: 2
samples: 16 # should be 16, default 1
update_interval: never
filters:
- multiply: 2.0
on_value:
- logger.log: 'UPDATED Battery Voltage'
- lambda: |-
id(updates)++;
## https://webbinaro.dev/blog/battery-powered-esp-sensors-esphome/
script:
- id: consider_deep_sleep
mode: queued
then:
- logger.log: 'Doing UPDATES'
- lambda: |-
id(updates) = 0;
id(k_thermocouple).update();
id(adc_vcc).update();
id(wifi_signalzzz).update();
- logger.log: 'Waiting for UPDATES'
- wait_until:
lambda: |-
return (id(updates) >= 4);
- logger.log: 'DONE Waiting for UPDATES'
- logger.log:
format: 'Batt: %3.2f, wifi: %3.2f, temp: %3.2f, ref_temp: %3.2f'
args: [ id(adc_vcc).state, id(wifi_signalzzz).state, id(k_thermocouple).state, id(ref_temp).state ]
- delay: 200ms
- if:
## It appears that id(vcc).state doesn't go through the multiplyer.
condition:
# On USB power is 3.7/2 1.34
lambda: 'return ((id(adc_vcc).state) < 3.0 && id(adc_vcc).state > 2.0);'
then:
- logger.log:
level: ERROR
format: 'Going to sleep. VOLTS under 3 %3.2f'
args: [ id(adc_vcc).state ]
- lambda: |-
id(switch_shutdown).turn_on();
else:
- logger.log:
format: 'Going to sleep for X amount of time. Prevent? %d'
args: [ id(ota_mode) ]
- lambda: |-
id(deep_sleep_1).begin_sleep(false);
## Can't use deep_sleep.enter, as it doesn't obey prevent_sleep
# - deep_sleep.enter:
# id: deep_sleep_1
# sleep_duration: ${sleep_duration_time}
Any insights would be appreciated.