6. Control Programming.¶
Final Codes
Master code(MCU-1) soap dispenser¶
#include <WiFi.h>
#include <esp_now.h> // - esp now library
#include <Wire.h>
#include <VL53L1X.h> // - Person_Approaching sensor library
#include <DFRobotDFPlayerMini.h>
#include <HardwareSerial.h>
VL53L1X sensor;
uint8_t receiverMac[] = {0x84, 0xFC, 0xE6, 0x00, 0xCF, 0x78}; // - recievers Address
#define SDA_PIN 4
#define SCL_PIN 6
#define DF_RX_PIN 9
#define DF_TX_PIN 10
#define THRESHOLD 800
#define DEBOUNCE_COUNT 3
HardwareSerial dfSerial(1);
DFRobotDFPlayerMini dfplayer;
bool personPresent = false;
uint8_t debounceCounter = 0;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed");
return;
}
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, receiverMac, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
Wire.begin();
Wire.setClock(400000); // use 400 kHz I2C
sensor.setTimeout(500);
if (!sensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1);
}
// information on range and timing limits.
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(50000);
sensor.startContinuous(50);
//dfplayer
dfSerial.begin(9600, SERIAL_8N1, DF_RX_PIN, DF_TX_PIN);
if (!dfplayer.begin(dfSerial)) while (1);
dfplayer.volume(25);
}
void loop() {
sensor.read();
int Person_Approaching = sensor.ranging_data.range_mm;
Serial.print("Range: ");
Serial.print(Person_Approaching);
if (Person_Approaching < THRESHOLD && !personPresent) {
personPresent = true;
dfplayer.play(1); // Entry bird sound
//delay(5000);
}else if(Person_Approaching > THRESHOLD && personPresent) {
const char *message = "Person_Exited"; // - SMS like message
esp_err_t result = esp_now_send(receiverMac, (uint8_t *)message, strlen(message)); // - send SMS
if (result == ESP_OK) {
Serial.println("Message sent");
} else {
Serial.println("Failed to send");
}
dfplayer.stop();
personPresent = false;
}
Serial.println();
delay(2000); // Send every 5 seconds
}
Final slave codes
//-----final soap dispensor code------------
#include <WiFi.h>
#include <esp_now.h>
#include <Wire.h>
#include <VL53L1X.h>
#include <DFRobotDFPlayerMini.h>
#include <HardwareSerial.h>
// ---------- Configuration ----------
#define PUMP_PIN D2
#define SDA_PIN D4
#define SCL_PIN D5
#define DF_RX_PIN D9
#define DF_TX_PIN D10
#define THRESHOLD 80 // mm
// ---------- Globals ----------
VL53L1X sensor;
HardwareSerial dfSerial(1);
DFRobotDFPlayerMini dfplayer;
bool monitoring = false;
bool soapDispensed = false;
bool handDetected = false;
unsigned long triggerTime = 0;
int reminderStage = 0; // 0 = none, 1 = first msg, 2 = second msg, 3 = final msg
void resetFlags() {
monitoring = false;
soapDispensed = false;
handDetected = false;
triggerTime = 0;
reminderStage = 0;
}
// ---------- ESP-NOW Callback ----------
void onDataReceive(const uint8_t *mac, const uint8_t *incomingData, int len) {
String received = "";
for (int i = 0; i < len; i++) {
received += (char)incomingData[i];
}
Serial.print("Received: ");
Serial.println(received);
if (received == "Person_Exited") {
resetFlags();
monitoring = true;
triggerTime = millis();
Serial.println("Monitoring started after person exit");
}
}
// ---------- Setup ----------
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
pinMode(PUMP_PIN, OUTPUT);
digitalWrite(PUMP_PIN, LOW);
// ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed");
return;
}
esp_now_register_recv_cb(onDataReceive);
// VL53L1X
Wire.begin(SDA_PIN, SCL_PIN);
Wire.setClock(400000);
sensor.setTimeout(500);
if (!sensor.init()) {
Serial.println("VL53L1X not found");
while (1);
}
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(50000);
sensor.startContinuous(50);
// DFPlayer
dfSerial.begin(9600, SERIAL_8N1, DF_RX_PIN, DF_TX_PIN);
if (!dfplayer.begin(dfSerial)) {
Serial.println("DFPlayer init failed");
while (1);
}
dfplayer.volume(30); // Adjust as needed
}
// ---------- Loop ----------
void loop() {
sensor.read();
int distance = sensor.ranging_data.range_mm;
if (!monitoring) return;
unsigned long elapsed = millis() - triggerTime;
// Hand detected
if (distance < THRESHOLD && !soapDispensed) {
Serial.println("Hand detected - dispensing soap");
digitalWrite(PUMP_PIN, HIGH);
delay(2000);
digitalWrite(PUMP_PIN, LOW);
dfplayer.play(4); // Thank you
soapDispensed = true;
monitoring = false;
return;
}
// Reminders based on time
if (elapsed > 5000 && reminderStage == 0) {
Serial.println("Playing reminder 1: Don't forget to wash your hands");
dfplayer.play(1); // Don't forget
reminderStage = 1;
} else if (elapsed > 10000 && reminderStage == 1) {
Serial.println("Playing reminder 2: Please wash your hands");
dfplayer.play(2); // Please wash
reminderStage = 2;
} else if (elapsed > 15000 && reminderStage == 2) {
Serial.println("Playing reminder 3: Unhygienic...");
dfplayer.play(3); // Unhygienic
reminderStage = 3;
}
delay(100);
}