M5Stick C Plus and Core2 Humidity Sensor for 3d Filament Dryer

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
2 Likes

No luck with the TTGO S3, I have not found any way to make it work in ESP Home.

The M5Stack Core2 yaml is below. This is for the AWS (yellow) version, which is $15 cheaper, but top hat is the same and should work for any Core2 derivative. Custom AXP192 build from @martydingo was key to get it to work. I’m sure the core2 feels like Marvin the robot from Hitchhiker’s guide…a simple temp and humidity sensor. These little things are crazy packed with stuff.

substitutions:
  devicename: espcore_1
  upper_devicename: m5stackcore2

esphome:
  name: $devicename
  platform: ESP32
  board: m5stack-core-esp32

# 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:


    

sensor:
# AXP192 power management - must be present to initialize TFT power on
# note tht you must include https://github.com/martydingo/esphome-axp192 source to make core2 work

  - platform: axp192
    model: M5CORE2
    address: 0x34
    i2c_id: bus_a
    update_interval: 30s
    battery_level:
      name: ${upper_devicename} Battery Level
      id: m5stick_batterylevel
    brightness: 1.0

# 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 %"


# 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

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO38

i2c:
  - id: bus_a
    sda: GPIO21
    scl: GPIO22
    scan: True

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% 
  - id: my_black
    red: 0%
    green: 0%
    blue: 0% 


# Graphs sized for M5Stick Display 320x240
graph:
  - id: humidity_graph_10
    duration: 10min
    x_grid: 1min
    y_grid: 1.0
    width: 318
    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: 318
    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: 318
    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: 318
    height: 100
    traces:
      - sensor: templocal
        line_type: SOLID
        line_thickness: 3
        color: my_yellow



# builtin st7789v 240x135 display
display:
  - platform: ili9341
    model: M5STACK
    cs_pin: GPIO5
    dc_pin: GPIO15
    rotation: 0
    update_interval: 5s
    id: this_display
    pages:
      - id: page2
        lambda: |-
          it.graph( 0, 0, id(temperature_graph_10), my_gray);
          it.graph( 0, 100, id(temperature_graph_2), my_gray);
          it.print(2, 205, id(font_icons), my_yellow, TextAlign::LEFT, "\U000F050F");
          it.printf(35, 202, id(font1), my_yellow, TextAlign::LEFT , "Dryer %.1f°", id(templocal).state);
          it.filled_rectangle(0, 70, 85, 30, my_gray);
          it.filled_rectangle(0, 170, 85, 30, my_gray);
          it.rectangle(0, 0, 318, 100, my_gray);
          it.rectangle(2, 2, 314, 96, my_gray);
          it.rectangle(1, 1, 316, 98, my_white);
          it.rectangle(0, 100, 318, 100, my_gray);
          it.rectangle(2, 102, 314, 96, my_gray);
          it.rectangle(1, 101, 316, 98, my_white);
          it.print(2, 70, id(font_icons), my_white, TextAlign::LEFT, "\U000F084E");
          it.print(32, 73, id(font2), my_white, TextAlign::LEFT, "1min");
          it.print(2, 170, id(font_icons), my_white, TextAlign::LEFT, "\U000F084E");
          it.print(32, 173, id(font2), my_white, TextAlign::LEFT, "20min");
      - id: page3
        lambda: |-
          it.graph( 0, 0, id(humidity_graph_10), my_gray);
          it.graph( 0, 100, id(humidity_graph_2), my_gray);
          it.print(2, 205, id(font_icons), my_orange, TextAlign::LEFT, "\U000F058C");
          it.printf(35, 202, id(font1), my_orange, TextAlign::LEFT, "Dryer %.1f%%", id(humiditylocal).state);
          it.filled_rectangle(0, 70, 85, 30, my_gray);
          it.filled_rectangle(0, 170, 85, 30, my_gray);
          it.rectangle(0, 0, 318, 100, my_gray);
          it.rectangle(2, 2, 314, 96, my_gray);
          it.rectangle(1, 1, 316, 98, my_white);
          it.rectangle(0, 100, 318, 100, my_gray);
          it.rectangle(2, 102, 314, 96, my_gray);
          it.rectangle(1, 101, 316, 98, my_white);
          it.print(2, 70, id(font_icons), my_white, TextAlign::LEFT, "\U000F084E");
          it.print(32, 73, id(font2), my_white, TextAlign::LEFT, "1min");
          it.print(2, 170, id(font_icons), my_white, TextAlign::LEFT, "\U000F084E");
          it.print(32, 173, id(font2), my_white, TextAlign::LEFT, "20min");

      - id: page1
        lambda: |-
          it.print(1, 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: 6s
    then:
      - display.page.show_next: this_display
      - component.update: this_display

time:
  - platform: homeassistant
    id: homeassistant_time
  - platform: sntp
    id: sntp_time
1 Like