#include <ESP8266WiFi.h>
#include <SSD1306Wire.h>
#include <DHT.h>
// Definisi pin
#define DHT_PIN D4 // GPIO2
#define SCL_PIN D6 // GPIO12 (SCL)
#define SDA_PIN D5 // GPIO14 (SDA)
// Inisialisasi OLED
SSD1306Wire display(0x3c, SDA_PIN, SCL_PIN);
// Inisialisasi DHT11
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);
// Variabel untuk timing dan efek kedip
unsigned long previousMillis = 0;
unsigned long blinkMillis = 0;
const long interval = 2000;
const long blinkInterval = 500;
bool blinkState = true;
void setup() {
Serial.begin(115200);
// Inisialisasi DHT11
dht.begin();
// Inisialisasi OLED
display.init();
display.flipScreenVertically();
// Tampilkan startup screen
display.clear();
// Baris 1: -:=4SUN86=:- (center) - font besar
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 0, "-:=4SUN86=:-");
// Baris 2 & 3: Suhu dan Kelembapan - font kecil
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 20, "Suhu : -- C");
display.drawString(0, 35, "Kelembapan: -- %");
// Baris 4: Scanning real time - font kecil
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 50, "scanning real time");
display.display();
Serial.println("System started successfully");
}
void loop() {
unsigned long currentMillis = millis();
// Update sensor setiap 2 detik
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Baca sensor DHT11
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
updateDisplay(-1, -1);
} else {
Serial.print("Suhu: ");
Serial.print(temperature);
Serial.print(" C, Kelembapan: ");
Serial.print(humidity);
Serial.println(" %");
updateDisplay(temperature, humidity);
}
}
// Efek kedip untuk "scanning real time" setiap 500ms
if (currentMillis - blinkMillis >= blinkInterval) {
blinkMillis = currentMillis;
blinkState = !blinkState;
updateBlinkEffect(blinkState);
}
}
void updateDisplay(float temp, float humidity) {
display.clear();
// Baris 1: -:=4SUN86=:- (center) - font besar
display.setFont(ArialMT_Plain_16);
display.setColor(WHITE);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 0, "-:=4SUN86=:-");
// Baris 2 & 3: Suhu dan Kelembapan - font kecil
display.setFont(ArialMT_Plain_10);
display.setColor(WHITE);
display.setTextAlignment(TEXT_ALIGN_LEFT);
// Format dengan titik dua yang sejajar
String tempStr = "Suhu : " + (temp >= 0 ? String(temp, 1) + " C" : "-- C");
String humStr = "Kelembapan: " + (humidity >= 0 ? String(humidity, 1) + " %" : "-- %");
display.drawString(0, 20, tempStr);
display.drawString(0, 35, humStr);
// Baris 4: Scanning real time - font kecil
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER);
if (blinkState) {
display.setColor(WHITE); // Normal (putih)
} else {
display.setColor(BLACK); // Mati (hitam) - efek kedip
}
display.drawString(64, 50, "scanning real time");
display.display();
}
void updateBlinkEffect(bool state) {
// Hanya update bagian yang berkedip untuk efisiensi
display.setColor(BLACK);
display.fillRect(0, 50, 128, 10); // Hapus area text
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER);
if (state) {
display.setColor(WHITE); // Menyala
} else {
display.setColor(BLACK); // Mati
}
display.drawString(64, 50, "scanning real time");
display.display();
}