Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues trying to get a SSD1306 to display text #128

Closed
rlust opened this issue Sep 27, 2018 · 22 comments
Closed

Issues trying to get a SSD1306 to display text #128

rlust opened this issue Sep 27, 2018 · 22 comments

Comments

@rlust
Copy link

rlust commented Sep 27, 2018

I have a D1 mini pro that was working displaying text, and now I am trying to get it working on esphomeyaml.
I am not getting anything to display. I need to know if I am missing something.
The display component is a very exciting addition to this great software!
I am using the following code:

esphomeyaml:
  name: oledoffice
  platform: ESP8266
  board: d1_mini_pro

wifi:
  

mqtt:
  broker: '192.168.1.xx'
  username: 'xx'
  password: 'xx'

# Enable logging
logger:

ota:

#Example configuration entry
time:
  - platform: sntp
    id: sntp_time
    servers:
      - 0.pool.ntp.org
      - 1.pool.ntp.org
      - 2.pool.ntp.org
# image:
#   - file: "image.png"
#     id: my_image
#     resize: 100x100

sensor:
  - platform: dht
    pin: D5
    temperature:
      name: "Off temperature"
    humidity:
      name: "Off humidity"
      id: my_sensor
    model: AM2302
    update_interval: 15s
binary_sensor:
  - platform: status
    name: "Off ESP32 Status"    
switch:
  - platform: restart
    name: "Off OLED Restart"
font:
  - file: "Sansation-Regular.ttf"
    id: my_font
    size: 20
i2c:
  sda: D1
  scl: D2
  scan: True

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    reset_pin: D0
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(my_font), "Hello World!");
      it.strftime(70, 0, id(my_font), "%Y-%m-%d %H:%M", id(sntp_time).now());  
@OttoWinter
Copy link
Member

Hmmm, I only had an SPI-based SSD1306 to test, and since both used kind of the same protocol I though both would work, but apparently not. Could you set your logger level to very_verbose and post the logs from that here? It would show all the i2c communication between the ESP and the display and would be very helpful to debug the issue. I have now also ordered an i2c-based SSD1306 display so that I can debug it later (though shipping from china does tend to take a while).

@mssaleh
Copy link

mssaleh commented Sep 27, 2018

I tried a very_verbose logger on the SSD1306 i2c, and here is a part of what came out (mainly it's repeated over and over):

[19:41:03][C][display.ssd1306:281]: Setting up I2C SSD1306...
[19:41:03][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:03][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:03][D][display.ssd1306:228]: fill(0): 0x0x3fff5b44
[19:41:03][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:03][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:03][VV][i2c:117]: Writing 0b10101111 (0xAF)
[19:41:03][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:03][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:03][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:03][VV][i2c:117]: Writing 0b11010101 (0xD5)
[19:41:03][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:03][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:117]: Writing 0b10000000 (0x80)
[19:41:04][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:04][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:117]: Writing 0b10101000 (0xA8)
[19:41:04][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:04][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:117]: Writing 0b00111111 (0x3F)
[19:41:04][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:04][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:117]: Writing 0b11010011 (0xD3)
[19:41:04][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:04][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:04][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:04][VV][i2c:117]: Writing 0b01000000 (0x40)
[19:41:04][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:04][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:04][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b10001101 (0x8D)
[19:41:05][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:05][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b00010000 (0x10)
[19:41:05][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:05][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b00100000 (0x20)
[19:41:05][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:05][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:05][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b10100001 (0xA1)
[19:41:05][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:05][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b11001000 (0xC8)
[19:41:05][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:05][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:05][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:05][VV][i2c:117]: Writing 0b11011010 (0xDA)
[19:41:06][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:06][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:06][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:06][VV][i2c:117]: Writing 0b00010010 (0x12)
[19:41:06][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:06][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:06][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:06][VV][i2c:117]: Writing 0b10000001 (0x81)
[19:41:06][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:06][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:06][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:06][VV][i2c:117]: Writing 0b10011111 (0x9F)
[19:41:06][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:06][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:06][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:06][VV][i2c:117]: Writing 0b11011001 (0xD9)
[19:41:06][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:06][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:06][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:06][VV][i2c:117]: Writing 0b00100010 (0x22)
[19:41:06][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:06][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:06][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:06][VV][i2c:117]: Writing 0b11011011 (0xDB)
[19:41:07][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:07][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:07][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:07][VV][i2c:117]: Writing 0b01000000 (0x40)
[19:41:07][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:07][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:07][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:07][VV][i2c:117]: Writing 0b10100100 (0xA4)
[19:41:07][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:07][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:07][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:07][VV][i2c:117]: Writing 0b10100110 (0xA6)
[19:41:07][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:07][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:07][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:07][VV][i2c:117]: Writing 0b00101110 (0x2E)
[19:41:07][VV][i2c:084]: Transmission ended. Status code: 0x00
[19:41:07][VV][i2c:079]: Beginning Transmission to 0x3C:
[19:41:07][VV][i2c:117]: Writing 0b00000000 (0x00)
[19:41:07][VV][i2c:117]: Writing 0b10101110 (0xAE)
[19:41:07][VV][i2c:084]: Transmission ended. Status code: 0x00

@OttoWinter
Copy link
Member

OttoWinter commented Sep 27, 2018

Oh wow, thanks! I think I just found at least one issue (and I have no clue why this would only show up with i2c, not spi) - In my implementation, I had the bytes for display on (0xAF) and off (0xAE) switched around. So when the display should turn on, it would be turned off :(

I have created a patch locally, but I will look at more of your log to see if there are any other issues.

In the meantime, could you try setting

esphomeyaml:
  # ...
  esphomelib_version: dev

and seeing if it works already?

@OttoWinter OttoWinter added the bug label Sep 27, 2018
@rlust
Copy link
Author

rlust commented Sep 27, 2018

I used you help in changing the yaml file to capture the verbose logs. I am now getting a series of dots on the display but it is not any data, and the esp stops running with an error.
Here is the yaml with changes:

esphomeyaml:
  name: oledoffice
  esphomelib_version: dev
  platform: ESP8266
  board: d1_mini_pro

wifi:
  ssid: 'xxxx'
  password: 'xxxxx'

mqtt:
  broker: '192.168.1.xx

  username: 'xx'
  password: 'xx'

# Enable logging
logger: 
  level: very_verbose
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: Espressif 8266 > WeMos D1 mini Pro
SYSTEM: ESP8266 80MHz 80KB RAM (16MB Flash)
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 38 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <ArduinoOTA> 1.0
|   |-- <ESP8266mDNS>
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266WiFi> 1.0
|-- <ESP8266WiFi> 1.0
|-- <ESP8266mDNS>
|   |-- <ESP8266WiFi> 1.0
|-- <Hash> 1.0
|-- <Wire> 1.0
|-- <esphomelib> 1.8.0 #e095235
|   |-- <AsyncMqttClient> 0.8.2
|   |   |-- <ESPAsyncTCP> 1.2.0
|   |   |   |-- <ESP8266WiFi> 1.0
|   |-- <ArduinoJson-esphomelib> 5.13.3
|   |-- <ESP Async WebServer> 1.1.1
|   |   |-- <ESPAsyncTCP> 1.2.0
|   |   |   |-- <ESP8266WiFi> 1.0
|   |   |-- <Hash> 1.0
|   |   |-- <ESP8266WiFi> 1.0
|   |   |-- <ArduinoJson-esphomelib> 5.13.3
|   |-- <FastLED> 3.2.0 #d27bac9
|   |   |-- <EspSoftwareSerial> 3.4.1
|   |-- <ArduinoOTA> 1.0
|   |   |-- <ESP8266mDNS>
|   |   |   |-- <ESP8266WiFi> 1.0
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266WiFi> 1.0
|   |-- <Wire> 1.0
|   |-- <ESP8266mDNS>
|   |   |-- <ESP8266WiFi> 1.0
Retrieving maximum program size .pioenvs/oledoffice/firmware.elf
Checking size .pioenvs/oledoffice/firmware.elf
Memory Usage -> http://bit.ly/pio-memory-usage
DATA:    [=====     ]  52.1% (used 42648 bytes from 81920 bytes)
PROGRAM: [====      ]  36.0% (used 375720 bytes from 1044464 bytes)
Configuring upload protocol...
Looking for upload port...
Use manually specified: /dev/cu.SLAB_USBtoUART
Uploading .pioenvs/oledoffice/firmware.bin
warning: serialport_set_baudrate: baud rate 921600 may not work
Uploading 379872 bytes from .pioenvs/oledoffice/firmware.bin to flash at 0x00000000
................................................................................ [ 21% ]
................................................................................ [ 43% ]
................................................................................ [ 64% ]
................................................................................ [ 86% ]
...................................................                              [ 100% ]
====================================================================================================== [SUCCESS] Took 22.71 seconds ======================================================================================================
INFO [esphomeyaml.__main__] Successfully uploaded program.
INFO [esphomeyaml.__main__] Starting log output from /dev/cu.SLAB_USBtoUART with baud rate 115200
[13:11:58]10100 (0x14)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00100000 (0x20)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b10100001 (0xA1)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b11001000 (0xC8)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b11011010 (0xDA)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00010010 (0x12)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b10000001 (0x81)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b11001111 (0xCF)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b11011001 (0xD9)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b11110001 (0xF1)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b11011011 (0xDB)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b01000000 (0x40)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b10100100 (0xA4)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b10100110 (0xA6)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00101110 (0x2E)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b10101111 (0xAF)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][C][component:243]:     Update interval: 5000ms
[13:11:58][V][component:062]: set_interval(name='update', interval=5000, offset=188)
[13:11:58][C][time.sntp:041]: Setting up SNTP...
[13:11:58][C][wifi:031]: Setting up WiFi...
[13:11:58][I][wifi:239]: WiFi Connecting to 'Lust'...
[13:11:58][C][wifi:256]:     STA Hostname: 'oledoffice'
[13:11:58][VV][component:136]: Running interval 'update':0 with interval=5000 last_execution=3178 (now=8388)
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00100001 (0x21)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b01111111 (0x7F)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00100010 (0x22)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
[13:11:58][VV][i2c:117]:     Writing 0b00000000 (0x00)
[13:11:58][VV][i2c:117]:     Writing 0b00000111 (0x07)
[13:11:58][VV][i2c:084]:     Transmission ended. Status code: 0x00
[13:11:58][VV][i2c:079]: Beginning Transmission to 0x3C:
// Collapsed...

@OttoWinter
Copy link
Member

@rlust Yes the error is expected. The very verbose logs are dumping too much data which triggers the hardware watchdog. What happens with just debug logs? The dots you're seeing could be a sign it is finally working. Thanks for the help!

@mssaleh
Copy link

mssaleh commented Sep 27, 2018

Unfortunately it hasn't worked with esphomelib_version: dev. On the contrary, other i2c sensors stopped working with this build. It seems that something is making the ESP2866 soft-reset repeatedly in the middle of the i2c transport.
Here is a part of the log after trying it:
link to log

@OttoWinter
Copy link
Member

@mssaleh Same thing, the debug logs are spamming the esp so much that it triggers the watchdog. "Soft WDT reset"

@mssaleh
Copy link

mssaleh commented Sep 27, 2018

I restored level: debug for the logger, and kept the esphomelib_version: dev flag. Now the i2c sensors are working, but the SSD1306 display is almost no show now. It isn't working, and the only log entries related to it are when the i2c scan function discovered the address:

[21:32:06][I][i2c:054]: Scanning i2c bus for active devices...
[21:32:06][I][i2c:061]: Found i2c device at address 0x23
[21:32:06][I][i2c:061]: Found i2c device at address 0x3C
[21:32:06][I][i2c:061]: Found i2c device at address 0x76

@fastbytes
Copy link

@OttoWinter It works! I had a similar issue using only one i2c device, an integrated SSD1306 display (ttgo-lora32-v1). Once I adding esphomelib_version: dev, the display is now working.

@mssaleh I'm not sure why, but I don't believe the reset_pin is working. Try adding this to the beginning of the generated main.cpp -- I needed to add this otherwise communication to the SSD1306 would just fail.

Without manually sending reset

[19:19:54][C][display.ssd1306:280]: Setting up I2C SSD1306...
[19:19:54][W][i2c:093]: Received NACK on transmit of address 0x3C
[19:19:54][E][display.ssd1306:284]: Communication with SSD1306 failed!
[19:19:54][E][component:166]: Component was marked as failed.

With manual reset (change 16 to match the PIN you are using)

  // Reset OLED display
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);
  delay(50);
  digitalWrite(16, HIGH);
[19:24:55][C][display.ssd1306:280]: Setting up I2C SSD1306...
[19:24:55][C][esphal:067]:     GPIO Pin 16 with mode OUTPUT

Also, I added this just after App.setup(); as a test (should display a box around the edge of the screen).

  // Update display
  display_i2cssd1306->rectangle(0, 0, display_i2cssd1306->get_width(), display_i2cssd1306->get_height());
  display_i2cssd1306->update();

@fastbytes
Copy link

It looks like the I2CSSD1306::setup() function attempts to begin transmittion before resetting the display, resulting in a NACK. We never make it to the SSD1306::setup() function, so the display is never enabled.

I'm not a developer by any means, so use the following with caution, but the following patch seemed to work for me.

--- D:\code\ESP32\esphomeyaml\ttgo2\.piolibdeps\esphomelib\src\esphomelib\display\ssd1306.cpp	2018-09-27 19:00:48.000000000 -0400
+++ D:\code\ESP32\esphomeyaml\ttgo3\.piolibdeps\esphomelib\src\esphomelib\display\ssd1306.cpp	2018-09-27 20:07:47.000000000 -0400
@@ -41,23 +41,12 @@
 
 static const uint8_t SSD1306_NORMAL_DISPLAY = 0xA6;
 
 void SSD1306::setup() {
   this->init_internal_(this->get_buffer_length_());
 
-  if (this->reset_pin_ != nullptr) {
-    this->reset_pin_->setup();
-    this->reset_pin_->digital_write(true);
-    delay(1);
-    // Trigger Reset
-    this->reset_pin_->digital_write(false);
-    delay(10);
-    // Wake up
-    this->reset_pin_->digital_write(true);
-  }
-
   this->command(SSD1306_COMMAND_DISPLAY_OFF);
   this->command(SSD1306_COMMAND_SET_DISPLAY_CLOCK_DIV);
   this->command(0x80); // suggested ratio
 
   this->command(SSD1306_COMMAND_SET_MULTIPLEX);
   this->command(this->get_height_internal_() - 1);
@@ -234,12 +223,23 @@
   return true;
 }
 void SPISSD1306::setup() {
   ESP_LOGCONFIG(TAG, "Setting up SPI SSD1306...");
   this->spi_setup();
   this->dc_pin_->setup(); // OUTPUT
+  
+  if (this->reset_pin_ != nullptr) {
+    this->reset_pin_->setup();
+    this->reset_pin_->digital_write(true);
+    delay(1);
+    // Trigger Reset
+    this->reset_pin_->digital_write(false);
+    delay(10);
+    // Wake up
+    this->reset_pin_->digital_write(true);
+  }
 
   SSD1306::setup();
 }
 void SPISSD1306::command(uint8_t value) {
   this->dc_pin_->digital_write(false);
   this->enable();
@@ -275,12 +275,23 @@
 }
 #endif
 
 #ifdef USE_I2C
 void I2CSSD1306::setup() {
   ESP_LOGCONFIG(TAG, "Setting up I2C SSD1306...");
+  
+  if (this->reset_pin_ != nullptr) {
+    this->reset_pin_->setup();
+    this->reset_pin_->digital_write(true);
+    delay(1);
+    // Trigger Reset
+    this->reset_pin_->digital_write(false);
+    delay(10);
+    // Wake up
+    this->reset_pin_->digital_write(true);
+  }
 
   this->parent_->begin_transmission_(this->address_);
   if (!this->parent_->end_transmission_(this->address_)) {
     ESP_LOGE(TAG, "Communication with SSD1306 failed!");
     this->mark_failed();
     return;

P.S.: Thanks for this amazing project! I've been toying around to create a similar framework using ESP-IDF, but this project blows it out of the water! Good work 👍 :)

@rlust
Copy link
Author

rlust commented Sep 28, 2018

The SSD1306 I2C I have only has four pins, and does not have a reset pin. I removed the reset pin i2c define.

Would that cause a problem?
With just the debug log it runs but does not display anything.

@fastbytes
Copy link

fastbytes commented Sep 28, 2018

Hey @rlust -- not sure, the SSD1306 I'm using is integrated on the ESP32 I'm using. However, regardless if you are using SPI or I2C, it looks like the pinouts always require an RST pin which is needed to enable the display.

I found a write-up for an Adafruit SSD1306 which has pinouts for both I2C and SPI. Good luck!

https://learn.adafruit.com/monochrome-oled-breakouts/wiring-128x64-oleds

GND goes to ground
Vin goes to 5V
Data to I2C SDA (on the Uno, this is A4 on the Mega it is 20 and on the Leonardo digital 2)
Clk to I2C SCL (on the Uno, this is A5 on the Mega it is 21 and on the Leonardo digital 3)
RST to digital 4 (you can change this pin in the code, later)

@fastbytes
Copy link

Well, I got a little carried away, and kept playing with the new Display logic... many hours later, it seems to be working quite well! I'm sure I'll regret not going to be earlier tomorrow, but it's hard to stop ;)

It appears lambda functionality was missing for ssd1306 displays, so even if I put it in the YAML config, it would never make it into main.cpp. Once I got that working, I noticed set_writer and other commands were not there in esphomelib. I made a few changes to esphomeyaml and esphomelib, and it has been working well for a few hours. I'm sure this could have been written better, but it served my needs.

Here's the git diffs for each based on esphomelib_version: dev -- hope this helps someone!

esphomeyaml

diff --git a/esphomeyaml/components/display/ssd1306_i2c.py b/esphomeyaml/components/display/ssd1306_i2c.py
index 7e04082..0347204 100644
--- a/esphomeyaml/components/display/ssd1306_i2c.py
+++ b/esphomeyaml/components/display/ssd1306_i2c.py
@@ -4,12 +4,13 @@ import esphomeyaml.config_validation as cv
 from esphomeyaml import pins
 from esphomeyaml.components import display
 from esphomeyaml.components.display import ssd1306_spi
-from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, CONF_RESET_PIN
-from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression
+from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, CONF_RESET_PIN, CONF_LAMBDA
+from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, process_lambda

 DEPENDENCIES = ['i2c']

 I2CSSD1306 = display.display_ns.I2CSSD1306
+I2CSSD1306Ref = I2CSSD1306.operator('ref')

 PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
     cv.GenerateID(): cv.declare_variable_id(I2CSSD1306),
@@ -21,7 +22,8 @@ PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({


 def to_code(config):
-    ssd = Pvariable(config[CONF_ID], App.make_i2c_ssd1306())
+    rhs = App.make_i2c_ssd1306();
+    ssd = Pvariable(config[CONF_ID], rhs)
     add(ssd.set_model(ssd1306_spi.MODELS[config[CONF_MODEL]]))

     if CONF_RESET_PIN in config:
@@ -32,6 +34,10 @@ def to_code(config):
         add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC]))
     if CONF_ADDRESS in config:
         add(ssd.set_address(config[CONF_ADDRESS]))
+    if CONF_LAMBDA in config:
+        for lambda_ in process_lambda(config[CONF_LAMBDA], [(I2CSSD1306Ref, 'it')]):
+            yield
+        add(ssd.set_writer(lambda_))

     display.setup_display(ssd, config)

esphomelib

diff --git a/src/esphomelib/display/ssd1306.cpp b/src/esphomelib/display/ssd1306.cpp
index 43f9c11..5c3a302 100644
--- a/src/esphomelib/display/ssd1306.cpp
+++ b/src/esphomelib/display/ssd1306.cpp
@@ -12,6 +12,7 @@
 
 #include "esphomelib/display/ssd1306.h"
 #include "esphomelib/log.h"
+#include "ssd1306.h"
 
 ESPHOMELIB_NAMESPACE_BEGIN
 
@@ -44,17 +45,6 @@ static const uint8_t SSD1306_NORMAL_DISPLAY = 0xA6;
 void SSD1306::setup() {
   this->init_internal_(this->get_buffer_length_());
 
-  if (this->reset_pin_ != nullptr) {
-    this->reset_pin_->setup();
-    this->reset_pin_->digital_write(true);
-    delay(1);
-    // Trigger Reset
-    this->reset_pin_->digital_write(false);
-    delay(10);
-    // Wake up
-    this->reset_pin_->digital_write(true);
-  }
-
   this->command(SSD1306_COMMAND_DISPLAY_OFF);
   this->command(SSD1306_COMMAND_SET_DISPLAY_CLOCK_DIV);
   this->command(0x80); // suggested ratio
@@ -238,8 +228,22 @@ void SPISSD1306::setup() {
   this->spi_setup();
   this->dc_pin_->setup(); // OUTPUT
 
+  if (this->reset_pin_ != nullptr) {
+    this->reset_pin_->setup();
+    this->reset_pin_->digital_write(true);
+    delay(1);
+    // Trigger Reset
+    this->reset_pin_->digital_write(false);
+    delay(10);
+    // Wake up
+    this->reset_pin_->digital_write(true);
+  }
+
   SSD1306::setup();
 }
+void SPISSD1306::set_writer(spissd_writer_t &&writer) {
+  this->writer_ = std::move(writer);
+}
 void SPISSD1306::command(uint8_t value) {
   this->dc_pin_->digital_write(false);
   this->enable();
@@ -273,12 +277,28 @@ SPISSD1306::SPISSD1306(SPIComponent *parent, GPIOPin *cs, GPIOPin *dc_pin, uint3
 bool SPISSD1306::high_speed() {
   return true;
 }
+void SPISSD1306::update() {
+  if (this->writer_.has_value())
+    (*this->writer_)(*this);
+  SSD1306::update();
+}
 #endif
 
 #ifdef USE_I2C
 void I2CSSD1306::setup() {
   ESP_LOGCONFIG(TAG, "Setting up I2C SSD1306...");
 
+  if (this->reset_pin_ != nullptr) {
+    this->reset_pin_->setup();
+    this->reset_pin_->digital_write(true);
+    delay(1);
+    // Trigger Reset
+    this->reset_pin_->digital_write(false);
+    delay(10);
+    // Wake up
+    this->reset_pin_->digital_write(true);
+  }
+
   this->parent_->begin_transmission_(this->address_);
   if (!this->parent_->end_transmission_(this->address_)) {
     ESP_LOGE(TAG, "Communication with SSD1306 failed!");
@@ -288,6 +308,9 @@ void I2CSSD1306::setup() {
 
   SSD1306::setup();
 }
+void I2CSSD1306::set_writer(i2cssd_writer_t &&writer) {
+  this->writer_ = std::move(writer);
+}
 void I2CSSD1306::command(uint8_t value) {
   this->write_byte(0x00, value);
 }
@@ -314,6 +337,11 @@ void I2CSSD1306::write_display_data() {
     }
   }
 }
+void I2CSSD1306::update() {
+  if (this->writer_.has_value())
+    (*this->writer_)(*this);
+  SSD1306::update();
+}
 I2CSSD1306::I2CSSD1306(I2CComponent *parent, uint32_t update_interval)
     : I2CDevice(parent, 0x3C), SSD1306(update_interval) {}
 #endif
diff --git a/src/esphomelib/display/ssd1306.h b/src/esphomelib/display/ssd1306.h
index 3cd1bb7..eef89d6 100644
--- a/src/esphomelib/display/ssd1306.h
+++ b/src/esphomelib/display/ssd1306.h
@@ -65,10 +65,14 @@ class SSD1306 : public PollingComponent, public DisplayBuffer {
 };
 
 #ifdef USE_SPI
+class SPISSD1306;
+
+using spissd_writer_t = std::function<void(SPISSD1306 &)>;
+
 class SPISSD1306 : public SSD1306, public SPIDevice {
  public:
   SPISSD1306(SPIComponent *parent, GPIOPin *cs, GPIOPin *dc_pin, uint32_t update_interval = 1000);
-
+  void update() override;
   void setup() override;
 
  protected:
@@ -79,17 +83,25 @@ class SPISSD1306 : public SSD1306, public SPIDevice {
   bool high_speed() override;
 
   GPIOPin *dc_pin_;
+  optional<spissd_writer_t> writer_{};
 };
 #endif
 
 #ifdef USE_I2C
+class I2CSSD1306;
+
+using i2cssd_writer_t = std::function<void(I2CSSD1306 &)>;
+
 class I2CSSD1306 : public SSD1306, public I2CDevice {
  public:
   I2CSSD1306(I2CComponent *parent, uint32_t update_interval = 1000);
+  void set_writer(i2cssd_writer_t &&writer);
   void setup() override;
+  void update() override;
  protected:
   void command(uint8_t value) override;
   void write_display_data() override;
+  optional<i2cssd_writer_t> writer_{};
 };
 #endif
 

myconfig.yaml

esphomeyaml:
  name: ttgo3
  platform: ESP32
  board: ttgo-lora32-v1
  esphomelib_version: dev

wifi:
  ssid: 'XXXXXXX'
  password: 'XXXXXXXXXXXXXX'

mqtt:
  broker: 'XXXXXXXXXXXXXXXXX'
  port: XXXX
  username: 'XXXXX'
  password: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

logger:
  level: VERY_VERBOSE
  logs:
    i2c: DEBUG
    spi: DEBUG

ota:

i2c:
  sda: GPIO4
  scl: GPIO15
  scan: false
  frequency: 700khz

font:
  - file: 'Lato-Regular.ttf'
    id: my_font
    size: 10

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    reset_pin: GPIO16
    address: 0x3C
    update_interval: 5s
    lambda: |-
      // Clear display (not sure if this is needed?)
      it.fill(0);
      // Current time, random location (like a screensaver)
      it.strftime(rand()%(20), rand()%(51), id(my_font), "%Y-%m-%d %H:%M:%S", id(sntp_time).now());

time:
  - platform: sntp
    id: sntp_time
    timezone: 'EST+5EDT,M3.2.0/2,M11.1.0/2'
    servers:
      - 0.ca.pool.ntp.org
      - 1.ca.pool.ntp.org
      - 2.ca.pool.ntp.org

OttoWinter added a commit to esphome/esphome-core that referenced this issue Sep 28, 2018
OttoWinter added a commit that referenced this issue Sep 28, 2018
@OttoWinter
Copy link
Member

OttoWinter commented Sep 28, 2018

@guardmedia Thank you very much for taking your time to fix this. It's very much appreciated! I've created the PRs #132 and esphome/esphome-core#159 to fix the issue as per your diffs (cleaned up a little bit).

The first issue, esphomeyaml not including the lambda: , in the C++ output is ... well a dumb mistake of mine :) I always debug with C++ code and later write tests in YAML, but those didn't catch that bug :( (Also, the set_writer method does exist for the SSD1306 class, it's just in the parent class DisplayBuffer 😉)

For the RESET pin issue: That's really interesting. It seems like when the RESET pin is not pulled high it won't even accept any i2c data (so a full shutdown). The reason @mssaleh doesn't have a RESET pin is because well that pin is quite unnecessary. If the breakout board the SSD1306 is mounted on has a small pull-up resistor to VCC, there's no external RESET pin necessary. Also, the SPI component fortunately didn't suffer from this either because it doesn't do any communication before the reset initialization code 😆

I will merge the mentioned PRs when I get time to test with my SPI setup again.

OttoWinter added a commit to esphome/esphome-core that referenced this issue Sep 28, 2018
OttoWinter added a commit that referenced this issue Sep 28, 2018
@brandond
Copy link
Collaborator

I am super happy to have this in esphome, I have a Wemos clone with integrated SSD1306 that I have been putting off converting over from micropython due to lack of support for the LCD!

@fastbytes
Copy link

@OttoWinter Just ran a test with a clean git pull of esphomeyaml, using esphomelib_version: dev, and it is working perfectly! Your approach is much cleaner, I haven't really got the grasp of C++ yet, but I'm getting there!😆 Also, good to know about the reset pin... it seems strange TTGO/Heltec would waste a GPIO just for the reset pin, but maybe this has changed in their newer versions (bought a bunch of the V1 boards a while back).

Thanks again!

@mssaleh
Copy link

mssaleh commented Sep 29, 2018

What a great and speedy effort! I also can confirm that i2c display now works perfectly with this fix (including using lambda). Many thanks to @OttoWinter, @guardmedia and everyone else involved in this wonderful piece of software!

@jblb
Copy link

jblb commented Sep 29, 2018

thanks what's work for me !

@OttoWinter
Copy link
Member

Ok, that's great. I'll close this issue now and hopefully release 1.8.2 in the next few days.

@rlust
Copy link
Author

rlust commented Oct 1, 2018

Great news, I got an e-paper module and I am able to display text now! Thanks for the work OttoWinter!

If anyone has the code working to display the values from a DHT temperature sensor I would love to see an example.

Love the increase of functionality of the software and ease of use!!

@rlust
Copy link
Author

rlust commented Oct 1, 2018

Ok I figured it out: There is a slight error in the example code for temp sensor, it is missing a f after the "Temperature %.2fC and I cannot get the degree symbol to display.
Here is the sensor config:

sensor:
  - platform: dht
    pin: GPIO27
    temperature:
      name: 'Display temperature'
      id: temperature
    humidity:
      name: 'Display humidity'
      id: humidity
    model: AM2302
    update_interval: 15s
it.print(0, 0, id(my_font), "Hello Randy welcome to my World!");
it.strftime(0, 20, id(my_font), "%Y-%m-%d %H:%M:%S", id(sntp_time).now());
it.printf(0, 45, id(my_font), "Temperature %.2fC, Humidity %.1f%%", id(temperature).value, id(humidity).value);
font:
  - file: 'Comic Sans MS.ttf'
    id: my_font
    size: 14

OttoWinter added a commit to esphome/esphome-docs that referenced this issue Oct 4, 2018
OttoWinter added a commit that referenced this issue Oct 4, 2018
@OttoWinter
Copy link
Member

@rlust Thanks, I'll update that.

For the degree symbol: What exactly doesn't work? Does it not compiled, does it not show up, or what is it?

OttoWinter added a commit to esphome/esphome-docs that referenced this issue Oct 4, 2018
@esphome esphome locked and limited conversation to collaborators Jun 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants