#include <WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
// --- Pin Definitions ---
const int DHT_PIN = 15;
const int TRIG_PIN = 5;
const int ECHO_PIN = 18;
const int SERVO_PIN = 13;
const int BUZZER_PIN = 12;
// --- Objects ---
DHTesp dht;
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo doorServo;
// --- Wi-Fi & ThingsBoard Credentials ---
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "mqtt.thingsboard.cloud";
const char* mqtt_clid = "workshopsyahrul";
const char* mqtt_user = "TiIOT";
const char* mqtt_pass = "12345678";
const char* mqtt_topic = "v1/devices/me/telemetry";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
float readDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
return (duration * 0.034 / 2);
}
void setup_wifi() {
delay(10);
Serial.println("\n========================================");
Serial.print("Connecting to Wi-Fi: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password, 6);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n[OK] Wi-Fi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("========================================\n");
}
void reconnect() {
while (!client.connected()) {
Serial.print("[MQTT] Connecting to ThingsBoard Cloud...");
if (client.connect(mqtt_clid, mqtt_user, mqtt_pass)) {
Serial.println(" [CONNECTED OK!]");
} else {
Serial.print(" [FAILED] rc=");
Serial.print(client.state());
Serial.println(" Retrying in 5 seconds...");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Setup Servo Pintu
doorServo.attach(SERVO_PIN);
doorServo.write(0); // Pintu Tertutup (0 derajat)
// Setup LCD I2C
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Smart Class IoT");
lcd.setCursor(0, 1);
lcd.print("Initializing...");
delay(2000);
lcd.clear();
// Setup Sensor DHT22
dht.setup(DHT_PIN, DHTesp::DHT22);
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 3000) { // Pengiriman data tiap 3 detik
lastMsg = now;
TempAndHumidity data = dht.getTempAndHumidity();
float temp = data.temperature;
float hum = data.humidity;
float dist = readDistance();
String statusRuang = "NORMAL";
String statusPintu = "CLOSED";
// Logika Otomatisasi: Ada orang mendekat (< 50 cm) ATAU Suhu Panas (> 30 C)
if (dist < 50.0 || temp > 30.0) {
doorServo.write(90); // Pintu Terbuka (90 derajat)
statusPintu = "OPEN";
if (temp > 30.0) {
statusRuang = "WARNING_HOT";
tone(BUZZER_PIN, 1000, 200); // Buzzer Peringatan
} else {
statusRuang = "PERSON_NEAR";
tone(BUZZER_PIN, 2000, 100);
}
} else {
doorServo.write(0); // Pintu Tertutup
statusPintu = "CLOSED";
noTone(BUZZER_PIN);
}
// Tampilan Layar LCD Lokal
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temp, 1);
lcd.print("C H:");
lcd.print(hum, 0);
lcd.print("% ");
lcd.setCursor(0, 1);
lcd.print("D:");
lcd.print((int)dist);
lcd.print("cm P:");
lcd.print(statusPintu);
lcd.print(" ");
// Payload JSON Kaya Telemetry ThingsBoard
String payload = "{";
payload += "\"suhu\":" + String(temp, 2) + ",";
payload += "\"kelembaban\":" + String(hum, 1) + ",";
payload += "\"jarak_cm\":" + String(dist, 1) + ",";
payload += "\"status\":\"" + statusRuang + "\",";
payload += "\"pintu\":\"" + statusPintu + "\"";
payload += "}";
// Publish MQTT
client.publish(mqtt_topic, payload.c_str());
// Log Serial Monitor
Serial.println("========================================");
Serial.print("Suhu : "); Serial.print(temp, 2); Serial.println(" C");
Serial.print("Kelembaban : "); Serial.print(hum, 1); Serial.println(" %");
Serial.print("Jarak Pintu : "); Serial.print(dist, 1); Serial.println(" cm");
Serial.print("Status Pintu: "); Serial.println(statusPintu);
Serial.print("Status Ruang: "); Serial.println(statusRuang);
Serial.print("Payload JSON: "); Serial.println(payload);
Serial.println("Status Transmisi: PUBLISHED OK");
Serial.println("========================================\n");
}
}