Implementing Low-Energy Smart Devices with Several Years of Independence

Attila Farago
4 min readJun 24, 2023

--

Microcontrollers such as ESP8266 and ESP32 from Espressif Systems are a cost effective way to deploy your C++ code and use to the local WiFi network and connect to Bluetooth device over Bluetooth Low Energy.

Bluetooth on a low-cost Wi-Fi microchip

ESPHome is an awesome low-code environment to implement an smart Arduino microcontroller node with a 2–3 EUR device.

Recently BTHome protocol has been created to support an open standard for broadcasting sensor data and button presses over Bluetooth LE.

As of now central hubs such as Home Assistant support BTHome reception, however independent processing on the edge has been suggested. That needs a hub such as a Raspberry Pi or a Mini-PC and scenario triggering that depends on local WiFi — introducing both delay and risks of downtime.

I have implemented bthome_receiver component to add low-code support for standalone reception of a Bluetooth Low Energy BTHome device.

Implementing a low energy smart device over WiFi

Bluetooth should not limit our imagination of implementing low energy devices. Why not connect a battery-powered remote node to the smart home hub?

Energy hunger of the traditional WiFi connection

In my first experiment I have connected two ESP8266 devices in a client-server scenario, waking up the battery powered client every minutes.

While connecting to the WiFi takes 5–10 seconds and depending on your router failure rate of 10–20% the energy cost for a simple measurement and pushing the measurement to the server /receiver/ node is quite high.

This resulted in a 980mAh to be able to push a measurement every 60 seconds 4,237 times before the battery was depleted, resulting in a 3.1 days total runtime.

In an ideal remote sensor assuming hourly reporting over wifi this would yield to a 6 months real runtime.

Reduce the Hunger with ESP-NOW

Connecting WiFi using a traditional router introduces several additional layers, delays and risks.

Espressiv Systems implemented ESP-NOW, a wireless and ad-hoc communication protocol for quick responses and low-power control.

“Beethowen” to the rescue

Communicating sensor data over ESP-NOW is possible, yet there seems to be a lack of standardized solution. This both increases development time and makes it less available for wider developer audience.

I have created Beethowen, an energy efficient method to transfer data over ESP-NOW Wireless Communication Protocol using BTHome protocol between two devices in an ad-hoc and independent way.

The name is coming from a playful 2 am brainstorming from “BTHome Over Esp-NoW”.

For low-code ESPHome development I have implemented beethowen_receiver component to add low-code support for standalone reception and beethowen_transmitter to add low-code support for standalone transmission.

Second Experiment with ESP-NOW

As a second experiment I was using ESP-NOW channel, reducing complete active time to 1,150 milliseconds resulting and increase 26,106 cycles of a 17.5 days total runtime with the same 980mAh battery of 60 second cycle time.

In an ideal remote sensor assuming hourly reporting over wifi this would yield to a 3 years real runtime, neglecting the battery self discharge.

The cycle time can be further improved using the WiFi persistent option to 300 ms with a theoretical increase of 78,318 cycles and a resulting 9 years real runtime.

Architectural Overview

Below is a short overview of the key components.

Source Code

The source code and the documentation is published as a standard github repository.

Sample Code

Beethowen Receiver

external_components:
- source: github://afarago/esphome_component_bthome

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "$systemName"
password: !secret wifi_password

beethowen_receiver:
dump: unmatched

sensor:
- platform: beethowen_receiver
mac_address: 11:22:33:44:55:55
name_prefix: Beethowen TestDevice
sensors:
- measurement_type: temperature
name: Temperature
- measurement_type: count_large
name: Count
unit_of_measurement: cycles

Beethowen Transmitter

external_components:
- source: github://afarago/esphome_component_bthome

esphome:
name: $systemName
libraries:
- ESP8266WiFi
on_loop:
then:
- lambda: |-
static bool update_requested = false;
if (!update_requested) {
id(my_bmp085).update();
update_requested = true;
} else if (id(bmp085_temperature_sensor).has_state()) {
id(my_beethowen_transmitter).transmit();
id(my_deep_sleep).begin_sleep(true);
}

beethowen_transmitter:
id: my_beethowen_transmitter
connect_persistent: true

sensor:
- platform: beethowen_transmitter
name: Beethowen TestDevice Temperature
measurement_type: temperature
lambda: |-
return id(bmp085_temperature_sensor).state;

- platform: bmp085
id: my_bmp085
temperature:
id: bmp085_temperature_sensor
internal: true

deep_sleep:
run_duration: 20s # max run duration for safeguarding
sleep_duration: 60s
id: my_deep_sleep

BTHome Receiver

external_components:
- source: github://afarago/esphome_component_bthome

esp32_ble_tracker:

bthome_receiver:
dump: unmatched

sensor:
- platform: bthome
mac_address: 11:22:33:44:55:55
name_prefix: BTHome Living Room
sensors:
- measurement_type: temperature
name: Temperature
- measurement_type: humidity
name: Humidity

- platform: bthome
mac_address: 22:33:44:55:55:66
sensors:
- measurement_type: temperature
name: BTHome Garage Temperature

binary_sensor:
- platform: bthome
mac_address: 11:22:33:44:55:55
name_prefix: BTHome Garage
sensors:
- measurement_type: opening
name: Opening

--

--

Attila Farago

interested in ev3, lego, spike, future of digital education