#include <WiFi.h>
#include <ESP32Servo.h>
#include "PubSubClient.h"
#include <DHT.h>
#define DHTTYPE DHT22
DHT dht(35, DHTTYPE);
int humidity;
const char *ssid = "Wokwi-GUEST";
const char *password = "";
const int waterLevelPinEcho = 5;
const int waterLevelPinTrig = 18;
const int servoPin = 2; // Digital pin for servo motor
const int res_len = 400; // taille du réservoir supposé 4 metre
const int servoPin1 = 23;
const int servoPin2 = 22;
const int servoPin3 = 21;
int travelTime;
float distance;
Servo myservo;
const char* mqttServer = "broker.hivemq.com";//"z96e4d99.us-east-1.emqx.cloud";
const int mqttPort = 1883;
// Choisir une valeur personnalisée pour mqttClient
// -> TOPICS auront le format mqqClient/.....
const char* mqttClient= "niveau_eau"; //Do not modify. Else, must change the topic in Amazon Lambda Function
WiFiClient espClient;
PubSubClient client(espClient);
char *TopicAction =(char*)malloc(50);
void setup() {
//Topics
strcpy (TopicAction, mqttClient);
strcat (TopicAction,"/Action");
Serial.begin(115200);
pinMode(waterLevelPinEcho, INPUT);
pinMode(waterLevelPinTrig, OUTPUT);
pinMode(servoPin1, OUTPUT);
pinMode(servoPin2, OUTPUT);
pinMode(servoPin3, OUTPUT);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialize servo motor
myservo.attach(servoPin);
closeServo();
digitalWrite(servoPin1, LOW);
digitalWrite(servoPin2, LOW);
digitalWrite(servoPin3, LOW);
connectmqtttopic();
}
void connectmqtttopic(){
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect(mqttClient )) {//in this case no user, no password are needed
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
if (client.subscribe(TopicAction)) {
Serial.print ("Suscribed to Topic: ");
Serial.println(TopicAction);
}
}
void loop() {
sendSoundWave();
travelTime = pulseIn(waterLevelPinEcho, HIGH); //Get Travel Time
distance = travelTime * 0.034 / 2; //Calculate Distance in cm
humidity = dht.readHumidity();
if(distance < 20){
closeServo();
}
else if((distance > 350) && humidity < 10){
openServo();
}
client.loop();
delay(1000);
}
void sendSoundWave() {
digitalWrite(waterLevelPinTrig, LOW);
delayMicroseconds(2);
digitalWrite(waterLevelPinTrig, HIGH);
delayMicroseconds(10);
digitalWrite(waterLevelPinTrig, LOW);
}
void openServo() {
myservo.write(180); // Open the servo (adjust as needed)
}
void closeServo() {
myservo.write(0); // Close the servo (adjust as needed)
}
void callback(char* topic, byte* payload, unsigned int length) {
char topicpl;
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
String allpayload= String( (char*) payload);
String thepayload = allpayload.substring(0,length);
if (thepayload.equals("OPEN")) {
if ((distance > 20) && (humidity > 10)){
openServo();
Serial.println("Servo opened");
client.publish(TopicAction, "Pompes Ouvertes");
}
else if((distance > 20) && (humidity < 10)){
client.publish(TopicAction, "Pluie tombe");
}
else{
client.publish(TopicAction, "Reservoir plein");
}
}
if (thepayload.equals("CLOSE")) {
closeServo();
Serial.println("Servo closed");
client.publish(TopicAction, "Pompes Fermées");}
if (thepayload.equals("LEVEL")) {
char level[10];
float p = ((res_len - distance)/res_len)*100;
dtostrf(p, 4, 2, level);
char *msg =(char*)malloc(50);
strcat (msg,"Le réservoir est ");
strcat (msg,level);
strcat (msg," % plein.");
client.publish(TopicAction, msg);
}
if (thepayload.equals("ZONE1")) {
if ((distance < 350) && (distance > 20)){
digitalWrite(servoPin1, HIGH);
digitalWrite(servoPin2, LOW);
digitalWrite(servoPin3, LOW);
Serial.println("Servo for zone 1 opened");
client.publish(TopicAction, "Pompes pour Zone 1 sont Ouvertes");
}
else{
client.publish(TopicAction, "Reservoir vide");
}
}
if (thepayload.equals("ZONE2")) {
if ((distance < 350) && (distance > 20)){
digitalWrite(servoPin1, LOW);
digitalWrite(servoPin2, HIGH);
digitalWrite(servoPin3, LOW);
Serial.println("Servo for zone 2 opened");
client.publish(TopicAction, "Pompes pour Zone 2 sont Ouvertes");
}
else{
client.publish(TopicAction, "Reservoir vide");
}
}
if (thepayload.equals("ZONE3")) {
if ((distance < 350) && (distance > 20)){
digitalWrite(servoPin1, LOW);
digitalWrite(servoPin2, LOW);
digitalWrite(servoPin3, HIGH);
Serial.println("Servo for zone 3 opened");
client.publish(TopicAction, "Pompes pour Zone 3 sont Ouvertes");
}
else{
client.publish(TopicAction, "Reservoir vide");
}
}
Serial.println("-----------------------");
}