/***************************************************************
ESP32 DevKit-C V4 — AI Smart Washing Machine (Wokwi-ready)
Corrected for your diagram.json wiring
***************************************************************/
#define BLYNK_TEMPLATE_ID "TMPL3fOmsq3fT"
#define BLYNK_TEMPLATE_NAME "AI Powered Smart Washing Machine"
#define BLYNK_AUTH_TOKEN "2s9kdrlW_5g9QpyAXPMTxwn4tXAc99r7"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <LiquidCrystal_I2C.h>
// WiFi
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// Pins (matching diagram.json)
const int PIN_POT_FABRIC = 33;
const int PIN_LDR = 34;
const int TRIG_PIN = 26;
const int ECHO_PIN = 27;
// Stepper motor (your wiring only allows 2-pin fake control)
const int MOTOR_PIN1 = 13; // A-
const int MOTOR_PIN2 = 14; // B+
// LEDs
const int LED_WASH = 32;
const int LED_RINSE = 25;
const int LED_SPIN = 2;
const int LED_DONE = 19;
// Buzzer
const int BUZZER_PIN = 23;
// LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Blynk pins
#define VP_POWER V0
#define VP_GENTLE V1
#define VP_HEAVY V2
#define VP_TERM V3
// --------------------------------------------------
// ENUM BEFORE USE
// --------------------------------------------------
enum WashMode { QUICK_GENTLE, GENTLE, NORMAL, HEAVY };
// --------------------------------------------------
// Buzzer melody
// --------------------------------------------------
int melody[] = {330,330,349,392,392,349,330,294,262};
int durations[] = {4,4,4,4,4,4,4,4,4};
void playMelody(){
for (int i=0; i<9; i++){
int d = 1000 / durations[i];
tone(BUZZER_PIN, melody[i], d);
delay(d*1.2);
noTone(BUZZER_PIN);
}
}
// --------------------------------------------------
// Sensor
// --------------------------------------------------
long readUltrasonicCM(){
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 38000);
if (duration == 0) return -1;
return duration / 58;
}
// --------------------------------------------------
// AI Prediction
// --------------------------------------------------
WashMode ai_predict_mode(int dirtRaw, int fabricRaw, int waterPct){
if (dirtRaw > 3200) return HEAVY;
if (fabricRaw > 2500) return GENTLE;
if (dirtRaw < 1500) return QUICK_GENTLE;
return NORMAL;
}
// --------------------------------------------------
// Fake Stepper (because diagram uses only 2 pins)
// --------------------------------------------------
void motorRotate(int speedDelay){
digitalWrite(MOTOR_PIN1, HIGH);
digitalWrite(MOTOR_PIN2, LOW);
delay(speedDelay);
digitalWrite(MOTOR_PIN1, LOW);
digitalWrite(MOTOR_PIN2, HIGH);
delay(speedDelay);
}
// --------------------------------------------------
// Washing Programs
// --------------------------------------------------
void doWash(int cycles){
lcd.clear(); lcd.print("Washing...");
for(int i=0;i<cycles;i++) motorRotate(50);
}
void doRinse(int cycles){
lcd.clear(); lcd.print("Rinsing...");
for(int i=0;i<cycles;i++) motorRotate(80);
}
void doSpin(int cycles){
lcd.clear(); lcd.print("Spinning...");
for(int i=0;i<cycles;i++) motorRotate(20);
}
void runGentle(){
Blynk.virtualWrite(VP_TERM, "Gentle Cycle START");
digitalWrite(LED_WASH, HIGH);
doWash(25);
digitalWrite(LED_WASH, LOW);
digitalWrite(LED_RINSE, HIGH);
doRinse(15);
digitalWrite(LED_RINSE, LOW);
digitalWrite(LED_SPIN, HIGH);
doSpin(20);
digitalWrite(LED_SPIN, LOW);
digitalWrite(LED_DONE, HIGH);
lcd.clear(); lcd.print("Gentle Done");
playMelody();
delay(500);
digitalWrite(LED_DONE, LOW);
}
void runHeavy(){
Blynk.virtualWrite(VP_TERM, "Heavy Cycle START");
digitalWrite(LED_WASH, HIGH);
doWash(40);
digitalWrite(LED_WASH, LOW);
digitalWrite(LED_RINSE, HIGH);
doRinse(20);
digitalWrite(LED_RINSE, LOW);
digitalWrite(LED_SPIN, HIGH);
doSpin(30);
digitalWrite(LED_SPIN, LOW);
digitalWrite(LED_DONE, HIGH);
lcd.clear(); lcd.print("Heavy Done");
playMelody();
delay(500);
digitalWrite(LED_DONE, LOW);
}
// --------------------------------------------------
// Blynk Controls
// --------------------------------------------------
BLYNK_WRITE(VP_POWER){
if(param.asInt()==1){
lcd.clear(); lcd.print("POWER ON");
Blynk.virtualWrite(VP_TERM, "POWER ON");
} else {
lcd.clear(); lcd.print("POWER OFF");
Blynk.virtualWrite(VP_TERM, "POWER OFF");
}
}
BLYNK_WRITE(VP_GENTLE){ if(param.asInt()==1) runGentle(); }
BLYNK_WRITE(VP_HEAVY){ if(param.asInt()==1) runHeavy(); }
// --------------------------------------------------
void setup(){
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(MOTOR_PIN1, OUTPUT);
pinMode(MOTOR_PIN2, OUTPUT);
pinMode(LED_WASH, OUTPUT);
pinMode(LED_RINSE, OUTPUT);
pinMode(LED_SPIN, OUTPUT);
pinMode(LED_DONE, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
lcd.init();
lcd.backlight();
lcd.print("AI Washer Boot");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
delay(1000);
lcd.clear(); lcd.print("Ready");
}
void loop(){
Blynk.run();
}