Still playing around (trying to get text_sensors for wifi info to work), but very happy with how quickly something like this can be done in ESPHome with the right kit. I have the LILYGO S3 coming with a larger display that I will likely standardize on for sensors with displays.
Keywords: M5stack, M5Stick-C Plus, Display, Histogram, Graph, ESPHome
This sample code will cycle through displaying histograms of temperature and humidity in 2 different time scales. I’m using this to watch my 3D filament dryer in action. The only problem i see with this hardware (other than it being massive overkill) is that it gets warm enough from the display backlight that you would not be able to mount the DHT22 or any temp sensor to the m5Stick
Hardware:
- M5Stack - M5StickC-Plus
- DHT22 Sensor attached via the grover connection on the stick
- Random USBC charger
I’m not a coder by any means. Hope this is helpful to someone getting started. I patched together several learnings from other projects I found on github.
substitutions:
devicename: espstick-playground
upper_devicename: M5StickCplay
esphome:
name: $devicename
platform: ESP32
board: m5stick-c
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-A81Ae0"
password: "CVb1KbgcP1hr"
captive_portal:
web_server:
binary_sensor:
- platform: gpio
pin:
number: GPIO37
inverted: true
name: ${upper_devicename} Button A
on_press:
then:
- light.turn_on: led1
on_release:
then:
- light.turn_off: led1
- platform: gpio
pin:
number: GPIO39
inverted: true
name: ${upper_devicename} Button B
on_press:
then:
- light.turn_on: led1
on_release:
then:
- light.turn_off: led1
i2c:
- id: bus_a
sda: GPIO21
scl: GPIO22
scan: True
- id: bus_b
sda: GPIO0
scl: GPIO26
sensor:
# AXP192 power management - must be present to initialize TFT power on
- platform: axp192
address: 0x34
i2c_id: bus_a
update_interval: 30s
battery_level:
name: ${upper_devicename} Battery Level
id: m5stick_batterylevel
brightness: 0.5
# Wifi Signal in db
- platform: wifi_signal
name: ${upper_devicename} WiFi Signal dB
id: wifi_dbm
# Wifi Signal in Percent
- platform: wifi_signal
name: ${upper_devicename} WiFi Strength
id: wifi_strength
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "Signal %"
# Uptime Monitor
- platform: uptime
name: ${upper_devicename} Uptime
# DHT22 temperature and humidity sensor
- platform: dht
pin: 33
model: DHT22
update_interval: 10s
temperature:
name: "Temp101"
id: templocal
filters:
lambda: return x * (9.0/5.0) + 32.0;
humidity:
name: "Humidity101"
id: humiditylocal
filters:
lambda: return x * 1;
# Uptime sensor
- platform: uptime
name: ${upper_devicename} Uptime
# Copy WIFI info into variables
text_sensor:
- platform: wifi_info
ip_address:
name: ESP IP Address
id: ESP_IP
ssid:
name: ESP Connected SSID
id: ESP_Network
bssid:
name: ESP Connected BSSID
mac_address:
name: ESP Mac Wifi Address
id: ESP_MAC
scan_results:
name: ESP Latest Scan Results
id: ESP_Scan
# internal LED
light:
- platform: monochromatic
output: builtin_led
name: ${upper_devicename} Led
id: led1
output:
- platform: ledc
pin: 10
inverted: true
id: builtin_led
spi:
clk_pin: GPIO13
mosi_pin: GPIO15
font:
- file: 'custom_components/fonts/arial.ttf'
id: font1
size: 36
- file: 'custom_components/fonts/arial.ttf'
id: font2
size: 20
- file: 'custom_components/fonts/arial.ttf'
id: font3
size: 14
- file: 'custom_components/fonts/arial.ttf'
id: font_big
size: 44
- file: 'custom_components/fonts/materialdesignicons-webfont.ttf'
id: font_icons
size: 31
glyphs:
- "\U000F092E" # wifi_nosignal
- "\U000F0923" # wifi_weak
- "\U000F0928" # wifi_strong
- "\U000F0083" # bat_low
- "\U000F0084" # bat_full
- "\U000F050F" # thermometer
- "\U000F058C" # humidity
- "\U000F084E" # scale
- file: 'custom_components/fonts/materialdesignicons-webfont.ttf'
id: icons_big
size: 44
glyphs:
- "\U000F092E" # wifi_nosignal
- "\U000F0923" # wifi_weak
- "\U000F0928" # wifi_strong
- "\U000F0083" # bat_low
- "\U000F0084" # bat_full
- "\U000F050F" # thermometer
- "\U000F058C" # humidity
- "\U000F084E" # scale
color:
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_yellow
red: 100%
green: 100%
blue: 0%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_gray
red: 50%
green: 50%
blue: 50%
- id: my_white
red: 100%
green: 100%
blue: 100%
- id: my_pink
red: 100%
green: 75%
blue: 80%
- id: my_orange
red: 100%
green: 50%
blue: 0%
# Graphs sized for M5Stick Display 240x135
graph:
- id: humidity_graph_10
duration: 10min
x_grid: 1min
y_grid: 1.0
width: 234
height: 100
traces:
- sensor: humiditylocal
line_type: SOLID
line_thickness: 3
color: my_orange
- id: humidity_graph_2
duration: 2h
x_grid: 20min
y_grid: 1.0
width: 234
height: 100
traces:
- sensor: humiditylocal
line_type: SOLID
line_thickness: 3
color: my_orange
- id: temperature_graph_10
duration: 10min
x_grid: 1min
y_grid: 1.0
width: 234
height: 100
traces:
- sensor: templocal
line_type: SOLID
line_thickness: 3
color: my_yellow
- id: temperature_graph_2
duration: 2h
x_grid: 20min
y_grid: 1.0
width: 234
height: 100
traces:
- sensor: templocal
line_type: SOLID
line_thickness: 3
color: my_yellow
# builtin st7789v 240x135 display
display:
- platform: st7789v
model: TTGO TDisplay 135x240
backlight_pin: GPIO1
cs_pin: GPIO5
dc_pin: GPIO23
reset_pin: GPIO18
rotation: 270
update_interval: 1s
id: this_display
pages:
- id: page2
lambda: |-
it.graph( 3, 1, id(temperature_graph_10), my_gray);
it.print(2, 104, id(font_icons), my_yellow, TextAlign::LEFT, "\U000F050F");
it.printf(35, 102, id(font1), my_yellow, TextAlign::LEFT , "%.1f°", id(templocal).state);
it.print(158, 104, id(font_icons), my_blue, TextAlign::LEFT, "\U000F084E");
it.print(188, 108, id(font2), my_blue, TextAlign::LEFT, "1min");
- id: page3
lambda: |-
it.graph( 3, 1, id(temperature_graph_2), my_gray);
it.print(2, 104, id(font_icons), my_yellow, TextAlign::LEFT, "\U000F050F");
it.printf(35, 102, id(font1), my_yellow, TextAlign::LEFT , "%.1f°", id(templocal).state);
it.print(158, 104, id(font_icons), my_blue, TextAlign::LEFT, "\U000F084E");
it.print(188, 108, id(font2), my_blue, TextAlign::LEFT, "20min");
- id: page4
lambda: |-
it.graph( 3, 1, id(humidity_graph_10), my_gray);
it.print(2, 104, id(font_icons), my_orange, TextAlign::LEFT, "\U000F058C");
it.printf(35, 102, id(font1), my_orange, TextAlign::LEFT, "%.1f%%", id(humiditylocal).state);
it.print(158, 104, id(font_icons), my_blue, TextAlign::LEFT, "\U000F084E");
it.print(188, 108, id(font2), my_blue, TextAlign::LEFT, "1min");
- id: page5
lambda: |-
it.graph( 3, 1, id(humidity_graph_2), my_gray);
it.print(2, 104, id(font_icons), my_orange, TextAlign::LEFT, "\U000F058C");
it.printf(35, 102, id(font1), my_orange, TextAlign::LEFT, "%.1f%%", id(humiditylocal).state);
it.print(158, 104, id(font_icons), my_blue, TextAlign::LEFT, "\U000F084E");
it.print(188, 108, id(font2), my_blue, TextAlign::LEFT, "20min");
- id: page1
lambda: |-
it.print(2, 30, id(icons_big), my_orange, TextAlign::LEFT, "\U000F058C");
it.printf(37, 30, id(font_big), my_orange, TextAlign::LEFT, "%.1f%%", id(humiditylocal).state);
it.print(2, 85, id(icons_big), my_yellow, TextAlign::LEFT, "\U000F050F");
it.printf(37, 85, id(font_big), my_yellow, TextAlign::LEFT , "%.1f°", id(templocal).state);
it.printf(20, 20, id(font3), my_blue, TextAlign::LEFT, "%", id(ESP_IP).state.c_str());
# For example cycle through pages on a timer
interval:
- interval: 5s
then:
- display.page.show_next: this_display
- component.update: this_display
time:
- platform: homeassistant
id: homeassistant_time
- platform: sntp
id: sntp_time