#include <Arduino.h>
// #include "DYPlayerArduino.h"
// #include <SoftwareSerial.h>
#define PIR_PIN 3 // PIR sensor input pin
#define BULB_PIN 5 // PWM pin for MOSFET/bulb control
#define MP3_RX 10 // SoftwareSerial RX for MP3
#define MP3_TX 11 // SoftwareSerial TX for MP3
// Initialise on software serial port.
// SoftwareSerial mySerial(MP3_RX, MP3_TX); // RX, TX
// DY::Player player(&mySerial);
// =========== INIT Conditions ================
const unsigned long INIT_DURATION = 10 * 1000UL; // 60 seconds
int INIT_LED_ON_TIME = 500; // LED On time (in milliseconds) during flashing at INIT state
int INIT_LED_OFF_TIME = 3000; // LED Off time (in milliseconds) during flashing at INIT state
// =========== READY Conditions ===============
unsigned long flashInterval = 10 * 1000UL; // LED Flash Interval during Ready state
const int readyLedOnTime = 500; // For how long the led needs to be on during Ready flashing
unsigned long lastLedToggleTime = millis() - INIT_LED_OFF_TIME - 20; // note last time led has toggled
// =========== CoolDown Condition =============
const unsigned long COOLDOWN_DURATION = 30 * 1000UL; // 2 minutes
unsigned long TRIGGER_LED_ON_TIME = 20 * 1000UL; // LED On time when PIR triggered
const int volume = 25; // Set mp3 volume from 1-30
enum State { INIT,
READY,
TRIGGERED }; // System states
State currentState = INIT; // Start in INIT
unsigned long initStartTime; // Timestamp for init start
unsigned long fadeStartTime; // Timestamp for fade start
unsigned long cooldownEndTime; // Timestamp for cooldown end
bool triggerLedOff = false; // flag to turn off led when pir triggered after the specified time pass
bool fullBrightness = false; // flag to check if light is on full brightness
int brightness = 0;
void setup() {
// player.begin();
// Also initiate the hardware serial port so we can use it for debug printing
// to the console..
Serial.begin(9600);
// player.setVolume(volume); // 50% Volume Set volume from 0-30
pinMode(PIR_PIN, INPUT_PULLUP); // PIR as input
pinMode(BULB_PIN, OUTPUT); // Bulb PWM as output
digitalWrite(BULB_PIN, LOW); // Start bulb off
initStartTime = millis(); // Record init start time
Serial.println("Perform Initialization");
}
void loop() {
switch (currentState) {
case INIT:
{
doInitSequence();
}
break;
case READY:
// Steady 50%, wait for PIR trigger
if (digitalRead(PIR_PIN) == HIGH) {
currentState = TRIGGERED;
fadeStartTime = millis(); // Start fade timer
cooldownEndTime = millis() + COOLDOWN_DURATION; // Initial cooldown
// player.playSpecified(1); //Play specified file
Serial.println("Play Mp3");
}
// Indicate led is in ready mode
if ((millis() - lastLedToggleTime) > flashInterval) {
Serial.println("flash led once to indicate Redy mode");
lastLedToggleTime = millis(); //Note current time
digitalWrite(BULB_PIN, HIGH);
delay(readyLedOnTime);
digitalWrite(BULB_PIN, LOW); // Turn off led
}
break;
case TRIGGERED:
{
if (fullBrightness == false) {
Serial.println("Set brightness to FULL");
digitalWrite(BULB_PIN, HIGH);
Serial.print("Full Brightness:");
Serial.println(brightness);
fullBrightness = true;
triggerLedOff = false; // Flag to be checked to turn off led after the time finish
}
}
if (!triggerLedOff && (millis() - fadeStartTime) > TRIGGER_LED_ON_TIME) {
digitalWrite(BULB_PIN, LOW); // Turn off led
triggerLedOff = true; // Set the flag to indicate led is now off
}
// Check if cooldown expired (2 min since last movement)
if (millis() >= cooldownEndTime) {
// Flash once: Brief off (200ms)
Serial.println("Cooldown Expired get back to ready state");
flashBulb(); // Flash bulb
digitalWrite(BULB_PIN, LOW);
Serial.println("Get back to Ready State");
fullBrightness = false;
currentState = READY; // Back to READY
}
break;
}
}
void flashBulb() {
// Flash bulb 2 times at 50% brightness
Serial.println("Flash led 2 times");
for (int i = 0; i < 2; i++) {
digitalWrite(BULB_PIN, HIGH); // Set to READY Brightness
delay(300); // Turn on bulb for 300ms
digitalWrite(BULB_PIN, LOW); // Turn off bulb
delay(500); // Keep bulb off for 500ms
}
lastLedToggleTime = millis(); // Note current time when led has been toggled
}
void doInitSequence() {
unsigned long elapsed = millis() - initStartTime;
bool ledState = false; //Hold led state
while (elapsed < INIT_DURATION) {
elapsed = millis() - initStartTime;
if (elapsed >= INIT_DURATION) {
currentState = READY;
Serial.println("Init Complete");
digitalWrite(BULB_PIN, LOW); // Turn off bulb
delay(500); // wait for 500 milliseconds
//Flash Bulb 2 times
flashBulb();
break;
}
if (ledState && (millis() - lastLedToggleTime) > INIT_LED_ON_TIME) {
Serial.println("turn off led init");
ledState = false; // Reset led state
lastLedToggleTime = millis(); // Note current time
digitalWrite(BULB_PIN, LOW); // Turn off led
} else if (!ledState && (millis() - lastLedToggleTime) > INIT_LED_OFF_TIME) {
Serial.println("turn on led init");
ledState = true; // set led state
lastLedToggleTime = millis(); // Note current time
digitalWrite(BULB_PIN, HIGH); // Set led state at INIT Brightness
}
delay(10); // wait for small duration
}
}