meta data for this page
  •  

lamaPLC project: Arduino - OLED SH1106 with AHT20/BMP280 Sensor

The initial version of the project aimed to display measurements from the AHT20/BMP280 sensor as simply as possible on an OLED display, specifically the available SH1106. The AHT20/BMP280 integrates two sensors into a single device. It operates with a 5V power supply and provides the following measurements:

  • AHT 20 Temperature: 22.12 degrees C
  • AHT 20 Humidity: 62.55% rH
  • BMP280 Pressure: 99128.00 hPa
  • BMP280 Pressure (64 bit): 99125.84 hPa
  • BMP280 Temperature: 23.17 degrees C

The five measurements are shown on the OLED display in small letters.

Wiring

Since both the display and the sensor use I²C to communicate, wiring is straightforward:

  • Arduino 5v - AHT20/BMP280 sensor VDD - SH1106 OLED VDD
  • Arduino GND - AHT20/BMP280 sensor GND - SH1106 OLED GND
  • Arduino SCL - AHT20/BMP280 sensor SCL - SH1106 OLED SCK
  • Arduino SDA - AHT20/BMP280 sensor SDA - SH1106 OLED SDA

Note: The U8g2lib library required for the OLED must be installed manually, as its source code is included in the OLED description.

The initial version of the code:

// lamaPLC project: Arduino - OLED SH1106 with AHT20/BMP280 Sensor
// 2026.02.07. free code
// link: https://lamaplc.com/doku.php?id=arduino:projects:oled_sh1106_with_aht20_bmp280
 
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_AHTX0.h>
#include <BMx280I2C.h>
#include <U8g2lib.h>
 
#define I2C_ADDRESS 0x77
 
char aht_temp[10];      //   AHT sensor temperature
char aht_hum[10];       //   AHT sensor humidity
char bmp_temp[10];      //   BMP sensor temperature
char bmp_press[10];     //   BMP sensor air pressure
char bmp_press_64[10];  //   BMP sensor air pressure 64 bit
 
char finalBuf_1[32];  // a row complete
char finalBuf_2[32];  // a row complete
char finalBuf_3[32];  // a row complete
char finalBuf_4[32];  // a row complete
char finalBuf_5[32];  // a row complete
 
bool aht_ok, bmp_ok;
 
unsigned long startMillis, currentMillis;  // current and start time
const unsigned long period = 5000;         // the value is a number of milliseconds
 
// Constructor for SH1106 128x64 I2C (Hardware I2C)
// U8G2_R0: No rotation. U8X8_PIN_NONE: No hardware reset pin.
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
 
Adafruit_AHTX0 aht;
 
BMx280I2C bmx280(I2C_ADDRESS);
 
void (*resetFunc)(void) = 0;  //declare reset function @ address 0
 
void setup() {
  Serial.begin(9600);
  Wire.begin();
  Serial.println("AHT20+BMP280 module test");
 
  if (!aht.begin()) {
    //Serial.println("Could not find a valid AHT20 sensor, check wiring!");
    //while (1);
    aht_ok = false;
  } else {
    aht_ok = true;
  }
 
  if (!bmx280.begin()) {
    //Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    //while (1);
    bmp_ok = false;
  } else {
    bmp_ok = true;
  }
  bmx280.resetToDefaults();
 
  //set an oversampling setting for pressure and temperature measurements.
  bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
  bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
 
  u8g2.begin();
}
 
void loop() {
 
  currentMillis = millis();                   // get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis >= period)  // test whether the period has elapsed
  {
    startMillis = currentMillis;  // time update
 
    // 2 second tact -----------------------------------------------------------------------------
 
    //start AHT20 measurement
    sensors_event_t humidity, temp;
    aht.getEvent(&humidity, &temp);
 
    dtostrf(temp.temperature, 9, 2, aht_temp);           // Converts to nnnn.nn format
    dtostrf(humidity.relative_humidity, 9, 2, aht_hum);  // Converts to nnnn.nn format
 
    snprintf(finalBuf_1, sizeof(finalBuf_1), "Temp : %s C", aht_temp);
    snprintf(finalBuf_2, sizeof(finalBuf_2), "Hum  : %s % rH", aht_hum);
 
    //start BMP280 measurement
    if (!bmx280.measure()) {
      bmp_ok = false;
    } else {
      bmp_ok = true;
    }
    //wait for the measurement to finish
    do {
      delay(100);
    } while (!bmx280.hasValue());
 
    dtostrf(bmx280.getTemperature(), 9, 2, bmp_temp);     // Converts to nnnn.nn format
    dtostrf(bmx280.getPressure(), 9, 2, bmp_press);       // Converts to nnnn.nn format
    dtostrf(bmx280.getPressure64(), 9, 2, bmp_press_64);  // Converts to nnnn.nn format
 
    snprintf(finalBuf_3, sizeof(finalBuf_3), "Temp : %s C", bmp_temp);
    snprintf(finalBuf_4, sizeof(finalBuf_4), "Press: %s hPa", bmp_press);
    snprintf(finalBuf_5, sizeof(finalBuf_5), "P_64 : %s hPa", bmp_press_64);
 
    u8g2.firstPage();
    do {
      // https://docs.rs/u8g2-fonts/latest/u8g2_fonts/fonts/index.html
      u8g2.setFont(u8g2_font_6x13_me);  // Set font
      u8g2.drawStr(0, 12, finalBuf_1);        // Draw text
      u8g2.drawStr(0, 24, finalBuf_2);         // Draw text
      u8g2.drawStr(0, 36, finalBuf_3);         // Draw text
      u8g2.drawStr(0, 48, finalBuf_4);         // Draw text
      u8g2.drawStr(0, 60, finalBuf_5);         // Draw text
 
    } while (u8g2.nextPage());
  }
}

Arduino example codes topics on lamaPLC