OLED SH1106 with esphome

I have successfully connected SH1106 OLED with esp32.


Now I have two issues,

Used the following code

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    id: oled_display
    pages: 
      - id: page1 
        lambda: |-
         // Print WiFi Signal
         it.printf(0, 26, id(arial_14), "Wi-Fi: %.1f", id(wifi_sgnl).state); 
         // Print time in HH:MM format
         it.strftime(0, 0, id(roboto), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
         // Print Room humidity"(from xiaomi sensor)
         if (id(room_humidity).has_state()) {
         it.printf(127,62, id(roboto), TextAlign::BOTTOM_RIGHT, "%.1f%%", id(room_humidity).state);
         }
         // Print Room temperature(from xiaomi sensor)
         if (id(room_temperature).has_state()) {
          it.printf(127, 0, id(Carrois_Gothic), TextAlign::TOP_RIGHT, "%.1f°C", id(room_temperature).state);
         }
         // Print 29Gal temperature(from dallas sensor)
         if (id(dallas_temp).has_state()) {
          it.printf(0, 62, id(Carrois_Gothic), TextAlign::BOTTOM_LEFT, "%.1f°C", id(dallas_temp).state);
         }
      - id: page2 
        lambda: |-
         // Print 29Gal temperature(from dallas sensor)
         if (id(dallas_temp).has_state()) {
          it.printf(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%.1f°C", id(dallas_temp).state);
         } 
      - id: page3 
        lambda: |-
         // Print time in HH:MM format
          it.strftime(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%H:%M", id(esptime).now());
      - id: page4 
        lambda: |-
         // Print time from Human Readable uptime
          it.printf(60, 10, id(Merriweather), TextAlign::CENTER_HORIZONTAL, "%s", id(uptime_human).state.c_str());
# For example cycle through pages on a timer
interval:
  - interval: 3s
    then:
      - display.page.show_next: oled_display
      - component.update: oled_display        

For uptime sensor used the following code


display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    id: oled_display
    pages: 
      - id: page1 
        lambda: |-
         // Print WiFi Signal
         it.printf(0, 26, id(arial_14), "Wi-Fi: %.1f", id(wifi_sgnl).state); 
         // Print time in HH:MM format
         it.strftime(0, 0, id(roboto), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
         // Print Room humidity"(from xiaomi sensor)
         if (id(room_humidity).has_state()) {
         it.printf(127,62, id(roboto), TextAlign::BOTTOM_RIGHT, "%.1f%%", id(room_humidity).state);
         }
         // Print Room temperature(from xiaomi sensor)
         if (id(room_temperature).has_state()) {
          it.printf(127, 0, id(Carrois_Gothic), TextAlign::TOP_RIGHT, "%.1f°C", id(room_temperature).state);
         }
         // Print 29Gal temperature(from dallas sensor)
         if (id(dallas_temp).has_state()) {
          it.printf(0, 62, id(Carrois_Gothic), TextAlign::BOTTOM_LEFT, "%.1f°C", id(dallas_temp).state);
         }
      - id: page2 
        lambda: |-
         // Print 29Gal temperature(from dallas sensor)
         if (id(dallas_temp).has_state()) {
          it.printf(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%.1f°C", id(dallas_temp).state);
         } 
      - id: page3 
        lambda: |-
         // Print time in HH:MM format
          it.strftime(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%H:%M", id(esptime).now());
      - id: page4 
        lambda: |-
         // Print time from Human Readable uptime
          it.printf(60, 10, id(Merriweather), TextAlign::CENTER_HORIZONTAL, "%s", id(uptime_human).state.c_str());
# For example cycle through pages on a timer
interval:
  - interval: 3s
    then:
      - display.page.show_next: oled_display
      - component.update: oled_display        

to make Human readable

- platform: uptime
    name: Uptime Sensor
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str(); 

You have not demonstrated that issue

A smaller font? or split the line with a newline character \n

[quote=“nickrout, post:2, topic:427790, full:true”]

I want to use a material icon like the one shown in the youtube video and screenshot I posted.

for simple google fonts I can add the following code and it will be added to esphome.

  # gfonts://family[@weight]
  - file: "gfonts://Roboto"
    id: roboto
    size: 20

this is the code I am using for the fonts

# font defined   
font:
  - file: "sh1106/arial.ttf"
    id: arial_14
    size: 14 
   # gfonts://family[@weight]
  - file: "gfonts://Roboto"
    id: roboto
    size: 20
  - file: "gfonts://Carrois Gothic"
    id: Carrois_Gothic
    size: 20
  - file: "gfonts://Kdam Thmor Pro"
    id: Kdam_Thmor_Pro
    size: 40
  - file: "gfonts://Merriweather"
    id: Merriweather
    size: 30    

I don’t want to use a smaller font, how to add the new line, this is the code I use to display the human-readable code

- id: page4 
        lambda: |-
         // Print time from Human Readable uptime
          it.printf(60, 10, id(Merriweather), TextAlign::CENTER_HORIZONTAL, "%s", id(uptime_human).state.c_str());

Like Nick said - insert a newline character where you want to split the line:

              return (
                (days ? to_string(days) + "d " : "") + 
                (hours ? to_string(hours) + "h " : "") + "\n" +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str(); 

I use the self-hosted font file, I haven’t been able to get gfonts:// working for the icons.

The font file containing many of the icons is here: material-design-icons/font at master · google/material-design-icons · GitHub

1 Like
- platform: uptime

    name: Uptime Sensor

    id: uptime_sensor

    update_interval: 60s

    on_raw_value:

      then:

        - text_sensor.template.publish:

            id: uptime_human

            state: !lambda |-

              int seconds = round(id(uptime_sensor).raw_state);

              int days = seconds / (24 * 3600);

              seconds = seconds % (24 * 3600);

              int hours = seconds / 3600;

              seconds = seconds % 3600;

              int minutes = seconds /  60;

              seconds = seconds % 60;

              return (

                (days ? to_string(days) + "d " : "") +

                (hours ? to_string(hours) + "h " : "") + "\n" +

                (minutes ? to_string(minutes) + "m " : "") + "\n" +

                (to_string(seconds) + "s")

              ).c_str();

I tried this method but it doesn’t seem to work

Then you probably need to split up the uptime into several fields and apply the formatting to the printf statement.

And use a smaller font.

that will be the long solution, isn’t it?

but for the material design icon I can’t get it to work

I tried the icon copy-paste method described here but it didn’t work. Display materialdesign icons on ESPHome attached to screen - #5 by makai

got this error

[20:03:05][W][display:176]: Encountered character without representation in font: '\xf3'
[20:03:05][W][display:176]: Encountered character without representation in font: '\xb0'
[20:03:05][W][display:176]: Encountered character without representation in font: '\x94'
[20:03:05][W][display:176]: Encountered character without representation in font: '\x84'
[20:03:05][W][display:176]: Encountered character without representation in font: '\xf3'
[20:03:05][W][display:176]: Encountered character without representation in font: '\xb0'
[20:03:06][W][display:176]: Encountered character without representation in font: '\x94'
[20:03:06][W][display:176]: Encountered character without representation in font: '\x84'
[20:03:06][W][display:176]: Encountered character without representation in font: '\xf3'
[20:03:06][W][display:176]: Encountered character without representation in font: '\xb0'
[20:03:06][W][display:176]: Encountered character without representation in font: '\x94'
[20:03:06][W][display:176]: Encountered character without representation in font: '\x84'
[20:03:07][W][display:176]: Encountered character without representation in font: '\xf3'
[20:03:07][W][display:176]: Encountered character without representation in font: '\xb0'
[20:03:07][W][display:176]: Encountered character without representation in font: '\x94'
[20:03:07][W][display:176]: Encountered character without representation in font: '\x84'

What is your glyphs: line?

partially fixed with

  - file: 'sh1106/materialdesignicons-webfont.ttf'
    id: icon_font
    size: 20
    glyphs:
      - "\U000F1A80" # mdi-thermometer-water
      - "\U000F0510" # mdi-thermometer-lines
      - "\U000F0155" # mdi-clock-start    

and for the lamda

  - id: page2 
        lambda: |-
         // Print "Temp icon" in top left.
          it.printf(2, 0, id(icon_font), TextAlign::TOP_LEFT, "\U000F1A80" ); 
         // Print "Aquarium" in top center.
          it.printf(127, 0, id(roboto), TextAlign::TOP_RIGHT, "Aquarium");
         // Print 29Gal temperature(from dallas sensor)
         if (id(dallas_temp).has_state()) {
          it.printf(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%.1f°C", id(dallas_temp).state);

Now at least I have got the icon on the screen, this is a slightly old picture, changed the code and moved the icon to the top left after this.

but getting this error every other second.

09:08:15	[W]	[display:176]	
Encountered character without representation in font: '
'
09:08:15	[W]	[display:176]	
Encountered character without representation in font: '
'
09:08:15	[W]	[display:176]	
Encountered character without representation in font: '
'
09:08:15	[W]	[display:176]	
Encountered character without representation in font: '
'
09:08:15	[W]	[display:176]	
Encountered character without representation in font: '

That is pointing to line 176 of the yaml (I think).

that is totally different code
image

  - platform: ble_client
    ble_client_id: itag_node
    name: "Black iTag btn"
    service_uuid: 'ffe0'
    characteristic_uuid: 'ffe1'
    notify: true
    update_interval: never
    on_notify:
      then:
        - binary_sensor.template.publish:
            id: black_button
            state: ON
        - binary_sensor.template.publish:
            id: black_button
            state: OFF
  - platform: ble_client
    ble_client_id: itag_node
    name: "Black iTag Battery"
    service_uuid: '180f'
    characteristic_uuid: '2a19'
    icon: 'mdi:battery'
    unit_of_measurement: '%'

161 to 182

Obviously not then! Other than very carefully checking that you have every glyph included I don’t know how else to debug this.

I am only using only using one icon i.e

- "\U000F1A80" # mdi-thermometer-water

but still facing this

It is working though isn’t it? You could just ignore.

it triggers my OCD :rofl:, seeing this yellow error again and again in logs.

I have that problem too. The solution is stop looking at the logs.

1 Like

It somehow resolved on its own, or I removed some fonts due to space issues.