Hello,
I am trying to get a Waveshare ePaper running with a waveshare driver board:
I have a printout on the screen and the refresh pin (17) and “book now” pin (16) work perfect. If I press the physically attached pushbutton, the screen gets either refreshed (thru HomeAssistant magic, because I need to get some data from HomeAssistant first) and than displayed or a slot is booked in HA and than the new data is displayed on the ePaper.
As I do not want to run it on power but on battery, my next step was to try to hook up deep sleep mode. I added:
deep_sleep:
run_duration: 40s # Stay awake for 40 seconds
sleep_duration: 25min # Sleep duration
wakeup_pin:
number: GPIO4 # Wakeup when GPIO4 is pressed (pulled LOW)
inverted: True
mode: INPUT_PULLUP
wakeup_pin_mode: KEEP_AWAKE
id: ${rmgr_device_name}_deep_sleep
and the ESP goes into deep sleep and waked up after 25 minutes, get the new data and continues sleeping. So far so nice.
But I do need, that a person standing in front of the ePaper can press any physical pushbutton, than the ESP wakes up, gets the data, displays the actual status (like waking up after a certain amount of time). But I cannot get this “wakeup physical pushbotton” to work.
I tried differend GPIOs, and stuck to GPIO4 because accordingh to what I understand, it is just “close” to 16/17 so I can avoind counting the wrong pin. So now if I use my connection with IO17 it refreshed the screen, if I use the same physical connection on IO4 it simply does nothing, if I only use the deep_sleep configuration from above.
If I add
# wakeup Pin
- platform: gpio
name: "${rmgr_device_name}_wakeup"
pin:
number: GPIO4
inverted: true
mode:
input: True
pullup: True
filters:
- delayed_on: 10ms
down at the binary section definitions which work with GPIO16 and 17, I get the following error from the compiler:
INFO ESPHome 2025.2.2
INFO Reading configuration /config/esphome/framery1.yaml...
WARNING GPIO15 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
Failed config
deep_sleep: [source /config/esphome/common/calendar_free_busy_display.yaml:51]
Pin 4 is used in multiple places.
run_duration: 40s
sleep_duration: 25min
wakeup_pin:
number: 4
inverted: True
mode:
input: True
pullup: True
output: False
open_drain: False
pulldown: False
ignore_pin_validation_error: False
binary_sensor.gpio: [source /config/esphome/common/calendar_free_busy_display.yaml:256]
Pin 4 is used in multiple places.
platform: gpio
name: framery1_wakeup
pin:
number: 4
inverted: True
mode:
input: True
pullup: True
output: False
open_drain: False
pulldown: False
ignore_pin_validation_error: False
if I do not add it, I get “no reaction” from ppushing the button.
I have absolutely no idea, what I have to do. Found some “esp_deep_sleep” like
https://community.home-assistant.io/t/deep-sleep-and-multiple-buttons/
or
https://ncrmnt.org/2021/12/06/optimizing-esp8266-esphome-for-battery-power-and-making-an-ice-bath-thermometer-as-well/
but do not get what I do different than what is shown there.
Thanks you for any help
Juergen
Here my full ESPHome Yaml.
# Calendar / Free Busy DASHBOARD
# For Home Assistant and ESPHome
# Inspired by WEATHERMAN by Madelena Mak 2022 - https://mmak.es
#
#######################
# VARIABLES passed into the system:
# - rmgr_device_name: the common prefix for sensors etc (still a bad name)
#
# ESPHome for battery:
# https://ncrmnt.org/2021/12/06/optimizing-esp8266-esphome-for-battery-power-and-making-an-ice-bath-thermometer-as-well/
# Core Configuration Section: https://esphome.io/components/esphome.html
esphome:
# https://esphome.io/components/esphome.html#changing-esphome-node-name
name: "${rmgr_device_name}"
# name is defined in specific instance config (e.g. framery1.yaml etc)
# https://esphome.io/components/esphome.html#on-boot
# on_boot is an *Automation* (https://esphome.io/automations/#automation)
on_boot: # == "Trigger"
priority: 200.0
then: # == "Actions"
- component.update: epaper_screen_print
- logger.log: "Forcing API reconnect after boot..."
- delay: 5s
# this triggers a reload in Home Assistant (which pushes the data down to the device)
# - homeassistant.event:
# event: "esphome.${rmgr_device_name}.booted"
# https://esphome.io/components/esp32.html
esp32:
# "if unsure choose a generic board from Espressif such as esp32dev."
board: esp32dev
framework:
type: arduino
# Enable logging
# https://esphome.io/components/logger.html
logger:
# level: NONE
# level: ERROR
# level: WARN
# level: INFO
level: DEBUG
# level: VERBOSE
# level: VERY_VERBOSE
# Deep Sleep Configuration
deep_sleep:
run_duration: 40s # Stay awake for 40 seconds
sleep_duration: 25min # Sleep duration
wakeup_pin:
number: GPIO4 # Wakeup when GPIO4 is pressed (pulled LOW)
inverted: True
mode: INPUT_PULLUP
wakeup_pin_mode: KEEP_AWAKE
id: ${rmgr_device_name}_deep_sleep
# Global variables for detecting if the display needs to be refreshed
# and other things :-)
globals:
- id: initial_data_received
type: bool
restore_value: no
initial_value: 'false'
- id: headline_text
type: std::string
restore_value: no
- id: subheadline_text
type: std::string
restore_value: no
- id: timeslots
type: std::vector<std::string>
restore_value: no
- id: is_occupied
type: std::vector<bool>
restore_value: no
- id: rmgr_booking_slot_length_minutes
type: std::string
restore_value: no
- id: last_display_refresh
type: std::string
restore_value: no
# Enable Home Assistant API
# https://esphome.io/components/api.html
api:
# on_client_connected:
# then:
# - logger.log: "Connected to HomeAssistant. -> booted"
# - homeassistant.event:
# event: esphome.${rmgr_device_name}.booted
# - logger.log: "simulte refresh to refresh the screen on first connect"
# - homeassistant.event:
# event: esphome.${rmgr_device_name}_refresh_clicked
services:
- service: "draw_schedule"
variables:
param_headline_text: string
param_subheadline_text: string
# !!! you need the same number of entries in param_timeslots and param_is_occupied
param_timeslots: string[]
param_is_occupied: bool[]
param_rmgr_booking_slot_length_minutes: string
param_last_display_refresh: string
then:
- lambda: 'id(initial_data_received) = true;'
- lambda: 'id(headline_text) = param_headline_text;'
- lambda: 'id(subheadline_text) = param_subheadline_text;'
- lambda: 'id(timeslots) = param_timeslots;'
- lambda: 'id(is_occupied) = param_is_occupied;'
- lambda: 'id(rmgr_booking_slot_length_minutes) = param_rmgr_booking_slot_length_minutes;'
- lambda: 'id(last_display_refresh) = param_last_display_refresh;'
- logger.log: ".-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. calfreebusy_draw_schedule Data"
- logger.log:
format: "param_headline_text has value >%s<"
args: [ 'id(headline_text).c_str()' ]
- logger.log:
format: "param_subheadline_text has value >%s<"
args: [ 'id(subheadline_text).c_str()' ]
- logger.log:
format: "param_timeslots has value >%i<"
args: [ 'id(timeslots)' ]
- component.update: epaper_screen_print
# https://esphome.io/components/ota/esphome
ota:
- platform: esphome
# ota turns safe_mode on, which we do not want.
safe_mode:
boot_is_good_after: 30s
# Wifi information
wifi:
networks:
# channel: 11
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 172.16.0.62
gateway: 172.16.0.1
subnet: 255.255.0.0
dns1: 172.16.0.1
dns2: 0.0.0.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
# does not work -> error before compiling
# ap:
# ssid: ${rmgr_device_name}_ssid
# password: !secret wifi_password
# Include custom fonts
font:
- file: 'fonts/GothamRnd-Book.ttf'
id: font_small_book
size: 18
glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ü', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.', '%', 'ä', 'ö', 'ü', 'ß', '(', ')']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_large_bold
size: 108
glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ü', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.','m', '%']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_title
size: 54
glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ü', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.','m', 'u', 'p', 'd', 't', '%']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_medium_bold
size: 30
glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ü', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.', '%', 'ä', 'ö', 'ü', 'ß', '(', ')']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_small_bold
size: 18
glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ü', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.','m', '%']
# Include Material Design Icons font
# Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medlarge
size: 18
glyphs:
- "\U000F05A9" # mdi-wifi
- "\U000F0928" # mdi-wifi-strength-4
- "\U000F0925" # mdi-wifi-strength-3
- "\U000F0922" # mdi-wifi-strength-2
- "\U000F091F" # mdi-wifi-strength-1
- "\U000F092B" # mdi-wifi-strength-alert-outline
# Check if epaper should be refreshed
sensor:
- platform: wifi_signal
name: "${rmgr_device_name} - WiFi Signal Strength"
id: "${rmgr_device_name}_wifisignal"
unit_of_measurement: "dBm"
entity_category: "diagnostic"
update_interval: 600s
binary_sensor:
# refresh durch HomeAssistant
- platform: homeassistant
entity_id: input_boolean.${rmgr_device_name}_refresh_clicked
id: ${rmgr_device_name}_update_epaper_display
# book durch Button am ESP
- platform: gpio
name: "${rmgr_device_name}_book_now"
pin:
number: GPIO16
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_on: 10ms
on_multi_click:
- timing:
- ON for at most 1s
- OFF for at most 1s
- ON for at most 1s
- OFF for at least 0.2s
then:
- logger.log: "Double Clicked"
- homeassistant.event:
event: esphome.${rmgr_device_name}_booknow_doubleclicked
- timing: # INFO: this is currently not used functionally.
- ON for 1s to 2s
- OFF for at least 0.5s
then:
- logger.log: "Single Long Clicked"
- homeassistant.event:
event: esphome.${rmgr_device_name}_booknow_longclicked
- timing:
- ON for at most 1s
- OFF for at least 0.5s
then:
- logger.log: "Single Short Clicked"
- homeassistant.event:
event: esphome.${rmgr_device_name}_booknow_clicked
# wakeup Pin
- platform: gpio
name: "${rmgr_device_name}_wakeup"
pin:
number: GPIO4
inverted: true
mode:
input: True
pullup: True
filters:
- delayed_on: 10ms
# refresh durch Button am ESP
- platform: gpio
name: "${rmgr_device_name}_refresh"
pin:
number: GPIO17
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_on: 10ms
on_multi_click:
- timing:
- ON for at most 1s
- OFF for at most 1s
- ON for at most 1s
- OFF for at least 0.2s
then:
- logger.log: "Double Clicked"
- homeassistant.event:
event: esphome.${rmgr_device_name}_refresh_doubleclicked
- timing: # INFO: this is currently not used functionally.
- ON for 1s to 2s
- OFF for at least 0.5s
then:
- logger.log: "Single Long Clicked"
- homeassistant.event:
event: esphome.${rmgr_device_name}_refresh_longclicked
- timing:
- ON for at most 1s
- OFF for at least 0.5s
then:
- logger.log: "Single Short Clicked"
- homeassistant.event:
event: esphome.${rmgr_device_name}_refresh_clicked
- platform: status
name: "${rmgr_device_name} Connected"
id: ${rmgr_device_name}_connected
# Pins for Waveshare ePaper ESP Board
spi:
clk_pin: GPIO13 # SCLK P13 SPI CLK pin, clock signal input
mosi_pin: GPIO14 # DIN P14 SPI MOSI pin, data input
# Now render everything on the ePaper screen.
display:
- platform: waveshare_epaper
# models from https://esphome.io/components/display/waveshare_epaper
# model: 7.50inV2 # s/w board evtl. älterer Treiber ???
# model: 7.50in-nV2 # s/w board
model: 7.50in-bV3 # r/s/w board
id: epaper_screen_print
cs_pin: GPIO15 # CS P15 Chip selection, low active
dc_pin: GPIO27 # DC P27 Data/command, low for commands, high for data
busy_pin:
number: GPIO25 # BUSY P25 Busy status output pin (means busy)
inverted: true
reset_pin: GPIO26 # RST P26 Reset, low active
reset_duration: 2ms
update_interval: never
rotation: 90°
lambda: |-
int offsetY = 40;
int offsetX = 0;
//# Print loading screen before data is received.
if (id(initial_data_received) == false) {
it.printf(240, 390, id(font_small_bold), TextAlign::TOP_CENTER, "WARTE AUF DATEN");
ESP_LOGD("display","Warte auf Daten");
} else {
// headline
int lineHeight = 35;
it.printf(50, offsetY, id(font_medium_bold), TextAlign::TOP_LEFT, "%s", id(headline_text).c_str());
offsetY += lineHeight;
// subheadline
lineHeight = 22;
it.printf(150, offsetY, id(font_small_book), TextAlign::TOP_LEFT, "%s", id(subheadline_text).c_str());
offsetY += lineHeight;
lineHeight = 22;
for (size_t i = 0; i < id(timeslots).size(); ++i) {
offsetY += lineHeight;
it.printf(50, offsetY, id(font_small_book), TextAlign::TOP_LEFT, "%s", id(timeslots)[i].c_str());
if (id(is_occupied)[i]) {
it.filled_rectangle(120, offsetY, 100, lineHeight);
}
}
}
//# decide for the WiFi-signal Symbol
//# is printed printed below
std::string wifiSymbol = "";
offsetX = it.get_width() - 50;
offsetY = it.get_height() - 150;
if(id(${rmgr_device_name}_wifisignal).has_state ()) {
if (id(${rmgr_device_name}_wifisignal).state >= -50) {
// Excellent
wifiSymbol = "\U000F0928";
} else if (id(${rmgr_device_name}_wifisignal).state >= -60) {
//Good
wifiSymbol = "\U000F0925";
} else if (id(${rmgr_device_name}_wifisignal).state >= -67) {
//Fair
wifiSymbol = "\U000F0922";
} else if (id(${rmgr_device_name}_wifisignal).state >= -70) {
//Weak
wifiSymbol = "\U000F091F";
} else {
//Unlikely working signal
wifiSymbol = "\U000F092B";
}
}
// Print booking slot length + Last refresh + Wifi
// we write from bottom to top
offsetX = it.get_width() - 50;
offsetY = it.get_height() - 130;
int lineHeight = 22;
// Print DBI and Wifi Signal
it.printf(offsetX - 25, offsetY, id(font_small_book), TextAlign::TOP_RIGHT, "%.0f dB", id(${rmgr_device_name}_wifisignal).state);
it.printf(offsetX, offsetY, id(font_mdi_medlarge), TextAlign::TOP_RIGHT, "%s", wifiSymbol.c_str());
//
it.printf(offsetX - 150, offsetY, id(font_small_book), TextAlign::TOP_RIGHT, "%s", id(rmgr_booking_slot_length_minutes).c_str());
offsetY -= lineHeight;
it.printf(offsetX, offsetY, id(font_small_book), TextAlign::TOP_RIGHT, "%s", id(last_display_refresh).c_str());
captive_portal: