#include <WiFi.h>
#include <ESP32Servo.h>
#include "HX711.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/************************* WiFi Access Point ***************************/
#define WLAN_SSID "Wokwi-GUEST"
#define WLAN_PASS ""
/************************* Adafruit.io Setup ***************************/
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME "Mursyid"
#define AIO_KEY "aio_BHcK58KNS0dWoNEz3S2a5g1gCdpU"
#define AIO_FEED_LEVEL "/feeds/food-level"
/************************* Pin Definitions ***************************/
#define MOTION_PIN 17
#define WEIGHT_DOUT_PIN 18
#define WEIGHT_SCK_PIN 19
#define SERVO_PIN 23
#define BUZZER_PIN 35
#define TRIG_PIN 5
#define ECHO_PIN 16
/************ Global State ************/
Servo myServo;
HX711 scale;
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish food_level = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_LEVEL);
// Function to connect and reconnect as necessary to the MQTT server
void MQTT_connect() {
int8_t ret;
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) {
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 10 seconds...");
mqtt.disconnect();
delay(10000);
retries--;
if (retries == 0) {
while (1);
}
}
Serial.println("MQTT Connected!");
}
void setup() {
Serial.begin(115200);
pinMode(MOTION_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
myServo.attach(SERVO_PIN);
scale.begin(WEIGHT_DOUT_PIN, WEIGHT_SCK_PIN);
scale.set_scale();
scale.tare();
Serial.println(F("Adafruit MQTT + Cat Feeder"));
// Connect to WiFi access point
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void dispenseFood() {
myServo.write(90); // Rotate servo to 90 degrees
delay(1000); // Wait for 1 second
myServo.write(0); // Rotate servo back to 0 degrees
delay(1000); // Wait for 1 second
}
void soundBuzzer() {
digitalWrite(BUZZER_PIN, HIGH);
delay(500); // Sound buzzer for 0.5 seconds
digitalWrite(BUZZER_PIN, LOW);
}
float getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
float distance = duration * 0.034 / 2; // Calculate the distance in cm
return distance;
}
unsigned long lastMsg = 0;
void loop() {
MQTT_connect();
mqtt.processPackets(10000);
if (!mqtt.ping()) {
mqtt.disconnect();
}
// Check if motion is detected
if (digitalRead(MOTION_PIN) == HIGH) {
Serial.println("Motion detected!");
soundBuzzer();
}
// Check if weight sensor detects the cat
if (scale.get_units() > 1) { // Adjust this threshold based on your cat's weight
Serial.println("Cat detected. Dispensing food...");
dispenseFood();
delay(5000); // Wait for 5 seconds to prevent continuous dispensing
} else {
Serial.println("No cat detected.");
}
// Publish food level
unsigned long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;
float distance = getDistance();
Serial.println("Food Level: " + String(distance, 2) + " cm");
char strDistance[10];
dtostrf(distance, 6, 2, strDistance);
food_level.publish(strDistance);
}
delay(1000); // Check sensors every second
}