#include <WiFi.h>
#include <MQTT.h>
#include <NewPing.h>
#include <ESP32Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <HX711.h>
// Deklarasi pin
#define TRIGGER_PIN 12
#define ECHO_PIN 14
#define MAX_DISTANCE 400
#define DOUT_PIN 18 // Pin data untuk HX711
#define SCK_PIN 19 // Pin clock untuk HX711
#define WEIGHT_THRESHOLD 0.05 // Berat minimum dalam kilogram sebelum dianggap kosong (50 gram)
const char* ssid = "Wokwi-GUEST"; // Ganti dengan SSID WiFi kamu
const char* password = ""; // Ganti dengan password WiFi kamu
// Konfigurasi MQTT
const char* mqttServer = "mountainrat662.cloud.shiftr.io";
const char* mqttUser = "mountainrat662";
const char* mqttPassword = "b0X48fxDejD3HhdU";
const int mqttPort = 1883;
WiFiClient net;
MQTTClient client;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
Servo myservo;
HX711 scale;
int servoPin = 13;
int distanceThreshold = 10;
bool isEating = false;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Variabel untuk status sebelumnya
String lastStatus = "";
void connectWiFi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected.");
}
void connectMQTT() {
Serial.print("Connecting to MQTT...");
client.begin(mqttServer, mqttPort, net);
// Set "will" message
client.setWill("petfeeder/status", "Pet Feeder Offline", true, 1);
while (!client.connect("ESP32_Client", mqttUser, mqttPassword)) {
Serial.print(".");
delay(1000);
}
Serial.println("\nConnected to MQTT.");
client.publish("petfeeder/status", "Pet Feeder Online", true, 1);
}
void sendMQTTMessage(const String &message) {
// Cek jika status baru berbeda dengan status sebelumnya untuk menghindari spam
if (message != lastStatus) {
client.publish("petfeeder/status", message.c_str(), true, 1);
lastStatus = message; // Perbarui status terakhir
}
}
void setup() {
Serial.begin(9600);
myservo.attach(servoPin);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SMART PET FEEDER");
scale.begin(DOUT_PIN, SCK_PIN);
scale.set_scale(2280.f); // Kalibrasi sesuai load cell Anda
scale.tare(); // Setel titik nol
connectWiFi();
connectMQTT();
delay(1000); // Tunggu stabilisasi sensor
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
delay(50);
int distance = sonar.ping_cm();
float weight = scale.get_units(); // Hasil langsung dikonversi ke kilogram
// Menampilkan berat di Serial Monitor dalam kilogram
Serial.print("Berat: ");
Serial.print(weight);
Serial.println(" kg");
// Mengirim data berat ke MQTT
String weightStr = String(weight, 2); // Konversi ke string
client.publish("petfeeder/weight", weightStr.c_str());
// Cek apakah makanan habis berdasarkan berat
if (weight < WEIGHT_THRESHOLD) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Makanan Kosong!");
sendMQTTMessage("Makanan Kosong!");
delay(2000);
return; // Keluar dari loop jika makanan kosong
}
// Logika pemberian makan
if (distance <= distanceThreshold) {
lcd.clear();
lcd.setCursor(0, 0);
if (!isEating) {
Serial.println("MENGISI WADAH MAKAN!");
lcd.print("MENGISI WADAH MAKAN!");
sendMQTTMessage("Mengisi Wadah Makan!");
myservo.writeMicroseconds(0);
delay(5000);
myservo.writeMicroseconds(1500);
delay(2000);
lcd.clear();
} else {
Serial.println("UCLUK sedang makan");
lcd.print("UCLUK sedang makan");
sendMQTTMessage("UCLUK sedang makan");
delay(5000);
lcd.clear();
}
isEating = true;
} else if (distance <= 20 && distance > distanceThreshold) {
Serial.println("WAKTUNYA MAKAN!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WAKTUNYA MAKAN!");
sendMQTTMessage("Waktunya Makan!");
delay(2000);
isEating = false;
} else if (distance <= 50 && distance > 20) {
Serial.println("UCLUK MENDEKAT");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("UCLUK MENDEKAT");
sendMQTTMessage("UCLUK Mendekat");
delay(2000);
isEating = false;
} else if (distance > 50) {
Serial.println("WADAH KOSONG DAN UCLUK JAUH");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WADAH KOSONG!");
lcd.setCursor(0, 1);
lcd.print("UCLUK JAUH!");
sendMQTTMessage("Wadah Kosong dan UCLUK Jauh");
delay(2000);
isEating = false;
delay(5000);
}
}