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!
Índice
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.
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.
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.
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:
- Conecta la placa a tu ordenador a través del puerto USB-C.
- 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”).
- 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.
- Pulsa en “Skip” y haz clic en el enlace “Edit” del bloque correspondiente al dispositivo que acabas de crear.
- 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
- 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.
- Cuando termine, selecciona la opción “Modern format” para descargar el fichero ‘.bin’ correspondiente.
- Ahora ve a la página de ESPHome y pulsa en “Connect”. En la ventana emergente selecciona tu placa y pulsa en “Conectar”.
- 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.
- 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’.
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.
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!
¿Dudas?¿necesitas ayuda? entra aquí
Y si te ha gustado, compártelo! 🙂