#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// Software SPI pins (matching your circuit)
#define TFT_CS 6
#define TFT_RST 7
#define TFT_DC 8
#define TFT_MOSI 9
#define TFT_MISO 11 // MISO on pin 11
#define TFT_SCLK 10 // SCK on pin 10
// Create display object with software SPI
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST, TFT_MISO);
// Other pins
#define PIR_PIN 3
#define BUZZER_PIN 2
#define RED_LED 4
#define GREEN_LED 5
bool motionDetected = false;
unsigned long lastMotionTime = 0;
void setup() {
Serial.begin(9600);
Serial.println("Starting System...");
// Initialize pins
pinMode(PIR_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
// Turn off all outputs initially
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(BUZZER_PIN, LOW);
// Initialize TFT
Serial.println("Initializing TFT...");
tft.begin();
// Test if display is working by drawing something
tft.setRotation(3); // Try different rotations: 0, 1, 2, 3
tft.fillScreen(ILI9341_BLACK);
// Test display with simple shapes
tft.fillRect(0, 0, 320, 40, ILI9341_RED);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(20, 10);
tft.println("Security System");
delay(2000);
// Draw main interface
drawInterface();
Serial.println("System Ready!");
}
void loop() {
unsigned long currentTime = millis();
// Read PIR sensor
int pirState = digitalRead(PIR_PIN);
// Motion detection with debounce
if (pirState == HIGH && !motionDetected &&
(currentTime - lastMotionTime) > 1000) {
motionDetected = true;
lastMotionTime = currentTime;
motionTriggered();
}
else if (pirState == LOW && motionDetected &&
(currentTime - lastMotionTime) > 1000) {
motionDetected = false;
motionCleared();
}
// Update time on display every second
static unsigned long lastUpdate = 0;
if (currentTime - lastUpdate > 1000) {
updateTime();
lastUpdate = currentTime;
}
}
void motionTriggered() {
Serial.println("MOTION DETECTED!");
// Buzzer pattern
for(int i = 0; i < 3; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
// Update display
drawStatus();
}
void motionCleared() {
Serial.println("Motion cleared");
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, HIGH);
// Update display
drawStatus();
}
void drawInterface() {
tft.fillScreen(ILI9341_BLACK);
// Title bar
tft.fillRect(0, 0, 320, 40, ILI9341_BLUE);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.println("Security System");
// Status box
tft.drawRect(10, 50, 300, 80, ILI9341_WHITE);
tft.setTextSize(1);
tft.setCursor(20, 60);
tft.println("STATUS:");
drawStatus();
// Info panel
tft.drawRect(10, 140, 300, 100, ILI9341_WHITE);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.setCursor(20, 150);
tft.println("SYSTEM INFO:");
tft.setCursor(20, 170);
tft.print("PIR Sensor: ");
tft.print(motionDetected ? "ACTIVE" : "STANDBY");
// Visual indicator
if (motionDetected) {
tft.fillCircle(290, 235, 8, ILI9341_RED);
} else {
tft.fillCircle(290, 235, 8, ILI9341_GREEN);
}
}
void drawStatus() {
// Clear status area
tft.fillRect(20, 80, 280, 40, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(20, 85);
if (motionDetected) {
tft.setTextColor(ILI9341_RED);
tft.println("ALERT! MOTION");
} else {
tft.setTextColor(ILI9341_GREEN);
tft.println("SYSTEM READY");
}
}
void updateTime() {
// Clear time area
tft.fillRect(20, 190, 280, 20, ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.setCursor(20, 190);
tft.print("Uptime: ");
tft.print(millis() / 1000);
tft.println(" sec");
}