Integrar una pantalla SSD1306 con ESPHome

Integrar una pantalla SSD1306 con ESPHome

En esta entrada vamos a aprender a integrar una pantalla SSD1306 con ESPHome para mostrar datos de Home Assistant en un dispositivo personalizado.

🥑 Si estás empezando con ESPHome, te recomiendo que veas el taller de la academia para sacarle el máximo partido!
Esphome para novatos

Requisitos previos

Para integrar una pantalla con ESPHome necesitas lo siguiente:

  • Una placa ESP32 o ESP8266. En mi caso voy a utilizar una placa ESP8266 por su pequeño tamaño que me va a permitir crear un dispositivo más compacto.
  • Una pantalla SSD1306. En esta ocasión vamos a utilizar esta pequeña pantalla que destaca por su bajo precio, su pequeño tamaño y la facilidad para instalarla.
  • Un cable USB-C para alimentar la placa de DATOS (con un cable de carga no vas a poder instalar el software).
  • Haber instalado ESPHome en Home Assistant.

-53%
Placa de desarrollo WIFI con pines, Micro USB/tipo C, WeMos D1 Mini PRO V3.0.0 V4.0.0 ESP32 S2, NodeMCU Lua IOT, 3,3 V
Aliexpress
2,94€ 6,39€
Placa de desarrollo WIFI con pines, Micro USB/tipo C, WeMos D1 Mini PRO V3.0.0 V4.0.0 ESP32 S2, NodeMCU Lua IOT, 3,3 V
-36%
Módulo de pantalla oled IIC Serial para Arduino, placa de pantalla LCD blanca de 0,96 pulgadas, 128X64, I2C, SSD1306, 12864
Aliexpress
2,78€ 4,41€
Módulo de pantalla oled IIC Serial para Arduino, placa de pantalla LCD blanca de 0,96 pulgadas, 128X64, I2C, SSD1306, 12864
-36%
DIYUSER-Módulo de pantalla OLED SSD1306 de 0,96 pulgadas, placa de pantalla LCD para Arduino, Blanco/azul/amarillo, 128x64, IIC, I2C, Serial, 12864
Aliexpress
2,66€ 4,22€
DIYUSER-Módulo de pantalla OLED SSD1306 de 0,96 pulgadas, placa de pantalla LCD para Arduino, Blanco/azul/amarillo, 128x64, IIC, I2C, Serial, 12864
-2%
USLION-Cable USB tipo C de carga rápida 7A, Cable de datos para MacBook, Xiaomi, Samsung, Cable USB a tipo C para Huawei
Aliexpress
1,77€ 1,81€
USLION-Cable USB tipo C de carga rápida 7A, Cable de datos para MacBook, Xiaomi, Samsung, Cable USB a tipo C para Huawei
*Algún precio puede haber cambiado desde la última revisión

Conexión de la pantalla

Para integrar una pantalla SSD1306 con ESPHome lo primero que vamos a hacer es conectar la pantalla con nuestra placa. Como siempre lo primero que te recomiendo es que consultes el ‘pinout’ (o distribución de pines) de la placa. En este caso, usaremos la ESP8266 (WeMos D1 Mini) cuyo ‘pinout’ es el siguiente.

esp8266 wemos d1 mini

Por otro lado, nuestra pantalla SSD1306 tiene el siguiente aspecto, que nos lleva al siguiente esquema de conexión.

  • GND irá conectado al pin GND (‘ground’ o tierra) de la placa.
  • VDD irá conectado al pin de alimentación 3v3 de la placa
  • SCK irá conectado al pin D1 de la placa, que se corresponde con el GPIO5.
  • SDA irá conectado al pin D2 de la placa, que se corresponde con el GPIO4.
💪 Por cierto, ya habrás notado que vas a necesitar soldar (no dejes que te intimide! en esta entrada te explico cómo aprender a soldar). Básicamente necesitas un soldador y un poco de estaño.
pantalla ssd1306

Configuración de ESPHome

Ahora tenemos que ‘flashear’ la placa con ESPHome y la configuración correspondiente, que vamos a extraer directamente de la documentación ESPHome sobre el componente SSD1306. Para ello sigue estos pasos:

  1. Conecta la placa a tu ordenador a través del puerto USB-C.
  2. En Home Assistant, accede al complemento de ESPHome desde el menú lateral y pulsa en “New device”. Pulsa en “Continue” y dale un nombre (por ejemplo, “Pantalla”).
  3. Pulsa en “Next” y a continuación selecciona la opción “ESP8266” como tipo de dispositivo. Verás que en el fondo se ha creado un nuevo dispositivo.
  4. Pulsa en “Skip” y haz clic en el enlace “Edit” del bloque correspondiente al dispositivo que acabas de crear.
  5. Añade las siguientes líneas al final del código.
captive_portal:
i2c:
  sda: GPIO4
  scl: GPIO5

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(font1), "Aguacatec :)");

font:
  - file: "gfonts://Roboto"
    id: font1
    size: 14
  1. Cuando hayas terminado de editar el código pulsa en “Save” e “Install”. Selecciona la opción “Manual download” y espera a que el código se compile.
  2. Cuando termine, selecciona la opción “Modern format” para descargar el fichero ‘.bin’ correspondiente.
  3. Ahora ve a la página de ESPHome y pulsa en “Connect”. En la ventana emergente selecciona tu placa y pulsa en “Conectar”.
  4. Ahora pulsa en “Install” y selecciona el fichero ‘.bin’ obtenido en el paso 7. De nuevo, pulsa en “Install”. Cuando finalice la instalación deberías ver lo siguiente en tu pantalla.
pantalla ssd1306
  1. Vuelve a Home Assistant y ve a Ajustes > Dispositivos y servicios. Lo normal es que tu dispositivo haya sido descubierto y aparezca en la parte superior, esperando únicamente a que pulses el botón de “Configurar”. De lo contrario pulsa en el botón de “Añadir integración”, busca “ESPHome” e introduce la IP de tu placa en el campo ‘Host’.

Configuración de la pantalla

A continuación vamos a ver algunas ideas de qué puedes conseguir tras integrar una pantalla SSD1306 con ESPHome.

Cambiar el tipo de fuente

Si has analizado el código que hemos creado para la placa ESP, es posible que hayas observado un apartado en el que hemos indicado un tipo de fuente (ya sabes, como las que has utilizado toda la vida tipo «Arial» o «Comic Sans»). Esto se debe a que podemos personalizar el tipo de letra que aparece en la pantalla.

En la documentación de ESPHome puedes encontrar todas las opciones disponibles que puedes parametrizar (como el tamaño de la letra, el grosor, el estilo…), pero me parece importante destacar de dónde tienes que sacar estas fuentes. Por un lado tienes la opción de descargar el fichero ‘.ttf’ correspondiente a un tipo de fuente (o incluso buscarlo en tu ordenador en la carpeta ‘Windows/Fonts’) y subirlo a la ruta ‘config/esphome/’. Luego sólo tendrías que llamarlo con un código como este:

font:
  - file: "arial.ttf"
    id: arial
    size: 20

No obstante, yo prefiero usar las de Google Fonts, ya que te ahorras todo el proceso anterior. Sólo tienes que entrar en su página web, encontrar la que te guste, e indicar su nombre en el código de la siguiente forma:

font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 14

Una vez que has agregado las fuentes que te gustan, no olvides indicar el ‘id’ de la misma en el texto correspondiente. Por ejemplo:

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(roboto), "Este texto lleva el tipo de fuente Roboto");

font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 14

Mostrar sensores de Home Assistant

Ahora que ya sabes cómo incluir texto en tu pantalla, probablemente quieras que este texto se corresponda con algún dato disponible en Home Assistant. Por ejemplo, supongamos que quieres mostrar la temperatura de una habitación proporcionada por el sensor ‘sensor.temperatura’.

pantalla ssd1306

Para ello primero tenemos que importar este dato en el código de ESPHome para tenerlo disponible. Observa como lo he hecho:

captive_portal:
i2c:
  sda: GPIO4
  scl: GPIO5

font:
  - file: "gfonts://Roboto"
    id: font14
    size: 14
  - file: "gfonts://Roboto"
    id: font25
    size: 25

sensor:
  - platform: homeassistant
    id: temperatura
    entity_id: sensor.temperatura
    internal: true

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(font14), "Temperatura");
      it.printf(0, 25, id(font25), "%.1f C", id(temperatura).state);

Aprovecho para invitarte a que revises de nuevo el código y te fijes en lo siguiente:

  • He añadido dos tipo de fuente, que aunque utilizan la misma familia, tienen distinto tamaño. De esta forma he conseguido que el valor se vea más grande que el título. Puedes añadir tantos tipos como quieras.
  • He incluido los datos del sensor de temperatura, dándole un ‘id’ que más tarde utilizaré para mostrar su valor. También le añado el atributo ‘internal:true’ para que no me lo duplique en Home Assistant.
  • He detallado dos líneas de texto en la pantalla, indicando en primer lugar las coordenadas en las que empieza cada una (los números del inicio representan la X y la Y). También he dado un tipo de fuente a cada una y el valor correspondiente.

Rotar la información en pantalla

Integrar una pantalla SSD1306 con ESPHome para mostrar un sólo dato de forma estática es un desperdicio de recursos. Sobretodo porque es muy fácil incluir otros datos disponibles de la misma forma, y pedirle que los vaya cambiando en la pantalla. Por ejemplo, supongamos que quiero añadir el dato de la humedad a la pantalla de la siguiente forma:

captive_portal:
i2c:
  sda: GPIO4
  scl: GPIO5

font:
  - file: "gfonts://Roboto"
    id: font14
    size: 14
  - file: "gfonts://Roboto"
    id: font25
    size: 25

sensor:
  - platform: homeassistant
    id: temperatura
    entity_id: sensor.temperatura
    internal: true
  - platform: homeassistant
    id: humedad
    entity_id: sensor.humedad
    internal: true

display:
  - platform: ssd1306_i2c
    id: pantalla
    model: "SSD1306 128x64"
    address: 0x3C
    pages:
      - id: page1
        lambda: |-
          it.print(0, 0, id(font14), "Temperatura");
          it.printf(0, 25, id(font25), "%.1f C", id(temperatura).state);
      - id: page2
        lambda: |-
          it.print(0, 0, id(font14), "Humedad");
          it.printf(0, 25, id(font25), "%.1f %%", id(humedad).state);          

interval:
  - interval: 5s
    then:
      - display.page.show_next: pantalla
      - component.update: pantalla 

Observa lo siguiente:

  • He añadido la humedad como segundo sensor procedente de Home Assistant.
  • He añadido el atributo ‘id’ al componente de la pantalla, para poder identificarlo.
  • También he añadido el atributo ‘pages’ para poder crear distintas «páginas» a mostrar en la pantalla. Cada una de ellas contiene uno de los datos a mostrar.
  • Por último he añadido el bloque ‘interval’ para que cada 5 segundos cambie la página que se muestra en el componente con ‘id’ de «pantalla».

Incluye iconos e imágenes

Seguro que una vez que consigas mostrar información útil en tu pantalla vas a querer dar el siguiente paso y hacerlo de una forma más estética. Para ello puedes ayudarte, por ejemplo, de los iconos «oficiales» que usamos en Home Assistant añadiendo las siguientes líneas:

image:
  - file: mdi:thermometer
    id: temperature
    resize: 40x40
  - file: mdi:water-percent
    id: humidity
    resize: 40x40

También puedes añadir imágenes personalizadas subiéndoladas dentro de la ruta ‘config/esphome’, e incluirlas de la siguiente forma.

image:
  - file: "logo.png"
    id: aguacatec
    resize: 40x40
    type: TRANSPARENT_BINARY

En ambos casos se incorporan al código de la misma forma, por ejemplo observa como he enriquecido el código.

captive_portal:
i2c:
  sda: GPIO4
  scl: GPIO5

font:
  - file: "gfonts://Roboto"
    id: font14
    size: 14
  - file: "gfonts://Roboto"
    id: font25
    size: 25

image:
  - file: mdi:thermometer
    id: temperature
    resize: 40x40
  - file: mdi:water-percent
    id: humidity
    resize: 40x40
  - file: "logo.png"
    id: aguacatec
    resize: 40x40
    type: TRANSPARENT_BINARY

time:
  - platform: homeassistant
    id: hora

sensor:
  - platform: homeassistant
    id: temperatura
    entity_id: sensor.temperatura
    internal: true
  - platform: homeassistant
    id: humedad
    entity_id: sensor.humedad
    internal: true

display:
  - platform: ssd1306_i2c
    id: pantalla
    model: "SSD1306 128x64"
    address: 0x3C
    pages:
      - id: page1
        lambda: |-
          it.print(0, 0, id(font14), "Aguacatec");
          it.strftime(0, 25, id(font25), "%H:%M", id(hora).now());
          it.image(it.get_width(), 15, id(aguacatec), ImageAlign::TOP_RIGHT);
      - id: page2
        lambda: |-
          it.print(0, 0, id(font14), "Temperatura");
          it.printf(0, 25, id(font25), "%.1f C", id(temperatura).state);
          it.image(it.get_width(), 15, id(temperature), ImageAlign::TOP_RIGHT);
      - id: page3
        lambda: |-
          it.print(0, 0, id(font14), "Humedad");
          it.printf(0, 25, id(font25), "%.1f %%", id(humedad).state);          
          it.image(it.get_width(), 15, id(humidity), ImageAlign::TOP_RIGHT);

interval:
  - interval: 5s
    then:
      - display.page.show_next: pantalla
      - component.update: pantalla 

Toma nota de lo siguiente:

  • En el caso de la imagen local he añadido el atributo ‘type: TRANSPARENT_BINARY’, para que entienda que el fondo de la imagen es transparente, y que el resto de los pixels deben tomar color.
  • Mediante el componente ‘time’ he importado el dato de la hora desde Home Assistant, para poder usarlo como reloj.
  • He alineado las imágenes con la esquina superior derecha, y les he dado un margen superior de 15 pixels.
pantalla ssd1306

Carcasa para la pantalla

Ahora que sabes cómo integrar una pantalla SSD1306 con ESPHome y mostrar un montón de información en ella, sólo queda buscarle un envoltorio atractivo. En mi caso he diseñado esta carcasa que imita uno de los míticos iPod de Apple, en la que cabe tanto la pantalla como la placa ESP8266.

Si te gusta, puedes descargarlo de forma gratuita desde nuestro perfil de Patreon. También puedes recibirlo en casa listo para ser montado por un aguacoin!

ipod


¿Dudas?¿necesitas ayuda? entra aquí
Y si te ha gustado, compártelo! 🙂
Contenido exclusivo de Aguacatec
Send this to a friend