PROJECT SMART HYDROPONIC IoT Versi 1 (Gunakan PC/Laptop)
PROJECT SMART HYDROPONIC IoT Versi 1 (Gunakan PC/Laptop)
// by M. Afdal Zikri
// FIXED & STABLE VERSION
#include <LiquidCrystal_I2C.h>
#include <MQTT.h>
#include <WiFi.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
MQTTClient client;
WiFiClient net;
#define trig 26
#define echo 27
#define BUZZER 13
bool statusWiFi = false;
bool statusMqtt = false;
int statusBuzzer = 0;
float setTDS = 0.0;
float setpHmin = 0.0;
float setpHmax = 0.0;
int nilaiTDS = 0, nilaipH = 0, jarak = 0;
unsigned long lastKirim = 0;
unsigned long lastBuzz = 0;
bool buz = false;
byte ceklist[8] = {
B00001, B00001, B00011, B10110,
B01100, B01000, B00000, B00000
};
byte silang[8] = {
B10001, B01010, B00100, B01010,
B10001, B00000, B00000, B00000
};
// ================= WIFI + MQTT (NON BLOCKING) =================
void konekOnline() {
lcd.setCursor(19,3);
lcd.write(byte(1));
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
delay(50);
}
client.begin("mqtt-dashboard.com", net);
while (!client.connected()) {
client.connect("SMART-HYDROPONIC-IoT-Zikri");
delay(50);
}
client.subscribe("smarthidroponik/zik/belitung/+");
client.publish("smarthidroponik/zik/belitung/koneksi", "online", 1, 1);
lcd.setCursor(19,3);
lcd.write(byte(0));
}
// ================= MQTT CALLBACK =================
void terimaPesan(String topic, String pesan) {
if (topic.endsWith("/irigasi")) {
int value = pesan.toInt();
digitalWrite(14, value);
lcd.setCursor(16,3);
value == 1? lcd.print("I"): lcd.print(" ");
}
if (topic.endsWith("/nutrisi")) {
int value = pesan.toInt();
digitalWrite(12, value);
lcd.setCursor(17,3);
value == 1? lcd.print("N"): lcd.print(" ");
}
if (topic.endsWith("/buzzer")) {
statusBuzzer = pesan.toInt();
lcd.setCursor(18,3);
statusBuzzer == 1? lcd.print("A"): lcd.print(" ");
}
if (topic.endsWith("/settds")) {
setTDS = pesan.toFloat();
EEPROM.put(0, setTDS);
EEPROM.commit();
}
if (topic.endsWith("/setphmin")) {
setpHmin = pesan.toFloat();
EEPROM.put(4, setpHmin);
EEPROM.commit();
}
if (topic.endsWith("/setphmax")) {
setpHmax = pesan.toFloat();
EEPROM.put(8, setpHmax);
EEPROM.commit();
}
}
// ================= SETUP =================
void setup() {
Serial.begin(115200);
pinMode(14, OUTPUT);
pinMode(12, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
digitalWrite(trig, LOW);
EEPROM.begin(32);
EEPROM.get(0, setTDS);
EEPROM.get(4, setpHmin);
EEPROM.get(8, setpHmax);
lcd.init();
lcd.backlight();
lcd.createChar(0, ceklist);
lcd.createChar(1, silang);
lcd.setCursor(0,0); lcd.print(" SMART HYDROPONIC ");
lcd.setCursor(0,1); lcd.print(" PETANIKODING ");
lcd.setCursor(0,2); lcd.print(" M. AFDAL ZIKRI ");
lcd.setCursor(0,3); lcd.print(" BPVP BELITUNG ");
delay(1500);
lcd.clear();
client.onMessage(terimaPesan);
client.setWill("smarthidroponik/zik/belitung/koneksi", "offline", 1, 1);
}
// ================= LOOP =================
void loop() {
client.loop();
if(!client.connected()) konekOnline();
utama();
kontrolBuzzer();
yield(); // cegah WDT
}
// ================= SENSOR & LCD =================
void utama() {
nilaiTDS = map(analogRead(34), 0, 4095, 0, 2000);
nilaipH = map(analogRead(35), 0, 4095, 0, 14);
digitalWrite(trig, HIGH);
delayMicroseconds(5);
digitalWrite(trig, LOW);
long durasi = pulseIn(echo, HIGH, 30000); // TIMEOUT
jarak = (durasi == 0) ? 0 : durasi / 58;
if (millis() - lastKirim >= 2000 && client.connected()) {
lastKirim = millis();
client.publish("smarthidroponik/zik/belitung/nilaitds", String(nilaiTDS));
client.publish("smarthidroponik/zik/belitung/nilaiph", String(nilaipH));
client.publish("smarthidroponik/zik/belitung/tinggiair", String(jarak));
}
lcd.setCursor(0,0);
lcd.print("PPM: "); lcd.print(nilaiTDS); lcd.print(" pH: "); lcd.print(nilaipH); lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("SET PPM: "); lcd.print(setTDS,0); lcd.print(" ");
lcd.setCursor(0,2);
lcd.print("SET pH: "); lcd.print(setpHmin,1); lcd.print("-"); lcd.print(setpHmax,1); lcd.print(" ");
lcd.setCursor(0,3);
lcd.print("Air: "); lcd.print(jarak); lcd.print(" CM ");
}
// ================= BUZZER =================
void kontrolBuzzer() {
if (statusBuzzer == 0) {
noTone(BUZZER);
return;
}
if (nilaiTDS < setTDS * 0.9 || nilaiTDS > setTDS * 1.1 ||
nilaipH < setpHmin || nilaipH > setpHmax) {
if (millis() - lastBuzz >= 500) {
lastBuzz = millis();
buz = !buz;
if (buz) tone(BUZZER, 1000);
else noTone(BUZZER);
}
} else {
noTone(BUZZER);
}
}