Build a
Mini Smart House
That Protects Itself!
A miniature house that locks its door with an RFID card, screams if someone breaks in, and shuts its own roof before the rain ruins your clothes! 🏠⚡
🏡 Meet Your Smart Mini House
This isn't just a model house — it's a working smart home prototype! Using one Arduino Uno, you'll build three real automation features found in actual smart homes: secure entry, intrusion detection, and environmental response. It's the same logic used in real home security systems and weather-aware automation — just shrunk down to dollhouse size!
An RFID reader sits by the front door. Tap an authorised card or key fob, and a servo motor swings the door latch open. Wrong card? The door stays locked and a red LED flashes.
A PIR motion sensor watches for movement near the house. If it detects motion while the house is "armed," a buzzer siren sounds and a red alarm LED flashes rapidly — just like a real burglar alarm!
A rain droplet sensor on the roof detects moisture. The moment it senses rain, a servo motor swings a cover panel over the mini clothesline — keeping your tiny laundry dry!
🛒 Parts Shopping List
Available on Amazon India, Robu.in, or your local electronics shop. Total cost ~₹2,500:
⚡ Circuit Diagram
Three features, one Arduino. Wire each module carefully and double-check before powering on:
🔧 Step-by-Step Build Guide
We'll build all three features one at a time, then combine them into one final program.
Use foam board or thick cardboard to build the house body:
- Walls: 4 panels, about 20×15 cm each, glued into a box shape
- Door: Cut a door opening, attach a hinged flap as the door panel
- Roof: Triangular roof on top — leave a small clothesline area visible at the back where the rain cover servo will swing over
- Mounting points: Glue small platforms inside for the Arduino, breadboard, and servos
Open Arduino IDE → Sketch → Include Library → Manage Libraries and install:
LIBRARY MANAGER// Search and install each: "MFRC522" // for the RFID reader "Servo" // built-in, controls both servos "LiquidCrystal_I2C" // for the status LCD
Upload this small sketch first to find the unique ID of your unlock card. Open Serial Monitor (9600 baud) and scan the card:
find_uid.ino#include <SPI.h> #include <MFRC522.h> #define SS_PIN 10 #define RST_PIN 9 MFRC522 rfid(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); rfid.PCD_Init(); Serial.println("Scan your unlock card..."); } void loop() { if (!rfid.PICC_IsNewCardPresent()) return; if (!rfid.PICC_ReadCardSerial()) return; Serial.print("Card UID: "); for (byte i = 0; i < rfid.uid.size; i++) { Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(rfid.uid.uidByte[i], HEX); } Serial.println(); rfid.PICC_HaltA(); }
Write down the UID — you'll paste it into the main code in the next step!
This is the complete program combining all three features. Replace AUTH_UID with your card's UID from Step 3:
#include <SPI.h> #include <MFRC522.h> #include <Servo.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> // ── Pin Definitions ──────────────────────────── #define SS_PIN 10 #define RST_PIN 9 #define DOOR_SERVO_PIN 5 #define ROOF_SERVO_PIN 6 #define BUZZER_PIN 7 #define GREEN_LED 4 #define RED_LED 8 #define BLUE_LED A1 #define PIR_PIN 3 #define RAIN_PIN A0 #define ARM_BUTTON 2 // ── ⭐ REPLACE WITH YOUR CARD'S UID ───────────── byte AUTH_UID[] = {0xAB, 0xCD, 0xEF, 0x12}; // ── Thresholds ────────────────────────────────── #define RAIN_THRESHOLD 500 // lower value = wetter MFRC522 rfid(SS_PIN, RST_PIN); Servo doorServo; Servo roofServo; LiquidCrystal_I2C lcd(0x27, 16, 2); bool alarmArmed = true; bool roofClosed = false; unsigned long lastButtonPress = 0; // ── Setup ────────────────────────────────────── void setup() { Serial.begin(9600); SPI.begin(); rfid.PCD_Init(); doorServo.attach(DOOR_SERVO_PIN); roofServo.attach(ROOF_SERVO_PIN); doorServo.write(0); // door locked roofServo.write(0); // roof open pinMode(BUZZER_PIN, OUTPUT); pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT); pinMode(BLUE_LED, OUTPUT); pinMode(PIR_PIN, INPUT); pinMode(ARM_BUTTON, INPUT_PULLUP); lcd.init(); lcd.backlight(); lcd.print("Smart House"); lcd.setCursor(0, 1); lcd.print("Booting up..."); delay(1500); Serial.println("Smart House Ready!"); } // ── Helper: compare UID ───────────────────────── bool matchUID(byte* target, byte size) { if (rfid.uid.size != size) return false; for (byte i = 0; i < size; i++) if (rfid.uid.uidByte[i] != target[i]) return false; return true; } // ── Feature 1: RFID Door Lock ─────────────────── void checkDoorLock() { if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return; if (matchUID(AUTH_UID, 4)) { Serial.println("✅ Door unlocked!"); doorServo.write(90); // open door digitalWrite(GREEN_LED, HIGH); lcd.clear(); lcd.print("Door: UNLOCKED"); tone(BUZZER_PIN, 1500, 150); delay(3000); // stay open 3 sec doorServo.write(0); // re-lock digitalWrite(GREEN_LED, LOW); lcd.clear(); lcd.print("Door: Locked"); } else { Serial.println("❌ Unknown card!"); digitalWrite(RED_LED, HIGH); tone(BUZZER_PIN, 400, 400); delay(600); digitalWrite(RED_LED, LOW); } rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); } // ── Feature 2: Theft Alert ────────────────────── void checkTheftAlert() { // Toggle arm/disarm with button (debounced) if (digitalRead(ARM_BUTTON) == LOW && millis() - lastButtonPress > 800) { alarmArmed = !alarmArmed; lastButtonPress = millis(); lcd.clear(); lcd.print(alarmArmed ? "Alarm: ARMED" : "Alarm: Disarmed"); Serial.println(alarmArmed ? "🔒 Alarm armed" : "🔓 Alarm disarmed"); delay(500); } if (alarmArmed && digitalRead(PIR_PIN) == HIGH) { Serial.println("🚨 INTRUDER DETECTED!"); lcd.clear(); lcd.print("!! INTRUDER !!"); for (int i = 0; i < 10; i++) { digitalWrite(RED_LED, HIGH); tone(BUZZER_PIN, 2000, 150); delay(150); digitalWrite(RED_LED, LOW); delay(150); } lcd.clear(); lcd.print("Alarm: ARMED"); } } // ── Feature 3: Rain Protection ────────────────── void checkRainProtection() { int rainLevel = analogRead(RAIN_PIN); if (rainLevel < RAIN_THRESHOLD && !roofClosed) { Serial.println("🌧️ Rain detected! Closing roof..."); roofServo.write(90); // swing cover over clothesline digitalWrite(BLUE_LED, HIGH); lcd.clear(); lcd.print("Rain! Roof"); lcd.setCursor(0,1); lcd.print("CLOSED"); roofClosed = true; } else if (rainLevel >= RAIN_THRESHOLD && roofClosed) { Serial.println("☀️ Rain stopped. Opening roof."); roofServo.write(0); digitalWrite(BLUE_LED, LOW); lcd.clear(); lcd.print("Clear skies"); roofClosed = false; } } // ── Main Loop — checks all 3 features ─────────── void loop() { checkDoorLock(); checkTheftAlert(); checkRainProtection(); delay(100); // small loop delay for stability }
Bring it all together inside your mini house:
- Mount the RFID reader just outside the front door
- Place the PIR sensor facing outward through a small window or the roof eave
- Fix the rain sensor plate flat on top of the roof, slightly tilted to shed water
- Hide the Arduino, breadboard, and wiring inside the house body
- Paint the house, add a tiny clothesline with paper clothes pegged on
- Add a porch light LED for extra realism! 💡
🛠️ Troubleshooting Guide
Three systems means more things to debug — but that's part of the fun of engineering!
| 🔴 Problem | 🟡 Likely Cause | ✅ Fix |
|---|---|---|
| RFID card always "Unknown" | UID doesn't match what's in code | Re-run find_uid.ino, copy the exact UID into AUTH_UID array |
| PIR sensor alarms constantly | Sensitivity too high or sensor warming up | Wait 30–60 sec after power-on for PIR to calibrate. Turn sensitivity dial down |
| Rain sensor always says "raining" | RAIN_THRESHOLD value wrong for your sensor | Print analogRead(A0) value via Serial — set threshold halfway between dry and wet readings |
| Both servos jitter constantly | Insufficient power from Arduino 5V pin | Power servos from a separate 5V supply, share common GND with Arduino |
| LCD shows garbled text | Wrong I²C address or loose wiring | Try 0x3F instead of 0x27. Recheck SDA→A4 and SCL→A5 connections |
| Buzzer doesn't sound for alarm | tone() conflicts with Servo library on same timer | This is a known Arduino issue — move buzzer to a different pin away from servo PWM pins |
| Door servo doesn't return to locked | Code stuck in delay() during card read | This is expected — wait for the 3 second auto-relock delay to finish |
🚀 Level Up Your Smart House!
Once the basic version works, try these advanced features used in real smart homes:
Add an ESP8266 to send a phone alert via Blynk app whenever the alarm triggers!
Add a 4×4 keypad as a backup PIN code entry if you lose your RFID card.
Add an ESP32-CAM to snap a photo whenever the PIR sensor triggers the alarm.
Add a DHT11 sensor to show indoor temperature and humidity on the LCD too!
Add a small solar panel + battery so your smart house runs completely off-grid.
Store an array of 5 different UIDs — give every family member their own access card!
❓ Frequently Asked Questions
Yes! This project is specifically designed to fit Arduino Uno's pins and memory. If you want to add even more sensors later, consider upgrading to an Arduino Mega which has many more pins.
The rain sensor works with any moisture — actual rain, a few water droplets, or even high humidity in extreme cases. For a real outdoor installation, mount it at a slight angle so water doesn't pool and give false readings.
Great question — in the current code, checkDoorLock() runs first, then checkTheftAlert(). If you scan a valid card while the alarm is armed, you'll briefly see both running. For a smarter system, add logic so unlocking the door automatically disarms the alarm — a great exercise to try yourself!
Absolutely — the core logic is identical to commercial smart home products! Scaling up would mean using stronger motors/actuators, weatherproof sensors, and a more powerful microcontroller, but the programming concepts you're learning here apply directly.
Definitely — judges love multi-feature integrated builds! Be ready to explain how each sensor works (PIR detects infrared body heat, rain sensors measure conductivity, RFID uses radio frequency identification) — that depth of explanation really impresses evaluators.
The Arduino Servo library uses Timer1, and tone() can sometimes interfere with PWM timing on certain pins. If you notice glitches, try using a NewTone or non-blocking buzzer library, or simply ensure your buzzer pin isn't one of the PWM-capable pins used by servos (3, 5, 6, 9, 10, 11).

Comments
Post a Comment