#include <WiFi.h>
#include <ESP32Servo.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <PubSubClient.h>
#include <HTTPClient.h>
const char* mqtt_server = "broker.mqtt-dashboard.com"; // Replace with your broker address
const int mqtt_port = 1883; // Default port for WebSocket over HTTPS
WiFiClient espClient;
PubSubClient client(espClient);
// WiFi Credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Ultrasonic sensor pins
#define TRIG_PIN 5
#define ECHO_PIN 18
#define TRIG2_PIN 2
#define ECHO2_PIN 0
// DHT sensor pins
#define DHT_PIN 4
#define DHT_TYPE DHT22
// Servo pins
#define SERVO_PIN 16
#define SERVO2_PIN 17
// LED pins
#define LED_RED 14
#define LED_GREEN 12
#define LED_BLUE 13
// PIR pins
#define PIR1_PIN 19
#define PIR2_PIN 27
// Variables
Servo myservo;
Servo myservo2;
DHT dht(DHT_PIN, DHT_TYPE);
long duration;
int distance;
long duration2;
int distance2;
unsigned long motionDetectedTime = 0;
unsigned long lastMotionTime = 0;
bool detected_hand = false;
bool in_kennel = true;
bool is_awake = true;
bool provide_food = false;
bool provide_water = false;
unsigned long servo1StartTime = 0;
bool servo1Open = false;
unsigned long servo2StartTime = 0;
bool servo2Open = false;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void callback(char* topic, byte* payload, unsigned int length) {
char buffer[length + 1];
memcpy(buffer, payload, length);
buffer[length] = '\0';
bool value = strcmp(buffer, "true") == 0;
if (value) {
if (String(topic) == "/22127143/topic/provide_food") provide_food = true;
if (String(topic) == "/22127143/topic/provide_water") provide_water = true;
}
}
void setup() {
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
// Serial.println("Connected to WiFi");
// Initialize sensors and servo
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(TRIG2_PIN, OUTPUT);
pinMode(ECHO2_PIN, INPUT);
dht.begin();
myservo.attach(SERVO_PIN);
myservo2.attach(SERVO2_PIN);
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(PIR1_PIN, INPUT);
pinMode(PIR2_PIN, INPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
// Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
// Function to send SMS using Pushsafer
void sendSMS(String message) {
HTTPClient http;
http.begin("https://www.pushsafer.com/api");
String postData = "k=3NdpC6Q9tn4TUdlm2Ock";
postData += "&m=" + message; // The message to be sent
postData += "&d=a";
postData += "&s=1";
postData += "&v=2";
postData += "&l=1";
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpResponseCode = http.POST(postData);
// if (httpResponseCode > 0) {
// String response = http.getString();
// Serial.println("Pushsafer Response: " + response);
// } else {
// Serial.println("Error in sending POST: " + String(httpResponseCode));
// }
http.end();
}
void reconnect() {
while (!client.connected()) {
// Serial.print("Attempting MQTT connection...");
if (client.connect("22CLC02-22127143")) {
Serial.println("MQTT connected");
client.subscribe("/22127143/topic/provide_food");
client.subscribe("/22127143/topic/provide_water");
} else {
// Serial.print("failed, rc=");
// Serial.print(client.state());
// Serial.println(" try again in 1 seconds");
delay(1000);
}
}
}
void provide_food_and_water(bool food, bool water) {
myservo.write(0);
myservo2.write(0);
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 2;
float level = 9 - distance;
client.publish("/22127143/topic/food_level", String(level).c_str());
digitalWrite(TRIG2_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG2_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG2_PIN, LOW);
duration2 = pulseIn(ECHO2_PIN, HIGH);
distance2 = duration2 * 0.034 / 2;
float level2 = 9 - distance2;
client.publish("/22127143/topic/water_level", String(level2).c_str());
if (distance > 7) {
sendSMS("The food level is low.");
}
if (distance2 > 7) {
sendSMS("The water level is low.");
}
if (food && distance > 6.5) {
myservo.write(90);
servo1Open = true;
servo1StartTime = millis();
provide_food = false;
}
if (water && distance2 > 6.5) {
myservo2.write(90);
servo2Open = true;
servo2StartTime = millis();
provide_water = false;
}
}
void check_temperature_and_humidity() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
display.setCursor(0, 0);
display.println("Temp: " + String(temperature) + "C");
display.display();
client.publish("/22127143/topic/temperature", String(temperature).c_str());
display.setCursor(0, 15);
display.println("Humidity: " + String(humidity) + "%");
display.display();
client.publish("/22127143/topic/humidity", String(humidity).c_str());
}
void check_dog_status() {
int motionState = digitalRead(PIR1_PIN);
if (motionState == HIGH) {
lastMotionTime = millis();
}
if (digitalRead(PIR2_PIN) == HIGH) detected_hand = true;
if (is_awake && (millis() - lastMotionTime > 5000)) { // 5 minutes
is_awake = false;
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_BLUE, LOW);
client.publish("/22127143/topic/status", "Sleeping");
} else if (!is_awake && (millis() - lastMotionTime < 3000)) { // 3 minutes
is_awake = true;
in_kennel = true;
detected_hand = false;
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_BLUE, LOW);
client.publish("/22127143/topic/status", "Awake");
} else if (!is_awake && detected_hand) {
in_kennel = false;
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_BLUE, HIGH);
sendSMS("Dog is out of kennel.");
}
}
void loop() {
provide_food_and_water(provide_food, provide_water);
if (servo1Open && (millis() - servo1StartTime >= 2000)) {
myservo.write(0); // Close the servo
servo1Open = false;
}
if (servo2Open && (millis() - servo2StartTime >= 2000)) {
myservo2.write(0); // Close the servo
servo2Open = false;
}
check_temperature_and_humidity();
check_dog_status();
if (!client.connected()) {
reconnect();
}
client.loop();
delay(1000);
}