#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>
// Sensor DHT
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);
// WiFi Credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT Server
const char* mqtt_server = "broker.emqx.io";
const int mqtt_port = 1883;
const char* client_id = "esp32_client";
WiFiClient espClient;
PubSubClient client(espClient);
// Relay pins sesuai urutan
const int relayPins[15] = { 13, 12, 14, 27, 26, 25, 33, 32, 15, 2, 5, 23, 18, 19, 22 };
// Variabel Global untuk data sensor dan timing
float suhu_mqtt = 0.0, hum_mqtt = 0.0;
unsigned long lastLcdUpdate = 0;
unsigned long lastMqttPublish = 0;
// Array global untuk menyimpan status terbaru masing-masing device (relay index 0 - 14)
String deviceStates[15];
// Fungsi Setup WiFi
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected: " + WiFi.localIP().toString());
}
// Callback untuk menangani data yang diterima melalui MQTT
void callback(char* topic, byte* payload, unsigned int length) {
// Pastikan payload berakhiran null
payload[length] = '\0';
String message = String((char*)payload);
Serial.print("Topic: "); Serial.println(topic);
Serial.print("Message: "); Serial.println(message);
// Parse JSON
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.println("Failed to parse JSON");
return;
}
String topicStr = String(topic);
if (topicStr == "smartGreenHouse/Aktuator") {
if (doc["device"] && doc["status"]) {
String device = doc["device"];
String status = doc["status"];
int pinIndex = -1;
// Mapping untuk Kipas
if (device == "Kipas 1") {
pinIndex = 0;
} else if (device == "Kipas 2") {
pinIndex = 1;
}
// Mapping untuk Pompa
else if (device == "Pompa 1") {
pinIndex = 2;
} else if (device == "Pompa 2") {
pinIndex = 3;
}
// Mapping untuk Lampu 1-11
else if (device.startsWith("Lampu ")) {
int lampuNum = device.substring(6).toInt();
if (lampuNum >= 1 && lampuNum <= 11) {
pinIndex = lampuNum + 3; // Karena lampu mulai dari relayPins[4]
}
}
if (pinIndex >= 0 && pinIndex < 15) {
// Tulis status ke relay
digitalWrite(relayPins[pinIndex], status == "ON" ? HIGH : LOW);
// Simpan status terbaru ke array deviceStates
deviceStates[pinIndex] = status;
Serial.println(device + ": " + status);
}
}
}
}
// Fungsi untuk koneksi ulang ke MQTT broker jika belum terhubung
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect(client_id)) {
Serial.println("connected");
client.subscribe("smartGreenHouse/Aktuator");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
delay(2000);
}
}
}
// Setup awal
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
dht.begin();
// Inisialisasi array deviceStates dengan default OFF
for (int i = 0; i < 15; i++) {
deviceStates[i] = "OFF";
}
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
// Set tiap relay sebagai OUTPUT dan matikan awal
for (int i = 0; i < 15; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
}
}
// Loop utama
void loop() {
if (!client.connected()) reconnect();
client.loop();
unsigned long currentMillis = millis();
// Update data sensor & tampil di LCD setiap 3 detik
if (currentMillis - lastLcdUpdate > 3000) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Suhu: ");
lcd.print(suhu_mqtt, 1);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Hum : ");
lcd.print(hum_mqtt, 1);
lcd.print(" %");
lastLcdUpdate = currentMillis;
}
// Publish data sensor ke MQTT setiap 30 detik
if (currentMillis - lastMqttPublish > 30000) {
float suhu = dht.readTemperature();
float hum = dht.readHumidity();
if (!isnan(suhu) && !isnan(hum)) {
suhu_mqtt = suhu;
hum_mqtt = hum;
StaticJsonDocument<128> data;
data["suhu"] = suhu;
data["kelembaban"] = hum;
char buffer[128];
serializeJson(data, buffer);
client.publish("smartGreenHouse/sensor_Data", buffer);
Serial.println("Published sensor: " + String(buffer));
}
lastMqttPublish = currentMillis;
}
delay(100);
}