Files
zorruno-homeassistant/esphome/esp-espnow_test_transmitter1.yaml
2026-07-11 18:19:37 +12:00

294 lines
8.0 KiB
YAML

#:########################################################################################:#
# ESP-NOW Test Transmitter 1
#:########################################################################################:#
#
# DEVICE:
# ESP32-S3-Zero / ESP32-S3 Super Mini
#
# VERSION:
# 1.2 - 2026-07-11
# - Changed GPIO4 wake source to ESP32 EXT1 ANY_LOW.
# - Added delay to allow ESP-NOW to initialise before transmission.
# - Added GPIO4 input and pull-up initialisation.
# - Waits for the wake button to be released before entering deep sleep.
# - Logs the ESP32 wake cause.
# - Sends each message three times for improved broadcast reliability.
#
# WIRING:
#
# 3.3 V
# |
# 10 kΩ
# |
# +-------- GPIO4
# |
# Push button
# |
# GND
#
# OPERATION:
# - Power-up or reset causes one transmission.
# - The transmitter sends the same ESP-NOW message three times.
# - It waits for GPIO4 to return HIGH.
# - It then enters deep sleep.
# - Pulling GPIO4 LOW wakes the transmitter and repeats the sequence.
#
# MESSAGE FORMAT:
# REMOTE_A:BUTTON_1:<random press ID>
#
# IMPORTANT:
# - ESP-NOW channel must match the receiver network channel.
# - The receiver is currently operating on channel 5.
# - This transmitter deliberately does not connect to normal Wi-Fi.
# - Firmware updates are performed by USB.
#
#:########################################################################################:#
substitutions:
device_name: esp-espnow-test-transmitter1
friendly_name: "ESPNow Test Transmitter 1"
remote_id: "REMOTE_A"
button_id: "BUTTON_1"
espnow_channel: "5"
wake_gpio: "4"
#:########################################################################################:#
# ESPHome Core
#:########################################################################################:#
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
on_boot:
priority: -100
then:
- lambda: |-
// Explicitly configure GPIO4 as an input with a pull-up.
gpio_set_direction(GPIO_NUM_4, GPIO_MODE_INPUT);
gpio_set_pull_mode(GPIO_NUM_4, GPIO_PULLUP_ONLY);
const esp_sleep_wakeup_cause_t wake_cause =
esp_sleep_get_wakeup_cause();
ESP_LOGI(
"wake",
"ESP-NOW transmitter booted. Wake cause: %d",
static_cast<int>(wake_cause)
);
if (wake_cause == ESP_SLEEP_WAKEUP_EXT1) {
ESP_LOGI("wake", "Wake was caused by the GPIO4 EXT1 input.");
} else if (wake_cause == ESP_SLEEP_WAKEUP_UNDEFINED) {
ESP_LOGI("wake", "Wake was caused by power-up or reset.");
} else {
ESP_LOGI(
"wake",
"Wake was caused by another source: %d",
static_cast<int>(wake_cause)
);
}
# Allow all ESPHome components, including ESP-NOW, to finish setup.
- delay: 750ms
- lambda: |-
id(press_id) = esp_random();
char payload_buffer[96];
snprintf(
payload_buffer,
sizeof(payload_buffer),
"${remote_id}:${button_id}:%lu",
static_cast<unsigned long>(id(press_id))
);
id(transmit_payload) = payload_buffer;
ESP_LOGI(
"espnow_tx",
"Prepared payload: %s",
id(transmit_payload).c_str()
);
- script.execute: send_espnow_press
- script.wait: send_espnow_press
- logger.log:
level: INFO
format: "Transmission sequence completed."
# Do not enter sleep while GPIO4 is still held LOW.
- logger.log:
level: INFO
format: "Waiting for GPIO4 button release."
- wait_until:
condition:
lambda: |-
return gpio_get_level(GPIO_NUM_4) == 1;
- delay: 100ms
- logger.log:
level: INFO
format: "GPIO4 released. Entering deep sleep."
- delay: 100ms
- deep_sleep.enter: deep_sleep_control
#:########################################################################################:#
# ESP32 Hardware
#:########################################################################################:#
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
#:########################################################################################:#
# Logging
#:########################################################################################:#
logger:
level: DEBUG
#:########################################################################################:#
# ESP-NOW
#:########################################################################################:#
#
# The transmitter does not connect to Wi-Fi, so its radio channel is set
# explicitly. Both transmitter and receiver must use the same channel.
#
espnow:
channel: ${espnow_channel}
enable_on_boot: true
#:########################################################################################:#
# Globals
#:########################################################################################:#
globals:
- id: press_id
type: uint32_t
restore_value: false
initial_value: '0'
- id: transmit_payload
type: std::string
restore_value: false
initial_value: '""'
#:########################################################################################:#
# ESP-NOW Transmission Script
#:########################################################################################:#
script:
- id: send_espnow_press
mode: single
then:
- logger.log:
level: INFO
format: "Sending ESP-NOW broadcast 1 of 3."
- espnow.broadcast:
data: !lambda |-
return std::vector<uint8_t>(
id(transmit_payload).begin(),
id(transmit_payload).end()
);
wait_for_sent: true
continue_on_error: true
on_sent:
- logger.log:
level: DEBUG
format: "Broadcast 1 submitted successfully."
on_error:
- logger.log:
level: WARN
format: "Broadcast 1 reported an error."
- delay: 75ms
- logger.log:
level: INFO
format: "Sending ESP-NOW broadcast 2 of 3."
- espnow.broadcast:
data: !lambda |-
return std::vector<uint8_t>(
id(transmit_payload).begin(),
id(transmit_payload).end()
);
wait_for_sent: true
continue_on_error: true
on_sent:
- logger.log:
level: DEBUG
format: "Broadcast 2 submitted successfully."
on_error:
- logger.log:
level: WARN
format: "Broadcast 2 reported an error."
- delay: 75ms
- logger.log:
level: INFO
format: "Sending ESP-NOW broadcast 3 of 3."
- espnow.broadcast:
data: !lambda |-
return std::vector<uint8_t>(
id(transmit_payload).begin(),
id(transmit_payload).end()
);
wait_for_sent: true
continue_on_error: true
on_sent:
- logger.log:
level: DEBUG
format: "Broadcast 3 submitted successfully."
on_error:
- logger.log:
level: WARN
format: "Broadcast 3 reported an error."
- delay: 75ms
#:########################################################################################:#
# Deep Sleep and GPIO4 Wake
#:########################################################################################:#
#
# ESP32-S3 supports EXT1 ANY_LOW wake.
#
# With one configured pin, ANY_LOW means:
# Wake when GPIO4 is pulled LOW.
#
# An external 10 kΩ pull-up between GPIO4 and 3.3 V is recommended.
#
deep_sleep:
id: deep_sleep_control
esp32_ext1_wakeup:
pins:
- GPIO${wake_gpio}
mode: ANY_LOW