SSD1306 / SH1106 OLED display
Overview
| Manufacturer | Solomon systech |
|---|---|
| Name | SSD1306 or SH1106 |
| Datasheet | SSD1306.pdf |
| Adafruit | Monochrome OLED breakouts, adafruit/Adafruit_SSD1306 |
| Arduino reference | Adafruit SSD1306 |
| ESPHome component | ssd1306_i2c1 and display2 |
| ESPHome config | packages/displays/ssd1306.yml3 |
| Supply voltage | , some breakout boards also support . |
These OLED displays have two different chipsets -- the more comon SSD1306 or SH1106
which seems to be more common on the larger 1.3" models.
ESPHome config
Both the SSD1306 and SH1106 displays are available with either I²C or SPI interfaces. But all
of mine have I²C interfaces so this page only talks about the ssd1306_i2c component.
Using a display with an SPI interface should be very similar, apart from using the spi component
instead of the i2c component.
For more info, see the [ssd1306 component in ESPHome](https://esphome.io/components/display/ssd1306#over-spi).
First set up an I²C bus first for the display:
i2c:
- sda: ${sda_gpio_pin}
scl: ${scl_gpio_pin}
id: i2c_ssd1306
Most ESP32 boards have 2+ I²C interfaces that can be used with any available GPIO pins. Keep in mind that I²C uses the pins for both input and output, so avoid using any strapping pins.
Configure the ssd1306_i2c1 component for your display:
display:
- platform: ssd1306_i2c
id: ssd1306
# or 'SH1106'
model: "SSD1306 128x64"
address: 0x3C
i2c_id: i2c_ssd1306
lambda: |-
it.printf(0, 30, id(font_id), TextAlign::BASELINE_LEFT, "sudo.is");
Both the chipset model and dimensions are configured as a string in the model
config item.
On/off switch
It is possible to turn off the display. While it is not exposed as a switch
component in the ssd1306 component, the C++ API4 provides
the turn_on(), turn_off() and is_on() functions.
We can use lambdas to call them, and template a switch component to control
it and represent the state.
switch:
- platform: template
name: "${hostname} Display"
id: ssd1306_switch_display
internal: false
disabled_by_default: false
lambda: |-
return id(ssd1306).is_on();
turn_on_action:
- lambda: |-
id(ssd1306).turn_on();
turn_off_action:
- lambda: |-
id(ssd1306).turn_off();
When turn_off() is called, the display gets fully powered off.
Brightness control
The C++ SSD1306 class API4 provides the functions set_contrast()
and get_contrast(). Contrast basically works the same as brightness, so we can use that
instead, with the same effect.
Template a number component to control the brightness/contrast by calling set_contrast:
number:
- platform: template
id: "ssd1306_contrast"
name: "${hostname} Display"
min_value: 0
max_value: 100
step: 0
entity_category: ""
unit_of_measurement: "%"
device_class: power_factor
mode: slider
update_interval: 5s
lambda: |-
float contrast = id(ssd1306).get_contrast();
return int(contrast*100);
set_action:
- lambda: |-
id(ssd1306).set_contrast(x/100);
The get_contrast() function was added in my pull request esphome#6435
and was merged in ESPHome 2024.4.0.
It should also be possible to use a templated output component and then configure a light
component using the monochromatic platform for a nicer presentation in Home Assistant.
Font
I've found that the font Noto Sans Mono looks good on this display.
Put the NotoSansMono-Regular.ttf
file somewhere ESPHome can find it, and then configure2 the display to use it.
font:
- file: "../fonts/NotoSansMono-Regular.ttf"
id: notomono24
size: 24
display:
- platform: ssd1306_i2c
id: ssd1306
model: "SSD1306 128x64"
address: 0x3C
i2c_id: i2c_ssd1306
lambda: |-
it.printf(127, 30, id(notomono24), TextAlign::BASELINE_LEFT, "sudo.is");
Unfortunately you need to specify a font entry for each font size you want to use.