TIMOTHY MWALA
Published © GPL3+

DIY Environmental Monitor with AHT20, C3-Mini & OLED via I2C

Measure temperature, humidity, heat index, and dew point with AHT20, Carenuity C3-Mini, and display the results on a crisp OLED screen!

BeginnerFull instructions provided1 hour218
DIY Environmental Monitor with AHT20, C3-Mini & OLED via I2C

Things used in this project

Hardware components

Carenuity C3-Mini
×1
Triple Adapter
×1
0.96 OLED DISPLAY
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

AHT20_C3-Mini_0.96-oled

C/C++
Remember to install the necessary libraries
#include <Wire.h>
#include <AHT20.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>

AHT20 aht20;

float ahtTemperature = 0.0, ahtHumidity = 0.0; // Variables for temperature and humidity
float heatIndex = 0.0, dewPoint = 0.0;         // Variables for derived metrics

#define SCREEN_WIDTH 128                       // OLED display width, in pixels
#define SCREEN_HEIGHT 64                       // OLED display height, in pixels
#define OLED_RESET -1                          // Reset pin (-1 if sharing Arduino reset pin)
#define OLED_I2C_ADDRESS 0x3C                  // SSD1306 I2C address
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

unsigned long previousMillis = 0;
const long interval = 5000;                    // Update interval (ms)

// Heat Index calculation (returns °C)
float calculateHeatIndex(float tempC, float humidity) {
  // Convert temperature to Fahrenheit
  float tempF = (tempC * 9.0 / 5.0) + 32.0;
  float hiF;

  // Full heat index formula (valid for T >= 80°F and RH >= 40%)
  if (tempF >= 80.0 && humidity >= 40.0) {
    hiF = -42.379 + 2.04901523 * tempF + 10.14333127 * humidity
          - 0.22475541 * tempF * humidity - 0.00683783 * tempF * tempF
          - 0.05481717 * humidity * humidity + 0.00122874 * tempF * tempF * humidity
          + 0.00085282 * tempF * humidity * humidity - 0.00000199 * tempF * tempF * humidity * humidity;
  } else {
    hiF = tempF; // Heat index ≈ temperature if outside valid range
  }

  // Convert back to Celsius
  return (hiF - 32.0) * 5.0 / 9.0;
}

// Dew Point calculation (returns °C)
float calculateDewPoint(float tempC, float humidity) {
  const float a = 17.625;
  const float b = 243.04;
  float alpha = (a * tempC) / (b + tempC) + log(humidity / 100.0);
  return (b * alpha) / (a - alpha);
}

void setup() {
  Serial.begin(115200);                        // Initialize serial communication
  Wire.begin();                                // Initialize I2C bus

  // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Halt if display initialization fails
  }
  display.display(); // Show splash screen
  delay(2000);       // Pause for 2 seconds
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);

  // Initialize AHT20 sensor
  if (!aht20.begin()) {
    Serial.println(F("AHT20 not detected. Check wiring. Freezing."));
    for (;;); // Halt if sensor initialization fails
  }
  Serial.println(F("AHT20 acknowledged."));
}

void loop() {
  unsigned long currentMillis = millis();

  // Read sensor data every 'interval' milliseconds
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Read temperature and humidity
    ahtTemperature = aht20.getTemperature();
    ahtHumidity = aht20.getHumidity();

    // Check for valid readings (e.g., non-NaN values)
    if (isnan(ahtTemperature) || isnan(ahtHumidity)) {
      Serial.println(F("Failed to read from AHT20 sensor!"));
    } else {
      // Calculate derived metrics
      heatIndex = calculateHeatIndex(ahtTemperature, ahtHumidity);
      dewPoint = calculateDewPoint(ahtTemperature, ahtHumidity);

      // Print to Serial for debugging
      Serial.print(F("Temperature: "));
      Serial.print(ahtTemperature, 2);
      Serial.print(F(" C\tHumidity: "));
      Serial.print(ahtHumidity, 2);
      Serial.print(F("% RH\tHeat Index: "));
      Serial.print(heatIndex, 2);
      Serial.print(F(" C\tDew Point: "));
      Serial.print(dewPoint, 2);
      Serial.println(F(" C"));

      // Update OLED display
      display.clearDisplay();
      display.setFont(&FreeSans9pt7b); // Smaller font to fit all data
      display.setCursor(0, 12);
      display.print(F("Temp: "));
      display.print(ahtTemperature, 1);
      display.print(F(" C"));
      display.setCursor(0, 27);
      display.print(F("Hum: "));
      display.print(ahtHumidity, 1);
      display.print(F(" %"));
      display.setCursor(0, 42);
      display.print(F("HI: "));
      display.print(heatIndex, 1);
      display.print(F(" C"));
      display.setCursor(0, 57);
      display.print(F("Dew: "));
      display.print(dewPoint, 1);
      display.print(F(" C"));
      display.display();
    }
  }
}

Credits

TIMOTHY MWALA
32 projects • 18 followers
I am an Embedded engineer who like prototyping

Comments