// Include Libraries
#include "Arduino.h"
#include "Buzzer.h"
#include "PIR.h"
#include "Relay.h"

///// Variables //////
unsigned long CurrentTime;                                    // time elapsed in millis since the Arduino was powered
unsigned long TimeFlag1000 = 0;                               // time counter for 1 second
unsigned long lastDetectTime = 0;                             // Time of last PIR sensor detection
unsigned long DownTime = 0;                                   // amount of time elapsed since the last detection
unsigned long TimeBuzzEnd = 10;                               // (in seconds) time for the buzzer to be turned OFF after TimeBuzzStart to avoid having it powered on forever
unsigned long DownTimeShutdown = 360;  // TEST: 30 - STD: 360 // (in seconds) maximum time allowed until relay will power everything off. I've put 6 min to ensure the printer cools down on it's own before powering it of, as the fans help on cooling.
unsigned long TimeBuzzStart = 60;     // TEST: 15 - STD: 60   // (in seconds) time for the buzzer to be turned ON after no movement is detected
unsigned long DownTimeLed = 30;       // TEST: 10 - STD: 30   // (in seconds) time for the red LED to be turned ON after no movement is detected (Added this to avoid intermitent detections from the PIR sensor)

boolean f_1s = false;                 // flag for 1 second scan frequency

int SwRel;                            // indicates the status of the relay switch (0 = OFF, 1 = ON)
int SwBuzz;                           // indicates the status of the buzzer switch (0 = OFF, 1 = ON)
int pirState = 0;                     // indicates the status of the PIR sensor (0 = no movement detected, 1 = movement detected)

//Arduino pins used
int pinSwBuzz = 12;                   // Buzzer switch
int pinSwRel = 11;                    // Relay switch
int pinLedY = 10;                     // Yellow led pin, will be powered on while the buzzer switch is on
int pinLedR = 9;                      // Red led pin, will be powered on when there's no movement detection
int pinLedG = 8;                      // Green led pin, will be powered on while the Relay switch is on
int pinPir = 7;                       // PIR sensor output pin
int pinRelay = 6;                     // printer to control the relay
int pinBuzz = 5;                      // Buzzer pin

void setup() {
  pinMode(pinSwRel, INPUT_PULLUP);
  pinMode(pinSwBuzz, INPUT_PULLUP);
  pinMode(pinLedR, OUTPUT);
  pinMode(pinLedG, OUTPUT);
  pinMode(pinLedY, OUTPUT);
  pinMode(pinBuzz, OUTPUT);
  pinMode(pinPir, INPUT);
  pinMode(pinRelay, OUTPUT);
  Serial.begin(9600);  // per llegir a la pantalla
  digitalWrite(pinRelay, LOW);
}

void loop() {
CurrentTime = millis ();
pirState = digitalRead(pinPir);
SwRel = !digitalRead(pinSwRel);       //My switch was giving the opposite result than expected, that's why I invert the read.
SwBuzz = !digitalRead(pinSwBuzz);     //My switch was giving the opposite result than expected, that's why I invert the read.

  if ((CurrentTime -  TimeFlag1000) >= 1000) {
    TimeFlag1000 = CurrentTime;
    f_1s = true;
  }
  
  if (f_1s == true){
    f_1s = false;
    
    if (pirState == HIGH) {
    lastDetectTime = CurrentTime;   // Update last detection time
    DownTime = 0;
    digitalWrite(pinLedR, LOW);
    digitalWrite(pinBuzz, LOW);
  }
    else {
    DownTime = (CurrentTime - lastDetectTime) / 1000;  // Calculate time since last detection
  }

  if ((SwBuzz == true) and ((DownTime >= TimeBuzzStart) and (DownTime < TimeBuzzStart + TimeBuzzEnd))){
    digitalWrite(pinBuzz, !digitalRead (pinBuzz));
  }
  else digitalWrite(pinBuzz, LOW);
  }
  
  if (SwRel == true) {
    //digitalWrite(pinLedG, HIGH);
    if (DownTime >= DownTimeShutdown){
      digitalWrite(pinRelay, HIGH);
    }
  //else digitalWrite(pinLedG, LOW);
  }
  if (DownTime > DownTimeLed) digitalWrite(pinLedR, HIGH);
  if (SwBuzz == true) digitalWrite(pinLedY, HIGH); else digitalWrite(pinLedY, LOW);
  if (SwRel == true) digitalWrite(pinLedG, HIGH); else digitalWrite(pinLedG, LOW);
}
