#include #include #include #include #include "DHT.h" #include "HX711.h" #include const char* ssid = "kiskz"; const char* password = "123443210"; const char* mqtt_server = "192.168.43.11"; WiFiClient espClient; PubSubClient client(espClient); LiquidCrystal_I2C lcd(0x27, 16, 2); #define DHTPIN 15 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); #define HX711_DT 18 #define HX711_SCK 19 HX711 scale; #define RELAY_KIPAS 4 #define RELAY_PTC 5 #define RELAY_ON LOW #define RELAY_OFF HIGH #define SOIL_PIN 35 const int soilWet = 1180; const int soilDry = 2495; bool autoMode = false; float minThreshold = 60.0; float maxThreshold = 90.0; const float localThreshold = 90.0; const unsigned long relayDuration = 30000; bool relayActive = false; unsigned long relayStartTime = 0; float temperature = 0; float humidity = 0; float weight = 0; int soilRaw = 0; int soilPercent = 0; void setup_wifi() { delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void callback(char* topic, byte* payload, unsigned int length) { StaticJsonDocument<256> doc; DeserializationError error = deserializeJson(doc, payload, length); if (error) return; if (doc.containsKey("auto")) { autoMode = (String(doc["auto"]) == "ON"); } if (doc.containsKey("min")) minThreshold = doc["min"]; if (doc.containsKey("max")) maxThreshold = doc["max"]; } void reconnect() { while (!client.connected()) { if (client.connect("ESP32Client")) { client.subscribe("iot/control/relay"); } else { delay(5000); } } } void setup() { Serial.begin(115200); Wire.begin(21, 22); dht.begin(); lcd.init(); lcd.backlight(); pinMode(RELAY_KIPAS, OUTPUT); pinMode(RELAY_PTC, OUTPUT); digitalWrite(RELAY_KIPAS, RELAY_OFF); digitalWrite(RELAY_PTC, RELAY_OFF); scale.begin(HX711_DT, HX711_SCK); scale.set_scale(-452.1357); scale.tare(); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); temperature = dht.readTemperature(); humidity = dht.readHumidity(); weight = scale.get_units(5); soilRaw = analogRead(SOIL_PIN); soilPercent = map(soilRaw, soilDry, soilWet, 0, 100); soilPercent = constrain(soilPercent, 0, 100); if (autoMode) { if (!relayActive && humidity > maxThreshold) { digitalWrite(RELAY_KIPAS, RELAY_ON); digitalWrite(RELAY_PTC, RELAY_ON); relayActive = true; relayStartTime = millis(); } if (relayActive && humidity <= minThreshold) { digitalWrite(RELAY_KIPAS, RELAY_OFF); digitalWrite(RELAY_PTC, RELAY_OFF); relayActive = false; } } else { if (!relayActive && humidity > localThreshold) { digitalWrite(RELAY_KIPAS, RELAY_ON); digitalWrite(RELAY_PTC, RELAY_ON); relayActive = true; relayStartTime = millis(); } if (relayActive && millis() - relayStartTime >= relayDuration) { digitalWrite(RELAY_KIPAS, RELAY_OFF); digitalWrite(RELAY_PTC, RELAY_OFF); relayActive = false; } } lcd.setCursor(0, 0); lcd.print("H:"); lcd.print(humidity, 1); lcd.print("% "); lcd.print("W:"); lcd.print((int)weight); lcd.print("g "); lcd.setCursor(0, 1); if (relayActive) { if (!autoMode) { unsigned long remaining = (relayDuration - (millis() - relayStartTime)) / 1000; lcd.print("H:"); lcd.print(remaining); lcd.print("s "); } else { lcd.print("H:Auto "); } } else { lcd.print("H:Idle "); } lcd.print("S:"); lcd.print(soilPercent); lcd.print("% "); StaticJsonDocument<256> doc; doc["humidity"] = humidity; doc["weight"] = weight; doc["soil"] = soilPercent; char buffer[256]; size_t n = serializeJson(doc, buffer); client.publish("iot/sensor", buffer, n); delay(1000); }