Output data from one ESP32 to two SH1106 oled displays

Hello everybody!
I’m trying to output sensor data to two SH1106 oled displays connected to the same ESP32. I’m not a codemaster and after try&error for a few days with being stuck on the same place I thought about bothering somebody else with my missing skills :upside_down_face: .

So this is the code that works so far:

font:
  - file: 'slkscr.ttf'
    id: font1
    size: 8

  - file: 'BebasNeue-Regular.ttf'
    id: font2
    size: 65

  - file: 'arial.ttf'
    id: font3
    size: 15


i2c:
  sda: GPIO21
  scl: GPIO22
  scan: false


display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    lambda: |-
      // Print time in HH:MM format
      it.strftime(64, -10, id(font2), TextAlign::TOP_CENTER, "%H:%M", id(esptime).now());
      }

It displays the time (same content) on both connected displays, so far what I expect. I read that I should use “0x3D” to address an additional display on the i2c-bus and tried to extend my code as following:

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    id: blue_display
    lambda: |-
      // Print time in HH:MM format
      it.blue_display.strftime(64, -10, id(font2), TextAlign::TOP_CENTER, "%H:%M", id(esptime).now());
      }

  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3D
    id: white_display
    lambda: |-
      // Print LivingRoom temperature (from homeassistant sensor)
      if (id(livingroom_temperature).has_state()) {
        it.white_display.printf(1, 64, id(font3), TextAlign::BASELINE_LEFT , "%.1f°", id(livingroom_temperature).state);
      }

      // Print LivingRoom humidity (from homeassistant sensor)
      if (id(livingroom_humidity).has_state()) {
        it.white_display.printf(127, 64, id(font3), TextAlign::BASELINE_RIGHT , "%.1f%%", id(livingroom_humidity).state);
      }

I tried using “id” to declare two different displays.
To be honest I don’t understand “it.strftime(” completely. I guess “it” is some kind of variable that I tried to replace or extend with my id’s I gave to the displays but the compiler keeps complaining about my id’s:

Compiling .pioenvs/muffy/src/main.cpp.o
Compiling .pioenvs/muffy/lib07d/ESPAsyncWebServer-esphome/WebAuthentication.cpp.o
/config/esphome/muffy.yaml: In lambda function:
**/config/esphome/muffy.yaml:101:10: error: 'class esphome::display::Display' has no member named 'blue_display'; did you mean 'Display'?**
       it.blue_display.strftime(64, -10, id(font2), TextAlign::TOP_CENTER, "%H:%M", id(esptime).now());
          ^~~~~~~~~~~~
          Display
/config/esphome/muffy.yaml: In function 'void setup()':
/config/esphome/muffy.yaml:102:8: error: expected ')' before '}' token
       }
        ^
        )
 
         
**src/main.cpp:2260:27: note: to match this '('**
**   blue_display->set_writer([=](display::Display & it) -> void {**
**                           ^**
**/config/esphome/muffy.yaml: At global scope:**
**/config/esphome/muffy.yaml:103:4: error: expected unqualified-id before ')' token**
** **
**    ^**
**/config/esphome/muffy.yaml:104:3: error: 'blue_display' does not name a type**
**   - platform: ssd1306_i2c**
**   ^~~~~~~~~~~~**
**/config/esphome/muffy.yaml:105:3: error: 'blue_display' does not name a type**
**     model: "SH1106 128x64"**
**   ^ ~~~~~~~~~~**
**/config/esphome/muffy.yaml:131:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:132:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:133:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:134:3: error: 'App' does not name a type**
**/config/esphome/muffy.yaml:135:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:136:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:137:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:138:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:139:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:140:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:141:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:142:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:143:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:144:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:118:4: error: expected unqualified-id before ')' token**
**/config/esphome/muffy.yaml:119:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:120:3: error: 'white_display' does not name a type**
**/config/esphome/muffy.yaml:128:3: error: 'App' does not name a type**
**/config/esphome/muffy.yaml:129:1: error: expected declaration before '}' token**
**Compiling .pioenvs/muffy/lib07d/ESPAsyncWebServer-esphome/WebHandlers.cpp.o**
***** [.pioenvs/muffy/src/main.cpp.o] Error 1**

I found a guy that used a second i2c bus because of the same i2c address on both displays. This could work in my case but I would consider it as a workaround. I would like to understand how to write the correct syntax.
Could somebody please give me a hint how to address the second display?
Thank you very much for your time and help!

What displays are you using ??
Do they support changing the I2C address ??
If so, have you done this and confirmed the display is now on 0x3D

it is the display object for which it is a lambda. So in both lambda’s you just use it. For example:

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    id: blue_display
    lambda: |-
      it.print(0, 10, id(font3), "Hello Blue display!");

  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3D
    id: white_display
    lambda: |-
      it.print(0, 10, id(font3), "Hello White display!");

But you need to change in hardware the address of the white display. It will not automatically listen to a different address.

Hey Timo - thanks a lot, this helps, at least in theory :slight_smile:
I have a new topic now as I have to find out if and how I can change the i2c address. Maybe I finally go for the workaround using a second bus although I recognized that this would require two more wires. Or… maybe somewhere is another oled with a different i2c address flying around.

Ok, I found that on the white display I could somehow change the I2C address. But I still cannot compile my code successfully, probably because of a syntax-error. Can someone please explain me what I did wrong/forgot?

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    id: blue_display
    lambda: |-
      // Print time in HH:MM format
      it.strftime(64, -10, id(font2), TextAlign::TOP_CENTER, "%H:%M", id(esptime).now());
      }

  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x78
    id: white_display
    lambda: |-
      // Print LivingRoom temperature (from homeassistant sensor)
      if (id(livingroom_temperature).has_state()) {
        it.printf(1, 64, id(font3), TextAlign::BASELINE_LEFT , "%.1f°", id(livingroom_temperature).state);
      }

      // Print LivingRoom humidity (from homeassistant sensor)
      if (id(livingroom_humidity).has_state()) {
        it.printf(127, 64, id(font3), TextAlign::BASELINE_RIGHT , "%.1f%%", id(livingroom_humidity).state);
      }

Since I introduced the display id’s the compiler complains about:

HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Dependency Graph
|-- AsyncTCP-esphome @ 2.1.4
|-- WiFi @ 2.0.0
|-- FS @ 2.0.0
|-- Update @ 2.0.0
|-- ESPAsyncWebServer-esphome @ 3.2.2
|-- DNSServer @ 2.0.0
|-- ESPmDNS @ 2.0.0
|-- noise-c @ 0.1.6
|-- Wire @ 2.0.0
Compiling .pioenvs/muffy/src/main.cpp.o
Compiling .pioenvs/muffy/lib07d/ESPAsyncWebServer-esphome/WebServer.cpp.o
/config/esphome/muffy.yaml: In function 'void setup()':
/config/esphome/muffy.yaml:102:8: error: expected ')' before '}' token
       }
        ^
        )
 
         
src/main.cpp:2260:27: note: to match this '('
   blue_display->set_writer([=](display::Display & it) -> void {
                           ^
/config/esphome/muffy.yaml: At global scope:
/config/esphome/muffy.yaml:103:4: error: expected unqualified-id before ')' token
 
    ^
/config/esphome/muffy.yaml:104:3: error: 'blue_display' does not name a type
   - platform: ssd1306_i2c
   ^~~~~~~~~~~~
/config/esphome/muffy.yaml:105:3: error: 'blue_display' does not name a type
     model: "SH1106 128x64"
   ^ ~~~~~~~~~~
/config/esphome/muffy.yaml:131:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:132:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:133:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:134:3: error: 'App' does not name a type
/config/esphome/muffy.yaml:135:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:136:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:137:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:138:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:139:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:140:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:141:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:142:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:143:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:144:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:118:4: error: expected unqualified-id before ')' token
/config/esphome/muffy.yaml:119:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:120:3: error: 'white_display' does not name a type
/config/esphome/muffy.yaml:128:3: error: 'App' does not name a type
/config/esphome/muffy.yaml:129:1: error: expected declaration before '}' token
*** [.pioenvs/muffy/src/main.cpp.o] Error 1
========================= [FAILED] Took 15.03 seconds =========================

Found the bracket and removed it… :see_no_evil: compiles successfully now, will report any progress.