#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>
#include <Keypad.h>
#include <DHT.h>
#include <SPI.h>
#include <MFRC522.h>
// OLED display initialization
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Define the pins for the keypad
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {22, 23, 24, 25};
byte colPins[COLS] = {26, 27, 28, 29};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Define the pins for the servos
const int curtainServoPin = 13;
const int doorServoPin = 12;
const int ventServoPin = 11;
Servo curtainServo;
Servo doorServo;
Servo ventServo;
// Define the pins for the relays
const int relay1Pin = 30;
const int relay2Pin = 31;
// Define the DHT11 sensor pin
const int dhtPin = A1;
DHT dht(dhtPin, DHT11);
// Define the pins for the PIR sensor
const int pirPin = 36;
// Define the pins for the LED lights
const int light1Pins[4] = {9, 8, 7, 6};
const int light2Pins[4] = {5, 4, 3, 2};
const int light3Pins[4] = {32, 33, 34, 35};
// Define other variables
const int ldrPin = A0;
const int ldrThreshold = 800; // Adjust this threshold based on your LDR readings
bool curtainAutomationEnabled = false;
bool ventShaftOpened = false;
bool dhtAutomationEnabled = false;
bool pirAutomationEnabled = false;
bool pirMotionDetected = false;
// Pin Definitions
#define RST_PIN 49
#define SS_PIN 53
#define BUZZER_PIN 10
#define GREEN_LED_PIN 47
#define RED_LED_PIN 48
// Create instances
MFRC522 mfrc522(SS_PIN, RST_PIN);
// Known UID values (Authorized Cards)
byte knownUID[][4] = {
{0xC7, 0xFD, 0xBA, 0x3B}, // Example known UID 1
{0x2B, 0x14, 0x63, 0x1B} // Example known UID 2
};
// Variables
int declineCount = 0;
const int maxDeclineCount = 3;
const unsigned long buzzerDuration = 5000;
unsigned long buzzerStartTime = 0;
int greenLedBlinks = 2;
int redLedBlinks = 2;
void setup() {
// Initialize display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.setTextSize(2); // Larger text size
display.setTextColor(SSD1306_WHITE);
display.clearDisplay();
// Display "Smart Holiday Apartment" centered
String textLine1 = "Smart";
String textLine2 = "Holiday";
String textLine3 = "Apartment";
int textWidth1 = textLine1.length() * 12; // Each character is 12 pixels wide with larger text size
int textWidth2 = textLine2.length() * 12;
int textWidth3 = textLine3.length() * 12;
int centerX = (SCREEN_WIDTH - textWidth1) / 2;
int centerY = (SCREEN_HEIGHT - 36) / 2; // 36 is the total height of 3 lines with larger text size
display.setCursor(centerX, centerY);
display.println(textLine1);
centerY += 18; // Move to the next line
display.setCursor((SCREEN_WIDTH - textWidth2) / 2, centerY);
display.println(textLine2);
centerY += 18;
display.setCursor((SCREEN_WIDTH - textWidth3) / 2, centerY);
display.println(textLine3);
display.display();
// Attach servos to their respective pins
curtainServo.attach(curtainServoPin);
doorServo.attach(doorServoPin);
ventServo.attach(ventServoPin);
// Initialize relay pins
pinMode(relay1Pin, OUTPUT);
pinMode(relay2Pin, OUTPUT);
// Turn off both relays initially
digitalWrite(relay1Pin, HIGH); // Assuming relay is active LOW
digitalWrite(relay2Pin, HIGH); // Assuming relay is active LOW
// Initialize PIR sensor
pinMode(pirPin, INPUT);
// Initialize LED light pins
for (int i = 0; i < 4; i++) {
pinMode(light1Pins[i], OUTPUT);
pinMode(light2Pins[i], OUTPUT);
pinMode(light3Pins[i], OUTPUT);
}
// Initialize DHT22 sensor
dht.begin();
// Initialize serial communication
Serial.begin(9600);
// Set initial servo positions
curtainServo.write(0);
doorServo.write(90);
ventServo.write(11);
SPI.begin();
mfrc522.PCD_Init();
pinMode(BUZZER_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
Serial.println("RFID Reader Initialized");
mfrc522.PCD_DumpVersionToSerial();
}
void loop() {
int ldrValue = analogRead(ldrPin);
bool isDay = ldrValue < ldrThreshold;
// Read temperature and humidity from DHT11 sensor
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// Read PIR sensor
pirMotionDetected = digitalRead(pirPin) == HIGH;
// Keypad input handling
char key = keypad.getKey();
if (key != NO_KEY) {
switch (key) {
case '1':
toggleLights(light1Pins, 4);
displayAction("LIGHT 1", digitalRead(light1Pins[0]) == HIGH ? "ON" : "OFF");
break;
case '2':
toggleLights(light2Pins, 4);
displayAction("LIGHT 2", digitalRead(light2Pins[0]) == HIGH ? "ON" : "OFF");
break;
case '4':
toggleRelay(relay1Pin);
displayAction("FAN", digitalRead(relay1Pin) == LOW ? "ON" : "OFF");
break;
case '5':
if (ventShaftOpened) {
toggleRelay(relay2Pin);
displayAction("VENT FAN", digitalRead(relay2Pin) == LOW ? "ON" : "OFF");
}
break;
case 'A':
togglePIRAutomation();
displayAction("MOTION", pirMotionDetected ? "ON" : "OFF");
break;
case '6':
// Display temperature and humidity data
displayTemperatureHumidity(temperature, humidity);
break;
case 'B':
toggleDHTAutomation();
displayAction("THERMO", dhtAutomationEnabled ? "ON" : "OFF");
break;
case '7':
openCloseServo(curtainServo);
displayAction("BLINDS", curtainServo.read() == 0 ? "CLOSED" : "OPEN");
break;
case '8':
toggleVentShaft();
displayAction("VENT", ventShaftOpened ? "OPEN" : "CLOSED");
break;
case '9':
openDoor();
displayAction("DOOR", "OPEN");
delay(100); // Display "DOOR OPEN" for 5 seconds
displayAction("DOOR", "CLOSED");
break;
case 'C':
toggleCurtainAutomation();
displayAction("BLINDS", curtainAutomationEnabled ? "ON" : "OFF");
break;
}
}
// Automatic curtain control based on LDR readings
if (isDay) {
if (curtainAutomationEnabled) {
curtainServo.write(180); // Open curtain blinds during the day if automation is enabled
}
} else {
if (curtainAutomationEnabled) {
curtainServo.write(0); // Close curtain blinds during the night if automation is enabled
}
}
// Automatic control based on temperature and humidity
if (dhtAutomationEnabled) {
if (temperature > 1) {
digitalWrite(relay1Pin, LOW); // Activate fan
} else {
digitalWrite(relay1Pin, HIGH); // Deactivate fan
}
if (humidity > 8) {
ventShaftOpened = true;
ventServo.write(100); // Open ventilation shaft
digitalWrite(relay2Pin, LOW); // Activate ventilation fan
} else {
ventShaftOpened = false;
ventServo.write(11); // Close ventilation shaft
digitalWrite(relay2Pin, HIGH); // Deactivate ventilation fan
}
}
// Automatic control based on PIR motion detection
if (pirAutomationEnabled) {
if (pirMotionDetected) {
digitalWriteAll(light1Pins, 4, HIGH); // Turn on lights1
digitalWriteAll(light2Pins, 4, HIGH); // Turn on lights2
} else {
digitalWriteAll(light1Pins, 4, LOW); // Turn off lights1
digitalWriteAll(light2Pins, 4, LOW); // Turn off lights2
}
}
// Automatic control for light3 based on LDR readings
if (ldrValue >= ldrThreshold) {
digitalWriteAll(light3Pins, 4, HIGH); // Turn on lights3
} else {
digitalWriteAll(light3Pins, 4, LOW); // Turn off lights3
}
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
handleCard();
mfrc522.PICC_HaltA();
}
// Check if Serial data is available
if (Serial.available() > 0) {
char command = Serial.read();
// Validate the received command
if (command >= '1' && command <= '6') {
// Valid command received
if (command == '1') {
// Turn on the first set of LEDs
for (int i = 0; i < 4; i++) {
digitalWrite(light1Pins[i], HIGH);
}
} else if (command == '2') {
// Turn off the first set of LEDs
for (int i = 0; i < 4; i++) {
digitalWrite(light1Pins[i], LOW);
}
} else if (command == '3') {
// Turn on the second set of LEDs
for (int i = 0; i < 4; i++) {
digitalWrite(light2Pins[i], HIGH);
}
} else if (command == '4') {
// Turn off the second set of LEDs
for (int i = 0; i < 4; i++) {
digitalWrite(light2Pins[i], LOW);
}
} else if (command == '5') {
// Turn on the relay
digitalWrite(relay1Pin, LOW);
} else if (command == '6') {
// Turn off the relay
digitalWrite(relay1Pin, HIGH);
}
} else {
// Invalid command received, handle the error or ignore
Serial.println("Invalid command received");
}
}
}
void toggleLights(int pins[], int count) {
for (int i = 0; i < count; i++) {
digitalWrite(pins[i], !digitalRead(pins[i]));
}
}
void digitalWriteAll(int pins[], int count, int value) {
for (int i = 0; i < count; i++) {
digitalWrite(pins[i], value);
}
}
void toggleRelay(int pin) {
digitalWrite(pin, !digitalRead(pin));
}
void toggleVentShaft() {
ventShaftOpened = !ventShaftOpened;
if (ventShaftOpened) {
ventServo.write(100); // Open ventilation shaft
digitalWrite(relay2Pin, LOW); // Activate ventilation fan
} else {
ventServo.write(11); // Close ventilation shaft
digitalWrite(relay2Pin, HIGH); // Deactivate ventilation fan
}
}
void openCloseServo(Servo &servo) {
if (servo.read() == 0) {
servo.write(80);
} else {
servo.write(0);
}
delay(500);
}
void openDoor() {
doorServo.write(0);
delay(5000); // Keep the door open for 5 seconds
doorServo.write(90);
}
void toggleDHTAutomation() {
dhtAutomationEnabled = !dhtAutomationEnabled;
Serial.print("DHT Automation: ");
Serial.println(dhtAutomationEnabled ? "Enabled" : "Disabled");
if (!dhtAutomationEnabled) {
digitalWrite(relay1Pin, HIGH); // Deactivate fan
ventShaftOpened = false;
ventServo.write(0); // Close ventilation shaft
digitalWrite(relay2Pin, HIGH); // Deactivate ventilation fan
}
}
void toggleCurtainAutomation() {
curtainAutomationEnabled = !curtainAutomationEnabled;
Serial.print("Curtain Automation: ");
Serial.println(curtainAutomationEnabled ? "Enabled" : "Disabled");
if (curtainAutomationEnabled) {
curtainServo.write(0); // Ensure curtain blinds are open during automation
}
}
void togglePIRAutomation() {
pirAutomationEnabled = !pirAutomationEnabled;
Serial.print("PIR Automation: ");
Serial.println(pirAutomationEnabled ? "Enabled" : "Disabled");
if (!pirAutomationEnabled) {
digitalWriteAll(light1Pins, 4, LOW); // Turn off lights1
digitalWriteAll(light2Pins, 4, LOW); // Turn off lights2
}
}
void displayAction(const char *action, const char *status) {
display.clearDisplay();
display.setTextSize(2); // Increase text size
display.setTextColor(SSD1306_WHITE);
int centerX = (SCREEN_WIDTH - strlen(action) * 12) / 2; // Calculate center position
int centerY = (SCREEN_HEIGHT - 24) / 2; // Center vertically
display.setCursor(centerX, centerY);
display.println(action);
centerY += 24; // Move down for status
centerX = (SCREEN_WIDTH - strlen(status) * 12) / 2; // Recalculate center position
display.setCursor(centerX, centerY);
// Display "ON" or "OFF" based on the status
if (strcmp(action, "MOTION") == 0) {
display.println(pirAutomationEnabled ? "ON" : "OFF");
} else {
display.println(status);
}
display.display();
delay(2000); // Display action for 2 seconds
display.clearDisplay();
display.display();
}
void displayTemperatureHumidity(float temperature, float humidity) {
display.clearDisplay();
display.setTextSize(2); // Increase text size to 2
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("TEMP:");
display.print(temperature); // Display temperature after "TEMP:"
display.setCursor(0, 30); // Increase vertical spacing
display.print("HUM:");
display.print(humidity); // Display humidity after "HUM:"
display.display();
delay(3000); // Display for 3 seconds
display.clearDisplay();
display.display();
}
// Handle RFID card detection
void handleCard() {
// Check card acceptance and perform respective actions
checkCardAcceptance() ? performCardAcceptedActions() : performCardDeclinedActions();
delay(1000);
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
}
// Check if card is accepted based on known UIDs
bool checkCardAcceptance() {
for (byte i = 0; i < sizeof(knownUID) / sizeof(knownUID[0]); i++) {
if (memcmp(mfrc522.uid.uidByte, knownUID[i], mfrc522.uid.size) == 0) {
return true;
}
}
return false;
}
// Perform actions when card is accepted
void performCardAcceptedActions() {
declineCount = 0;
blinkLED(GREEN_LED_PIN, greenLedBlinks); // Blink green LED
openDoor(); // Open the door
}
// Perform actions when card is declined
void performCardDeclinedActions() {
declineCount++;
if (declineCount >= maxDeclineCount) {
digitalWrite(BUZZER_PIN, HIGH);
buzzerStartTime = millis();
// Blink red LED while buzzer is active
while (millis() - buzzerStartTime <= buzzerDuration) {
digitalWrite(RED_LED_PIN, HIGH);
delay(300);
digitalWrite(RED_LED_PIN, LOW);
delay(300);
}
digitalWrite(BUZZER_PIN, LOW);
declineCount = 0;
} else {
blinkLED(RED_LED_PIN, redLedBlinks); // Blink red LED
}
}
// Blink an LED a specified number of times
void blinkLED(int pin, int numBlinks) {
for (int i = 0; i < numBlinks; i++) {
digitalWrite(pin, HIGH);
delay(300);
digitalWrite(pin, LOW);
delay(300);
}
}