Fredrik Erlandsson

Logo

PhD in Computer science, data scientist at Consid AB.

Building a environment sensor with a display using D1-mini and ESPHome

2025-08-14

A fun exercise to getting to know some hardware is to start with ESP8266 and in particular Wemos D1-mini. In this post I show how to build an environment sensor (with temperature and pressure) that shows the result on a display.

Bill of hardware:

As both BMP280 and the OLED display is using I2C for communication, the wiring is quite straight forward as seen here:

Just make sure to connect SDA to GPIO4 and SDC to GPIO5 and provide GND and Vcc.

To keep programming to a minimum we are using ESPHome, a framework that instead of coding uses yaml config. Both the BMP280 sensor and the OLED display have native support in ESPHome.

SPI setup:

i2c:
  sda: D1
  scl: D2
  scan: true

For the sensor the example config looks like this:

  - platform: bmp280_i2c
    address: 0x76
    temperature:
      name: "BMP280 Temperature"
      id: bmp280_temperature
    pressure:
      name: "BMP280 Pressure"
      id: bmp280_pressure

For the display we first must define fonts:

font:
  - file:
      type: gfonts
      family: Roboto
      weight: 900
    id: roboto
    size: 20

  - file:
      type: gfonts
      family: Roboto
    id: roboto_16
    size: 16

And use it like this:

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(roboto), "Hello World!");

What we like to do is update the display whenever our sensor updates..

yaml for updating display dynamically
display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    lambda: |-
      it.print(0, 0, id(roboto_16), "Temp / Pressure");

      // Print temperature
      if (id(bmp280_temperature).has_state()) {
        it.printf(
          127,
          23,
          id(roboto),
          TextAlign::TOP_RIGHT,
          "%.1f °C",
          id(bmp280_temperature).state
        );
      }

      // Print pressure
      if (id(bmp280_pressure).has_state()) {
        it.printf(
            127,
            60,
            id(roboto),
            TextAlign::BASELINE_RIGHT,
            "%.1f hPa",
            id(bmp280_pressure).state
        );
      }

Final code: ESPHome.yaml