#include <Arduino.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include <PubSubClient.h>
#define TRIG_PIN_FRONT 12
#define ECHO_PIN_FRONT 14
#define TRIG_PIN_LEFT 27
#define ECHO_PIN_LEFT 26
#define TRIG_PIN_RIGHT 18
#define ECHO_PIN_RIGHT 17
#define TRIG_PIN_BACK 5
#define ECHO_PIN_BACK 16
#define DIST_THRESHOLD 20
#define BUZZER_PIN 4
Servo servoLeft;
Servo servoRight;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "172.187.230.56";
const int mqttPort = 1883;
const char* mqttUser = "";
const char* mqttPassword = "";
const char* machineTopic = "cleaner/machine";
WiFiClient espClient;
PubSubClient client(espClient);
bool machineState = false;
bool bladeState = false;
void setup() {
Serial.begin(9600);
servoLeft.setPeriodHertz(50);
servoRight.setPeriodHertz(50);
servoLeft.attach(21, 1000, 2000);
servoRight.attach(19, 1000, 2000);
pinMode(TRIG_PIN_FRONT, OUTPUT);
pinMode(ECHO_PIN_FRONT, INPUT);
pinMode(TRIG_PIN_LEFT, OUTPUT);
pinMode(ECHO_PIN_LEFT, INPUT);
pinMode(TRIG_PIN_RIGHT, OUTPUT);
pinMode(ECHO_PIN_RIGHT, INPUT);
pinMode(TRIG_PIN_BACK, OUTPUT);
pinMode(ECHO_PIN_BACK, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
setup_wifi();
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.println("Message arrived on topic:");
Serial.print(topic);
Serial.println();
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println("Message received:");
Serial.println(message);
if (strcmp(topic, machineTopic) == 0) {
if (message == "on") {
machineState = true;
Serial.println("Machine turned ON");
} else if (message == "off") {
machineState = false;
Serial.println("Machine turned OFF");
} else if (message == "blade_on") {
bladeState = true;
Serial.println("Blade turned ON");
} else if (message == "blade_off") {
bladeState = false;
Serial.println("Blade turned OFF");
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP32Client")) {
Serial.println("connected");
// Once connected, subscribe to the topics
client.subscribe(machineTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (machineState) {
int distanceFront = getDistance(TRIG_PIN_FRONT, ECHO_PIN_FRONT);
int distanceLeft = getDistance(TRIG_PIN_LEFT, ECHO_PIN_LEFT);
int distanceRight = getDistance(TRIG_PIN_RIGHT, ECHO_PIN_RIGHT);
int distanceBack = getDistance(TRIG_PIN_BACK, ECHO_PIN_BACK);
Serial.print("Front distance: ");
Serial.print(distanceFront);
Serial.print(" cm, Left distance: ");
Serial.print(distanceLeft);
Serial.print(" cm, Right distance: ");
Serial.print(distanceRight);
Serial.print(" cm, Back distance: ");
Serial.print(distanceBack);
Serial.println(" cm");
// Check if all sides have obstacles within 2 cm
if (distanceFront <= 2 && distanceLeft <= 2 && distanceRight <= 2 && distanceBack <= 2) {
Serial.println("Obstacles detected on all sides. Stopping machine.");
machineState = false;
moveStop(); // Add a function to stop the machine
return; // Exit the loop to prevent further execution
}
if (distanceFront <= DIST_THRESHOLD) {
if (distanceLeft > distanceRight) {
Serial.println("Obstacle on the left, turning right");
turnRight();
} else {
Serial.println("Obstacle on the right, turning left");
turnLeft();
}
} else if (distanceBack <= DIST_THRESHOLD) {
Serial.println("Obstacle behind, turning around");
turnAround();
} else {
Serial.println("No obstacle detected. Moving forward.");
moveForward();
}
// Control the blade if it's turned on
if (bladeState) {
// Blade operation logic here
}
// Continuous sweeping of both servos
sweepServos();
}
delay(1000);
digitalWrite(BUZZER_PIN, HIGH);
delay(100); // Adjust the duration of the beep
digitalWrite(BUZZER_PIN, LOW);
}
void moveStop() {
servoLeft.write(90);
servoRight.write(90);
}
int getDistance(int trigPin, int echoPin) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;
// If the distance is out of range, return a large value
if (distance <= 0 || distance > 400) {
return 400; // Maximum sensor range is typically around 400 cm
}
return distance;
}
void moveForward() {
servoLeft.write(90);
servoRight.write(90);
}
void turnLeft() {
servoLeft.write(0);
servoRight.write(180);
}
void turnRight() {
servoLeft.write(180);
servoRight.write(0);
}
void turnAround() {
servoLeft.write(180);
servoRight.write(180);
}
void sweepServos() {
for (int pos = 0; pos <= 180; pos += 1) {
servoLeft.write(pos);
servoRight.write(pos);
delay(2);
}
for (int pos = 180; pos >= 0; pos -= 1) {
servoLeft.write(pos);
servoRight.write(pos);
delay(2);
}
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
ultrasonic1:VCC
ultrasonic1:TRIG
ultrasonic1:ECHO
ultrasonic1:GND
ultrasonic2:VCC
ultrasonic2:TRIG
ultrasonic2:ECHO
ultrasonic2:GND
ultrasonic3:VCC
ultrasonic3:TRIG
ultrasonic3:ECHO
ultrasonic3:GND
ultrasonic4:VCC
ultrasonic4:TRIG
ultrasonic4:ECHO
ultrasonic4:GND
servo1:GND
servo1:V+
servo1:PWM
servo2:GND
servo2:V+
servo2:PWM
bz1:1
bz1:2