Component display took a long time for an operation (283 ms)

Hi, I seem to have very slow comms with my I2C OLED display. Is it just my setup or is this common elsewhere? Typical log entries show latency over and over again:

[12:44:40][W][component:237]: Component display took a long time for an operation (283 ms).
[12:44:40][W][component:238]: Components should block for at most 30 ms.
[12:44:41][W][component:237]: Component display took a long time for an operation (283 ms).
[12:44:41][W][component:238]: Components should block for at most 30 ms.
[12:44:42][W][component:237]: Component display took a long time for an operation (283 ms).
[12:44:42][W][component:238]: Components should block for at most 30 ms.

The hardware config is an ESP32 WROOM-32E (HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash). The display is a 0.96" I2C SSD1306 (128*64), but I have also tested a 1.3" version and it’s the same.

Here are the important parts from the YAML.
The page rotation on the display only happens every 10 seconds but the latency errors occur every second.

esp32:
  board: esp32dev
  framework:
    type: arduino
i2c:
  # Support for the RTC with backup battery
  sda: 21
  scl: 22
  scan: true
  id: bus_a
display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    id: white_oled
    contrast: 40%
    reset_pin: 23
    # address: 0x3C
    pages:
      - id: page1 
        lambda: |-
            it.printf(0, 0, id(font1), "Heating");
            it.printf(0, 20, id(font1), "Controller");
      - id: page2
        lambda: |-
            char str[17];
            //const time_t oneHourInSec = 3600;
            //time_t currTime = id(ds1307_time).now().timestamp + oneHourInSec;
            time_t currTime = id(ds1307_time).now().timestamp;
            strftime(str, sizeof(str), "%H:%M", localtime(&currTime));
            it.printf(0, 0, id(font1), "Time: %s", str);
            it.printf(0, 44, id(font1), "%.1f°C", id(office_temperature).state);
      - id: page3
        lambda: |-
            it.printf(0, 0, id(font1), "BOOST UNTIL");
            it.printf(0, 44, id(font1), TextAlign::BOTTOM_LEFT, "Up   - %s", id(text_time_us_heating).state.c_str());
            it.printf(0, 64, id(font1), TextAlign::BOTTOM_LEFT, "Down - %s", id(text_time_ds_heating).state.c_str());

interval:
  - interval: 10s
    # Interval timer for page changes on OLED display
    then:
      - display.page.show_next: white_oled
      - component.update: white_oled
[12:44:38][C][i2c.arduino:071]: I2C Bus:
[12:44:38][C][i2c.arduino:072]:   SDA Pin: GPIO21
[12:44:38][C][i2c.arduino:073]:   SCL Pin: GPIO22
[12:44:38][C][i2c.arduino:074]:   Frequency: 50000 Hz
[12:44:38][C][i2c.arduino:086]:   Recovery: bus successfully recovered
[12:44:38][I][i2c.arduino:096]: Results from i2c bus scan:
[12:44:38][I][i2c.arduino:102]: Found i2c device at address 0x3C
[12:44:38][I][i2c.arduino:102]: Found i2c device at address 0x50
[12:44:38][I][i2c.arduino:102]: Found i2c device at address 0x68
...
[12:44:39][C][ssd1306_i2c:023]: I2C SSD1306
[12:44:39][C][ssd1306_i2c:023]:   Rotations: 0 °
[12:44:39][C][ssd1306_i2c:023]:   Dimensions: 128px x 64px
[12:44:39][C][ssd1306_i2c:024]:   Address: 0x3C
[12:44:39][C][ssd1306_i2c:025]:   Model: SH1106 128x64
[12:44:39][C][ssd1306_i2c:026]:   Reset Pin: GPIO23
[12:44:39][C][ssd1306_i2c:027]:   External VCC: NO
[12:44:39][C][ssd1306_i2c:028]:   Flip X: YES
[12:44:39][C][ssd1306_i2c:029]:   Flip Y: YES
[12:44:39][C][ssd1306_i2c:030]:   Offset X: 0
[12:44:39][C][ssd1306_i2c:031]:   Offset Y: 0
[12:44:39][C][ssd1306_i2c:032]:   Inverted Color: NO
[12:44:39][C][ssd1306_i2c:033]:   Update Interval: 1.0s

The hardware board is a 4-relay type and I have two LED’s and an RTC fitted. The RTC is also on the I2C bus, but even with this physically eliminated the problem still remains.

How can I judge the utilisation of the ESP32 CPU during use, is there a method of outputting a load value during runtime? Are there modules which are known to cause latency when used with I2C displays?

Ok, I resolved it. :slight_smile:
It’s the I2C frequency - the default is 50kHz - not enough for my needs.

I used 300kHz and it’s fine since:

i2c:
  # Support for the RTC with backup battery
  sda: 21
  scl: 22
  scan: True
  frequency: 300kHz
  id: bus_a