issues
issues copied to clipboard
Support for SH1107
The problem
I was looking for support for the SH1107 OLED driver, and found a merged PR https://github.com/esphome/esphome/pull/2967, which actually was testing on the same HW I was searching for support on, the Adafruit FeatherWing OLED - 128x64 OLED.
But I was unable to make it work, the display is only showing white noise.
I have supplied my full config.yaml, and I'm using the example from the PR
Which version of ESPHome has the issue?
Version: 2022.1.0-dev
What type of installation are you using?
pip
Which version of Home Assistant has the issue?
No response
What platform are you using?
ESP32
Board
featheresp32
Component causing the issue
ssd1306_i2c
Example YAML snippet
esphome:
name: oled
esp32:
board: featheresp32
framework:
type: arduino
# Enable logging
logger:
i2c:
display:
- platform: ssd1306_i2c
model: 'SH1107_128x64'
rotation: 90
flip_x: false
flip_y: false
offset_y: -30
lambda: |-
it.line(0, 0, 128, 64);
// Draw the outline of a rectangle with the top left at [5,5], a width of 10 and a height of 10
it.rectangle(5, 5, 10, 10);
it.circle(118, 54, 5);
Anything in the logs that might be useful for us?
[08:18:47][I][logger:214]: Log initialized
[08:18:47][I][app:029]: Running through setup()...
[08:18:47][I][i2c.arduino:159]: Performing I2C bus recovery
[08:18:47][C][ssd1306_i2c:010]: Setting up I2C SSD1306...
[08:18:48][I][app:062]: setup() finished successfully!
[08:18:48][I][app:102]: ESPHome version 2022.1.0-dev compiled on Jan 5 2022, 08:18:12
[08:18:48][C][logger:233]: Logger:
[08:18:48][C][logger:234]: Level: DEBUG
[08:18:48][C][logger:235]: Log Baud Rate: 115200
[08:18:48][C][logger:236]: Hardware UART: UART0
[08:18:48][C][i2c.arduino:037]: I2C Bus:
[08:18:48][C][i2c.arduino:038]: SDA Pin: GPIO23
[08:18:48][C][i2c.arduino:039]: SCL Pin: GPIO22
[08:18:48][C][i2c.arduino:040]: Frequency: 50000 Hz
[08:18:48][C][i2c.arduino:043]: Recovery: bus successfully recovered
[08:18:48][I][i2c.arduino:053]: Results from i2c bus scan:
[08:18:48][I][i2c.arduino:059]: Found i2c device at address 0x3C
[08:18:48][C][ssd1306_i2c:023]: I2C SSD1306
[08:18:48][C][ssd1306_i2c:023]: Rotations: 90 °
[08:18:48][C][ssd1306_i2c:023]: Dimensions: 128px x 64px
[08:18:48][C][ssd1306_i2c:024]: Address: 0x3C
[08:18:48][C][ssd1306_i2c:025]: Model: SH1107 128x64
[08:18:48][C][ssd1306_i2c:027]: External VCC: NO
[08:18:48][C][ssd1306_i2c:028]: Flip X: NO
[08:18:48][C][ssd1306_i2c:029]: Flip Y: NO
[08:18:48][C][ssd1306_i2c:030]: Offset X: 0
[08:18:48][C][ssd1306_i2c:031]: Offset Y: 226
[08:18:48][C][ssd1306_i2c:032]: Inverted Color: NO
[08:18:48][C][ssd1306_i2c:033]: Update Interval: 1.0s
Additional information
No response
I encountered similar problems, and decided to compare esphome/esphome#2967 to working examples (1 2), and to the chipset datasheet.
Findings:
- Y offset readback of 226 is expected due to an underflow (it is treated as uint8_t, 256-30=226). However, 226 works because Display Offset register of SH1107 only cares about lower 7 bits, so sending 226 or 98 is equivalent. Adafruit code has offset 0x60=96, because esphome driver starts writing at column two - unsure why.
- Incorrect SSD1306 write mode (not SH1106/SH1107 one) was used
- Incorrect SH1107 starting line and charge pump commands were used, but POR defaults worked well already
- OLED data is preserved over resets/power cycles, so old text will re-appear and give illusion of things working properly. Maybe that is what happened with @arunderwood in the original PR?
Notes regarding Adafruit module specifically:
- Only short I2C cable worked, not 50cm one
- Adafruit code suggest that external_vcc should be set to true. This makes sense since board schematic has 3.3V->12V boost circuit.
I have rolled up all the fixes into https://github.com/nikitakuklev/esphome/tree/sh1107_fix, and it works with the following config:
external_components:
- source: github://nikitakuklev/esphome@sh1107_fix
components: [ ssd1306_base, ssd1306_i2c ]
sensor:
- platform: uptime
name: Uptime Sensor
id: uptime_sensor
update_interval: 0.1s
display:
- platform: ssd1306_i2c
model: 'SH1107_128x64'
rotation: 90
flip_x: false
flip_y: false
offset_y: 96
offset_x: 0
external_vcc: true
update_interval: 1.0s
lambda: |-
it.line(0, 0, 128, 64);
it.rectangle(5, 5, 10, 10);
it.circle(118, 54, 5);
it.rectangle(0, 0, 128, 64);
it.filled_circle(((int)id(uptime_sensor).state)*10 % 128, it.get_height() / 2, 10);
Will submit a PR, but first some independent testing would be appreciated (above config will pull the corrected files). You should see a circle moving across the screen.
I can confirm, it fixed the problem. Thanks a loot!
I can also confirm, it works.
Thanks
Cool! Is this fix only for I2C? What about SPI OLED's? For me it's not working... only a small part of the screen.
[17:37:11][C][logger:233]: Logger:
[17:37:11][C][logger:234]: Level: DEBUG
[17:37:11][C][logger:235]: Log Baud Rate: 115200
[17:37:11][C][logger:236]: Hardware UART: UART0
[17:37:11][C][spi:097]: SPI bus:
[17:37:11][C][spi:098]: CLK Pin: GPIO18
[17:37:11][C][spi:100]: MOSI Pin: GPIO23
[17:37:11][C][spi:102]: Using HW SPI: YES
[17:37:12][C][uptime.sensor:031]: Uptime Sensor 'Uptime Sensor'
[17:37:12][C][uptime.sensor:031]: State Class: 'total_increasing'
[17:37:12][C][uptime.sensor:031]: Unit of Measurement: 's'
[17:37:12][C][uptime.sensor:031]: Accuracy Decimals: 0
[17:37:12][C][uptime.sensor:031]: Icon: 'mdi:timer-outline'
[17:37:12][C][ssd1306_spi:019]: SPI SSD1306
[17:37:12][C][ssd1306_spi:019]: Rotations: 90 °
[17:37:12][C][ssd1306_spi:019]: Dimensions: 128px x 64px
[17:37:12][C][ssd1306_spi:020]: Model: SH1107 128x64
[17:37:12][C][ssd1306_spi:021]: CS Pin: GPIO14
[17:37:12][C][ssd1306_spi:022]: DC Pin: GPIO27
[17:37:12][C][ssd1306_spi:023]: Reset Pin: GPIO33
[17:37:12][C][ssd1306_spi:024]: External VCC: YES
[17:37:12][C][ssd1306_spi:025]: Flip X: NO
[17:37:12][C][ssd1306_spi:026]: Flip Y: NO
[17:37:12][C][ssd1306_spi:027]: Offset X: 0
[17:37:12][C][ssd1306_spi:028]: Offset Y: 96
[17:37:12][C][ssd1306_spi:029]: Inverted Color: NO
[17:37:12][C][ssd1306_spi:030]: Update Interval: 1.0s
[17:37:12][C][web_server:162]: Web Server:
[17:37:12][C][web_server:163]: Address: m5stack_hass.local:80
[17:37:12][D][sensor:113]: 'Uptime Sensor': Sending state 5.93100 s with 0 decimals of accuracy
Config:
display:
- platform: ssd1306_spi
model: 'SH1107_128x64'
rotation: 90
flip_x: false
flip_y: false
offset_y: 96
offset_x: 0
reset_pin: 33
external_vcc: true
cs_pin: 14
dc_pin: 27
lambda: |-
it.line(0, 0, 128, 64);
it.rectangle(5, 5, 10, 10);
it.circle(118, 54, 5);
it.rectangle(0, 0, 128, 64);
it.filled_circle(((int)id(uptime_sensor).state)*10 % 128, it.get_height() / 2, 10);
What hardware are you using? Link to product?
What hardware are you using? Link to product?
Old version of M5 Stick:
https://docs.m5stack.com/en/core/m5stick
It uses: OLED Screen 1.3 inch, 64 x 128, SH1107
Looks like the SPI implementation needs an small update. If you are lucky, perhaps @nikitakuklev can fix in the branch.
I don't have a SPI module to test, so just copied I2C changes into SPI component. @rpaludo, can you see if these work? You will need to modify config to include:
external_components:
- source: github://nikitakuklev/esphome@sh1107_fix
components: [ ssd1306_base, ssd1306_i2c, ssd1306_spi ]
All right! It worked like a charm. Thanks @nikitakuklev and @jenscski.
I can confirm this fixes the static screen for my esp8266 huzzah with Adafruit FeatherWing OLED screen as well. I do get a red x in the yaml for the offset_y with the message "value must be at most 32", but it allows installing and works properly only with 96. Not sure if that is expected or not.
Which YAML editor are you using? This probably happens because there is a change in the external_components library.
It's the default editor that pops up when you click the "EDIT" button in ESPHome inside of Home Assistant. I'm using ESPHome version 2022.1.2, with Home Assistant version 2021.12.10
Interesting, I went back to get another screenshot and now the red x is gone. I had saved/closed the editor multiple times while changing the lambda around and the red x stayed there. I think doing a new browser window may have fixed it?
Probably safe to disregard that issue, everything is working great for me so far.
The red x issue was probably due it not fetching files before first compilation - part of patch changes offset limits (it was -32 to 32 before).
I came upon another issue with Adafruit module specifically - when using I2C connector, it sometime takes several tries to get the screen working from a cold power up. I suspect it has something to do with SH1107 power-up sequence requirements, the APX803 reset circuit on OLED board (150ms delay from power on before SH1107 is released from reset), and lack of direct reset pin control (unlike in case of soldered shield). The issue seems random, and was not fixable with artificial command delays/slow I2C frequency. A viable but ugly fix was adding:
on_boot:
priority: -100
then:
- lambda: |-
App.feed_wdt();
delay(500);
// disp is oled id
id(disp).setup();
id(disp).setup();
id(disp).setup();
id(disp).setup();
id(disp).setup();
However, since things work for everyone else it is prudent to proceed - will make a pull request on the weekend.
Has this been fixed? Planning to buy a SH1107 display.
@nikitakuklev Where you able to submit your fixes to the main repo?
I am trying to get the M5Stack OLED SH1107 working. It's I2C.
https://docs.m5stack.com/en/unit/oled
@nstrelow I am trying to get the M5 Stack SH1107 OLED display but all I get is the random dots all over. I tried a few of the code sample above but it doesn't even compile. Should it work or is it not fully supported yet?
Based on this https://esphome.io/components/display/ssd1306.html?highlight=sh1107 I thought it would work.
@alexruffell I couldn't get it working, the M5 display works a bit different apparently. The code above with the -96 is also not working.
That is weird - is anything different between above M5 stick that was reported as working and yours? Different revision?
I will rebase my patches as potential fix, but won't have time for proper pull request until a few week from now.
@nikitakuklev At the web page provided by @nstrelow ( https://docs.m5stack.com/en/unit/oled ) there are schematics, a library and code samples but none for ESP. Maybe those may help.
@nikitakuklev I haven't tried your fix for the Adafruit module, maybe that works. It'll try at some point.
One thing that definitly didn't work, was the offset_y: 96
, were it complained it could only offset up to 32.
Ok, I can set the offset_y: 96
, just the editor complains.
But I get the following error on compile on the newest esphome. Probably a rebase is needed. @nikitakuklev did you find the time? 😁
src/esphome/components/ssd1306_base/ssd1306_base.cpp: In member function 'virtual void esphome::ssd1306_base::SSD1306::setup()':
src/esphome/components/ssd1306_base/ssd1306_base.cpp:120:12: warning: enumeration value 'SH1107_MODEL_128_64' not handled in switch [-Wswitch]
switch (this->model_) {
^
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/components/web_server_base/web_server_base.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/components/wifi/wifi_component.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/components/wifi/wifi_component_esp32_arduino.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/components/wifi/wifi_component_esp8266.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/components/wifi/wifi_component_esp_idf.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/application.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/color.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/component.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/component_iterator.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/controller.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/entity_base.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/helpers.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/log.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/scheduler.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/esphome/core/util.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/src/main.cpp.o
Generating partitions /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/partitions.bin
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib528/AsyncTCP-esphome/AsyncTCP.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib64d/WiFi/ETH.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib64d/WiFi/WiFi.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib64d/WiFi/WiFiAP.cpp.o
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib64d/WiFi/WiFiClient.cpp.o
Archiving /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib528/libAsyncTCP-esphome.a
Compiling /data/m5stack-atom-speaker-kit/.pioenvs/m5stack-atom-speaker-kit/lib64d/WiFi/WiFiGeneric.cpp.o
src/main.cpp: In function 'void setup()':
src/main.cpp:895:38: error: invalid new-expression of abstract class type 'esphome::ssd1306_i2c::I2CSSD1306'
disp = new ssd1306_i2c::I2CSSD1306();
^
In file included from src/esphome.h:62:0,
from src/main.cpp:3:
src/esphome/components/ssd1306_i2c/ssd1306_i2c.h:10:7: note: because the following virtual functions are pure within 'esphome::ssd1306_i2c::I2CSSD1306':
class I2CSSD1306 : public ssd1306_base::SSD1306, public i2c::I2CDevice {
^
In file included from src/esphome.h:17:0,
from src/main.cpp:3:
src/esphome/components/display/display_buffer.h:373:23: note: virtual esphome::display::DisplayType esphome::display::DisplayBuffer::get_display_type()
virtual DisplayType get_display_type() = 0;
^
I've done a rebase on the current esphome dev branch, with a couple of additional quick fixes. It's available here: https://github.com/bekriebel/esphome/tree/sh1107_fix. This is working for me, but I'm seeing the initial startup issue sometimes occurring. The on_boot
fix doesn't seem to fix it for me, though.
@bekriebel Awesome I am FINALLY seeing something on my screen. Thanks so much 🥳
Thank you to nikitakuklev and bekriebel; your fixes did the trick for me
I finally got my M5 Stack SH1107 display to work! Thank you!
This is the code I had to use, note the offset_x
is set to 32 otherwise the rectangle was half off the screen. It took a bit of open/close/refresh of esphome for it to stop complaining about the offset_y: 96
setting.
i2c:
- id: bus_a
sda: 33
scl: 32
scan: true
external_components:
- source: github://bekriebel/esphome@sh1107_fix
components: [ ssd1306_base, ssd1306_i2c ]
display:
- platform: ssd1306_i2c
model: 'SH1107_128x64'
rotation: 90
flip_x: false
flip_y: false
offset_y: 96
offset_x: 32
external_vcc: true
update_interval: 1.0s
lambda: |-
it.line(0, 0, 128, 64);
it.rectangle(5, 5, 10, 10);
it.circle(118, 54, 5);
it.rectangle(0, 0, 128, 64);
it.filled_circle(((int)id(uptime_sensor).state)*10 % 128, it.get_height() / 2, 10);
sensor:
- platform: uptime
name: Uptime Sensor
id: uptime_sensor
update_interval: 0.1s
EDIT: Is there any chance this fix will make it to the standard distribution of esphome?
Also got a 128x128 SH1107 display working with this fix. Thank you @nikitakuklev and @bekriebel! :)
Only had to include a few small tweaks to the code to add SH1107_MODEL_128_128
definition, specifying the correct height and width. Made an extra commit from @bekriebel branch, https://github.com/jacobparra/esphome/tree/sh1107_fix
Here is the config used. offset_y
set to 0
, but offset_x
value seems to not affect (tried with 32 and 96).
i2c:
scan: true
sda: GPIO26
scl: GPIO27
external_components:
- source: github://jacobparra/esphome@sh1107_fix
components: [ ssd1306_base, ssd1306_i2c ]
display:
- platform: ssd1306_i2c
model: 'SH1107_128x128'
rotation: 0
flip_x: false
flip_y: false
offset_y: 0
offset_x: 0
external_vcc: true
update_interval: 1.0s
lambda: |-
it.line(0, 0, 128, 128);
it.rectangle(5, 5, 10, 10);
it.circle(118, 54, 5);
it.rectangle(0, 0, 128, 128);
it.filled_circle(((int)id(uptime_sensor).state)*10 % 128, it.get_height() / 2, 10);
sensor:
- platform: uptime
name: Uptime Sensor
id: uptime_sensor
update_interval: 0.1s
BTW, display tested is from TZT 1.5 inch OLED 4pin. In the back it reads 1.5" GME128128-01-IIC ver:2.0
, Dots:128*128
, IC:SH1107
Following @alexruffell comment, maybe the whole fix could make it to esphome repo.
Has anyone tried to use this with PicoW? I bought a Waveshare 1.3 OLED, using above configuration with i2c without any luck. Any ideas, suggestions?
@bekriebel and @nikitakuklev confirming this (rebased) fix works with ESPHome 2023.5.5 on a FeatherS2 with FeatherWing OLED - 128x64.
Please make a PR to the main ESPHome repo for this.
@bekriebel @jacobparra @nikitakuklev this patch broke today with the release of ESPHome 2023.6.0. Screen is all white.
Definitely Broken! See the attached image...
@bekriebel @jacobparra @nikitakuklev this patch broke today with the release of ESPHome 2023.6.0. Screen is all white.