// ============================================================
// SISTEM MONITORING SUHU & KELEMBABAN RUANG KELAS
// Hardware : ESP32-C3 DevKitM-1 + DHT22 + LCD 16x2 I2C
// Author : Dimas Nugroho (NIM: 23171065005)
// Institusi: ITBU Jakarta
// Simulasi : https://wokwi.com
// ============================================================
#include <WiFi.h> // ✅ Ganti dari ESP8266WiFi.h
#include <WiFiClientSecure.h>
#include <Wire.h> // ✅ Wajib untuk I2C (LCD)
#include <DHTesp.h>
#include <LiquidCrystal_I2C.h>
// ========================== CONFIG WI-FI ==========================
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ======================== CONFIG TELEGRAM =========================
const String BOT_TOKEN = "7316018385:AAFAUR3-qhJ1ZQNDDgvSbRTLO9X1UWbkRMM";
const String CHAT_ID = "303031334";
// ========================= KONFIGURASI PIN =============================
#define DHT_PIN 4 // GPIO4 → Pin DATA sensor DHT22
#define LED_RED 5 // GPIO5 → LED merah (indikator tidak normal)
#define LED_GREEN 6 // GPIO6 → LED hijau (indikator normal)
#define I2C_SDA 2
#define I2C_SCL 1
// ========================= THRESHOLD SUHU ==============================
#define SUHU_MAX 30.0 // Suhu terlalu panas (°C)
#define SUHU_MIN 18.0 // Suhu terlalu dingin (°C)
#define KELEMBABAN_MAX 80.0 // Kelembaban terlalu tinggi (%)
// ====================== INISIALISASI OBJEK ============================
DHTesp dht;
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C LCD = 0x27
// ========================= VARIABEL GLOBAL ============================
unsigned long waktuCekTerakhir = 0;
unsigned long waktuKirimTerakhir = 0;
const long INTERVAL_CEK = 5000; // Baca sensor setiap 5 detik
const long INTERVAL_KIRIM = 60000; // Kirim status tiap 1 menit
bool statusTerakhirNormal = true;
// ======================================================================
void setup() {
Serial.begin(115200);
delay(500);
// ✅ Inisialisasi I2C dengan pin eksplisit untuk ESP32-C3
Wire.begin(I2C_SDA, I2C_SCL);
// Inisialisasi pin LED
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, LOW);
// Inisialisasi sensor DHT22
dht.setup(DHT_PIN, DHTesp::DHT22);
Serial.println("Sensor DHT22 siap...");
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Sistem Monitoring");
lcd.setCursor(0, 1);
lcd.print("Ruang Kelas IoT");
delay(2000);
lcd.clear();
// Koneksi Wi-Fi
lcd.setCursor(0, 0);
lcd.print("Konek WiFi...");
Serial.print("Menghubungkan ke WiFi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int percobaan = 0;
while (WiFi.status() != WL_CONNECTED && percobaan < 20) {
delay(500);
Serial.print(".");
percobaan++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi Terhubung!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi Terhubung!");
lcd.setCursor(0, 1);
lcd.print(WiFi.localIP());
delay(2000);
kirimTelegram("*Sistem Monitoring Aktif!*\nMonitoring suhu ruang kelas telah dimulai.\nThreshold: " + String(SUHU_MIN) + "C - " + String(SUHU_MAX) + "C");
} else {
Serial.println("\nGagal konek WiFi. Mode Offline.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi Gagal!");
lcd.setCursor(0, 1);
lcd.print("Mode Offline");
delay(2000);
}
lcd.clear();
}
// ======================================================================
void loop() {
unsigned long waktuSekarang = millis();
// ---- Baca sensor setiap INTERVAL_CEK ----
if (waktuSekarang - waktuCekTerakhir >= INTERVAL_CEK) {
waktuCekTerakhir = waktuSekarang;
float suhu = dht.getTemperature();
float kelembaban = dht.getHumidity();
if (isnan(suhu) || isnan(kelembaban)) {
Serial.println("ERROR: Gagal membaca sensor DHT22!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sensor Error!");
lcd.setCursor(0, 1);
lcd.print("Cek koneksi DHT");
return;
}
Serial.println("----------------------------");
Serial.print("Suhu : "); Serial.print(suhu); Serial.println(" C");
Serial.print("Kelembaban : "); Serial.print(kelembaban); Serial.println(" %RH");
lcd.setCursor(0, 0);
lcd.print("Suhu: ");
lcd.print(suhu, 1);
lcd.print((char)223);
lcd.print("C ");
lcd.setCursor(0, 1);
lcd.print("Lembab: ");
lcd.print(kelembaban, 1);
lcd.print("% ");
bool kondisiNormal = (suhu >= SUHU_MIN && suhu <= SUHU_MAX && kelembaban <= KELEMBABAN_MAX);
if (kondisiNormal) {
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_RED, LOW);
Serial.println(">>> STATUS: NORMAL");
} else {
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, HIGH);
Serial.println(">>> STATUS: TIDAK NORMAL - PERINGATAN!");
}
if (!kondisiNormal && statusTerakhirNormal) {
String pesan = "PERINGATAN RUANG KELAS!\n";
if (suhu > SUHU_MAX)
pesan += "Suhu TERLALU PANAS: " + String(suhu, 1) + "C (Max: " + String(SUHU_MAX) + "C)\n";
else if (suhu < SUHU_MIN)
pesan += "Suhu TERLALU DINGIN: " + String(suhu, 1) + "C (Min: " + String(SUHU_MIN) + "C)\n";
if (kelembaban > KELEMBABAN_MAX)
pesan += "Kelembaban TERLALU TINGGI: " + String(kelembaban, 1) + "% (Max: " + String(KELEMBABAN_MAX) + "%)\n";
pesan += "Segera periksa kondisi ruangan!";
kirimTelegram(pesan);
statusTerakhirNormal = false;
}
if (kondisiNormal && !statusTerakhirNormal) {
String pesan = "Kondisi Ruang Kelas Normal\n";
pesan += "Suhu: " + String(suhu, 1) + "C\n";
pesan += "Kelembaban: " + String(kelembaban, 1) + "%\n";
pesan += "Ruangan kembali dalam kondisi ideal.";
kirimTelegram(pesan);
statusTerakhirNormal = true;
}
}
// ---- Kirim laporan berkala setiap INTERVAL_KIRIM ----
if (waktuSekarang - waktuKirimTerakhir >= INTERVAL_KIRIM && waktuKirimTerakhir != 0) {
waktuKirimTerakhir = waktuSekarang;
float suhu = dht.getTemperature();
float kelembaban = dht.getHumidity();
if (!isnan(suhu) && !isnan(kelembaban)) {
String pesan = "Laporan Berkala Ruang Kelas\n";
pesan += "Suhu : " + String(suhu, 1) + " C\n";
pesan += "Kelembaban : " + String(kelembaban, 1) + " %RH\n";
pesan += "Status WiFi: Terhubung\n";
bool normal = (suhu >= SUHU_MIN && suhu <= SUHU_MAX);
pesan += normal ? "Kondisi: NORMAL" : "Kondisi: PERIKSA!";
kirimTelegram(pesan);
}
}
if (waktuKirimTerakhir == 0) {
waktuKirimTerakhir = millis();
}
}
// ======================================================================
// FUNGSI: Kirim pesan ke Bot Telegram
// ======================================================================
void kirimTelegram(String pesan) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi tidak terhubung. Notifikasi Telegram dibatalkan.");
return;
}
WiFiClientSecure klien;
klien.setInsecure();
Serial.println("Mengirim ke Telegram...");
if (klien.connect("api.telegram.org", 443)) {
String url = "/bot" + BOT_TOKEN + "/sendMessage";
String payload = "{\"chat_id\":\"" + CHAT_ID + "\","
"\"text\":\"" + pesan + "\","
"\"parse_mode\":\"Markdown\"}";
klien.println("POST " + url + " HTTP/1.1");
klien.println("Host: api.telegram.org");
klien.println("Content-Type: application/json");
klien.println("Content-Length: " + String(payload.length()));
klien.println("Connection: close");
klien.println();
klien.println(payload);
unsigned long batasWaktu = millis() + 5000;
while (klien.connected() && millis() < batasWaktu) {
if (klien.available()) {
String baris = klien.readStringUntil('\n');
if (baris.indexOf("\"ok\":true") > 0) {
Serial.println("Pesan Telegram berhasil dikirim!");
break;
}
}
}
klien.stop();
} else {
Serial.println("Gagal terkoneksi ke api.telegram.org");
}
}
Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1