Project Overview
This project creates a smart laundry reminder system that detects when you enter the laundry room and reminds you if there’s a load waiting to be transferred from washer to dryer or from dryer to basket. It’s perfect for busy households where laundry often gets forgotten.
Difficulty: Intermediate
Estimated time: 2-3 hours
Estimated cost: $25-35
How It Works
PIR sensors detect when someone enters the laundry room. The system checks the state of the washer and dryer (using vibration sensors or current sensors) and knows if there’s a completed load waiting. If laundry needs attention, it plays a voice reminder through a speaker. A display can also show the status.
Optional features include sending a notification to your phone and tracking laundry cycles over time.
Materials Needed
- ESP32 (1)
- HC-SR501 PIR sensor (1)
- Vibration sensors (SW-420) for washer and dryer (2)
- DFPlayer Mini MP3 module (1)
- MicroSD card (with voice reminders)
- Small speaker (3W)
- OLED display (128×64, I2C) (optional)
- LEDs (for status indication)
- Resistors (220Ω)
- Jumper wires
- Power supply (5V 2A)
- Project enclosure
Circuit Diagram
Connection Table
| Component |
Pin |
ESP32 Pin |
PIR Sensor |
OUT
| GPIO 4
| Washer Vibration Sensor |
OUT
| GPIO 5
| Dryer Vibration Sensor |
OUT
| GPIO 6
| DFPlayer Mini |
TX
| GPIO 16
| DFPlayer Mini |
RX
| GPIO 17
| OLED Display |
SDA
| GPIO 21
| OLED Display |
SCL
| GPIO 22
| Red LED (Washer status) |
Anode
| GPIO 2
| Green LED (Dryer status) |
Anode
| GPIO 15
|
表
Arduino Code
// Laundry Room Reminder System
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
SoftwareSerial mySoftwareSerial(16, 17);
DFRobotDFPlayerMini myDFPlayer;
const int pirPin = 4;
const int washerSensorPin = 5;
const int dryerSensorPin = 6;
const int redLedPin = 2;
const int greenLedPin = 15;
// Laundry state variables
bool washerRunning = false;
bool dryerRunning = false;
bool washerDone = false;
bool dryerDone = false;
unsigned long washerStopTime = 0;
unsigned long dryerStopTime = 0;
unsigned long lastReminderTime = 0;
const unsigned long reminderCooldown = 1800000; // 30 minutes between reminders
void setup() {
Serial.begin(115200);
pinMode(pirPin, INPUT);
pinMode(washerSensorPin, INPUT);
pinMode(dryerSensorPin, INPUT);
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
// Initialize display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("Display not found");
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// Initialize DFPlayer
mySoftwareSerial.begin(9600);
if (!myDFPlayer.begin(mySoftwareSerial)) {
Serial.println("DFPlayer error");
}
myDFPlayer.volume(25);
displayMessage("Laundry Monitor", "Ready");
Serial.println("Laundry Monitor Ready");
delay(30000); // PIR warm-up
}
void displayMessage(String line1, String line2) {
display.clearDisplay();
display.setCursor(0, 0);
display.println(line1);
display.setCursor(0, 20);
display.println(line2);
display.display();
}
void checkVibrationSensors() {
// Washer detection
bool washerVibration = digitalRead(washerSensorPin) == HIGH;
if (washerVibration && !washerRunning) {
washerRunning = true;
washerDone = false;
Serial.println("Washer started");
displayMessage("Washer", "Running...");
}
if (!washerVibration && washerRunning) {
washerRunning = false;
washerStopTime = millis();
washerDone = true;
Serial.println("Washer finished");
displayMessage("Washer", "Done!");
digitalWrite(redLedPin, HIGH);
}
// Dryer detection
bool dryerVibration = digitalRead(dryerSensorPin) == HIGH;
if (dryerVibration && !dryerRunning) {
dryerRunning = true;
dryerDone = false;
Serial.println("Dryer started");
displayMessage("Dryer", "Running...");
}
if (!dryerVibration && dryerRunning) {
dryerRunning = false;
dryerStopTime = millis();
dryerDone = true;
Serial.println("Dryer finished");
displayMessage("Dryer", "Done!");
digitalWrite(greenLedPin, HIGH);
}
// Auto-clear after 1 hour
if (washerDone && (millis() - washerStopTime > 3600000)) {
washerDone = false;
digitalWrite(redLedPin, LOW);
}
if (dryerDone && (millis() - dryerStopTime > 3600000)) {
dryerDone = false;
digitalWrite(greenLedPin, LOW);
}
}
void playReminder() {
if (washerDone && dryerDone) {
myDFPlayer.play(1); // "Both washer and dryer are done"
Serial.println("Reminder: Both loads done");
displayMessage("Reminder", "Both loads done!");
} else if (washerDone) {
myDFPlayer.play(2); // "Washer is done"
Serial.println("Reminder: Washer done");
displayMessage("Reminder", "Move washer load");
} else if (dryerDone) {
myDFPlayer.play(3); // "Dryer is done"
Serial.println("Reminder: Dryer done");
displayMessage("Reminder", "Take out clothes");
}
}
void loop() {
checkVibrationSensors();
bool motion = digitalRead(pirPin) == HIGH;
if (motion && (washerDone || dryerDone) &&
(millis() - lastReminderTime > reminderCooldown)) {
lastReminderTime = millis();
playReminder();
}
// Update display with current status
if (!motion) {
String status1 = "Washer: ";
status1 += washerRunning ? "Running" : (washerDone ? "DONE!" : "Idle");
String status2 = "Dryer: ";
status2 += dryerRunning ? "Running" : (dryerDone ? "DONE!" : "Idle");
displayMessage(status1, status2);
}
delay(100);
}
Voice Prompt Files
Create MP3 files on SD card (folder “01”):
- 001.mp3: “The washer and dryer are both finished. Please attend to the laundry.”
- 002.mp3: “The washing machine has finished its cycle. Please move clothes to the dryer.”
- 003.mp3: “The dryer has finished. Please remove your clothes.”
Installation Steps
- Mount vibration sensors: Attach SW-420 sensors to washer and dryer using magnets or double-sided tape.
- Position PIR sensor: Place at doorway of laundry room at 2m height.
- Mount speaker: Position where reminder can be heard clearly.
- Assemble electronics: Place ESP32 and DFPlayer in enclosure.
- Test sensors: Run washer/dryer cycles to verify detection.
- Adjust sensitivity: Vibration sensors may need adjustment to avoid false triggers.
Project Extensions
- Wi-Fi notifications: Send push notification to phone when cycle completes.
- Google Home integration: Announce reminders on smart speakers.
- LED strip: Add color-changing LED strip to show status at a glance.
- Usage tracking: Log laundry cycles to track energy usage and detergent consumption.
- Remote monitoring: Check laundry status from anywhere via web interface.
Troubleshooting
- Vibration sensor not detecting: Adjust sensitivity potentiometer. Ensure sensor is in firm contact with machine.
- False detections: Reduce sensitivity. Add debounce in code.
- No voice reminders: Check DFPlayer wiring and SD card files.
- PIR not detecting: Adjust sensitivity. Ensure clear view of doorway.
Conclusion
This laundry reminder system eliminates forgotten loads and makes laundry day more efficient. With automatic detection and voice reminders, you’ll never leave wet clothes in the washer again.