294 lines
8.0 KiB
YAML
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 |