int ledPin = 26;
int pirPin = 27;
int mode = 0; // 0=NORMAL, 1=NIGHT, 2=AWAY
unsigned long lastMotionTime = 0;
const int delayTime = 5000;
bool ledState = false;
bool lastPIRState = LOW; // PIR starts LOW (no motion)
String command = "";
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT); // PIR drives its own signal, no pullup needed
Serial.begin(9600);
Serial.println("Mode: NORMAL"); // print initial mode
}
void loop() {
// ---- SERIAL COMMAND HANDLING ----
if (Serial.available()) {
command = Serial.readStringUntil('\n');
command.trim();
if (command == "ON") {
if (mode == 0) {
ledState = true;
Serial.println("App: Light ON");
} else {
Serial.println("ON command ignored (not in NORMAL mode)");
}
}
else if (command == "OFF") {
if (mode == 0) {
ledState = false;
Serial.println("App: Light OFF");
} else {
Serial.println("OFF command ignored (not in NORMAL mode)");
}
}
else if (command == "NORMAL") {
mode = 0;
ledState = false;
Serial.println("Mode: NORMAL");
}
else if (command == "NIGHT") {
mode = 1;
ledState = false;
lastMotionTime = 0;
Serial.println("Mode: NIGHT");
}
else if (command == "AWAY") {
mode = 2;
ledState = false;
Serial.println("Mode: AWAY");
}
command = "";
}
// ---- MODE LOGIC ----
if (mode == 0) {
// NORMAL: LED controlled only by serial ON/OFF
}
else if (mode == 1) {
// NIGHT: PIR triggers LED for 5 seconds
int currentPIRState = digitalRead(pirPin);
// Detect rising edge (PIR goes HIGH when motion detected)
if (lastPIRState == LOW && currentPIRState == HIGH) {
ledState = true;
lastMotionTime = millis();
Serial.println("Motion detected -> ON");
}
lastPIRState = currentPIRState;
// Auto OFF after 5 seconds
if (ledState == true && millis() - lastMotionTime >= delayTime) {
ledState = false;
Serial.println("No motion -> OFF");
}
}
else if (mode == 2) {
// AWAY: always OFF, no exceptions
ledState = false;
}
digitalWrite(ledPin, ledState);
}