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_i2c 1 and display 2 |
ESPHome config | packages/displays/ssd1306.yml 3 |
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_i2c
1 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.