// relay control board with rise and fall activate
#include "Wire.h"
#include "EEPROM.h"
#include "SPI.h"
#include "Servo.h"
#include "RTClib.h"

Servo servo1;                          // create servo object to control a servo
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int posn = 0;                            // variable to store the servo position                         
int val;
int med_tray;
int relay_trig =0;
int servo_num = 0;
      
const int ledPin =  4;                       // buzzer and led pin
int ledState = LOW;
int Signal = 0;
int buzzpin = 5;
int toneuse = 1000;
int tonelow = 1000;
int tonehigh = 2500; 
const int Keyin = 6;  
int Key_buff;

const byte interruptPin1 = 2;  
const byte interruptPin2 = 3;
const byte interruptPin3 = 18;
//const byte interruptPin4 = 19;

//bool fHasLooped  = true;
const int LEDpin = 12;
int LEDState =LOW;
int pushpressed = 1;
long previousMillis = 0;           
long interval = 700;                  
unsigned long currentMillis;
long previousMillisLED = 0;    
long intervalLED = 3000;          
unsigned long currentMillisLED;
int Alarm_flag = 0;

int MornHH = 6;           //    HH - hours         
int MornMM = 00;          //    MM - Minute
int EndmornHH = 9;       //    HH - hours
int EndmornMM = 00;       //    MM - Minute
int LunchHH = 11;         //    HH - hours
int LunchSS = 00;         //    MM - Minute
int EndlunchHH = 15;      //    HH - hours
int EndlunchMM = 00;      //    MM - Minute
int EvenHH = 16;          //    HH - hours 
int EvenMM = 00;          //    MM - Minute       
int EndevenHH = 23;       //    HH - hours
int EndevenMM = 00;       //    MM - Minute 
int buzz2pm2HH = 23;      //    HH - hours
int buzz2pm2MM = 00;      //    MM - Minute
int buzz2pm2SS = 24;      //    HH - hours
int buzz8pm2HH = 00;      //    MM - Minute

void servo_move(int &ser_trig,int &ser_num) {
  Serial.print("trig stage");Serial.println(ser_trig);
  Serial.print("tray in is");Serial.println(ser_num);
  if (ser_trig ==1 && ser_num == 1){ 
  servo1.write(0);
  servo3.write(0); 
  delay(2000);
  servo1.write(90);
  servo3.write(90);
  delay(2000); 
  servo1.write(0);
  servo3.write(0);
  delay(10);
  ser_trig =0;
  ser_num =0;
  }
  if (ser_trig ==1 && ser_num == 2){ 
  servo2.write(0);
  servo5.write(0);
  delay(2000);
  servo2.write(90);
  servo5.write(90);
  delay(2000); 
  servo2.write(0);
  servo5.write(0);
  delay(10);
  ser_trig =0;
  ser_num=0;
  }
  if (ser_trig ==1 && ser_num == 3){ 
  servo3.write(0);
  servo6.write(0);
  delay(2000);
  servo3.write(90);
  servo6.write(90);
  delay(2000); 
  servo3.write(0);
  servo6.write(0);
  delay(10);
  ser_trig =0;
  ser_num =0;
  }
}

void setup() {
  Serial.begin(115200);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }
 //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));            // ตั้งเวลาจริงสำหรับการทำงาน
 // rtc.adjust(DateTime(2024, 2, 5, 7, 59, 30));                // ตั้งเวลาการจ่ายยาแบบแมน่วล 

  pinMode(ledPin, OUTPUT);
  pinMode(buzzpin, OUTPUT);
  pinMode(Keyin,INPUT);

  servo1.attach (10);
  servo2.attach (13);
  servo3.attach (9);
  servo4.attach (12);
  servo5.attach (8);
  servo6.attach (11);

  servo1.write(0);
  servo2.write(0);
  servo3.write(0);
  servo4.write(0);
  servo5.write(0);
  servo6.write(0);
}

void loop() {
time_show();
DateTime now = rtc.now();
Serial.print("Hour now ");Serial.println(int(now.hour()));
Serial.print("Hour set ");Serial.println(EndmornHH);
Serial.print("Hour set ");Serial.println(EndlunchHH);
Serial.print("Hour set ");Serial.println(EndevenHH);

if ( int(now.hour()) >= MornHH  && int(now.hour()) <= EndmornHH){
detachInterrupt(digitalPinToInterrupt(interruptPin2));
detachInterrupt(digitalPinToInterrupt(interruptPin3));
attachInterrupt(digitalPinToInterrupt(interruptPin1),start_buzz1, CHANGE);
}
if (int(now.hour()) >= LunchHH  && int(now.hour()) <= EndlunchHH){
detachInterrupt(digitalPinToInterrupt(interruptPin3));
detachInterrupt(digitalPinToInterrupt(interruptPin1));
attachInterrupt(digitalPinToInterrupt(interruptPin2),start_buzz2, CHANGE);
}
if (int(now.hour()) >= EvenHH  && int(now.hour()) <= EndevenHH){
detachInterrupt(digitalPinToInterrupt(interruptPin1));
detachInterrupt(digitalPinToInterrupt(interruptPin2));
attachInterrupt(digitalPinToInterrupt(interruptPin3),start_buzz3, CHANGE);
}
Serial.println("WAIT INTERRUPT FOR ACTION"); 
Serial.print("RELAY TRIGGER STAGE : ");Serial.println(relay_trig);
Serial.print("SERVO_NUM : ");Serial.println(servo_num);
     
    Key_buff = digitalRead(Keyin);  
    if (Key_buff == 0) {
      Alarm_flag = 0;
    }
    Serial.print("Alarm : ");Serial.println(Alarm_flag);
    Buzznblink();
    servo_move(relay_trig,servo_num); 
}

void start_buzz1() {
Serial.println("Interrupted1 "); 
  digitalWrite(ledPin, HIGH);                  //Switch ON RED LED
  relay_trig = 1;
  servo_num = 1;
  Alarm_flag =1;
}
void start_buzz2() {
Serial.println("Interrupted2 "); 
  digitalWrite(ledPin, HIGH);                  //Switch ON RED LED
  relay_trig = 1;
  servo_num = 2;
  Alarm_flag =1;
}
void start_buzz3() {
Serial.println("Interrupted3 "); 
  digitalWrite(ledPin, HIGH);                  //Switch ON RED LED
  relay_trig = 1;
  servo_num = 3;
  Alarm_flag =1;
}
}

void time_show() {
    DateTime now = rtc.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" ( ");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); // this line converts the day of the week number to the corresponding word from the list above
    Serial.print(" ) ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    delay (200);
  }

 void Buzznblink() {                    // function to start buzzing when time reaches to defined interval
 if (Alarm_flag == 1) {
    Serial.println("Alarm is true");
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;         // save the last time you blinked the LED
      Serial.println("Start Alarm");
      if (ledState == LOW) {                  // if the LED is off turn it on and vice-versa:
        ledState = HIGH;
        toneuse = tonehigh;
      }  else {
        ledState = LOW;
        toneuse = tonelow;
      }
      digitalWrite(ledPin, ledState);
      tone(buzzpin, toneuse);
    }
  }
  else if (Alarm_flag == 0) {
    Serial.println("Alarm false");
    ledState = LOW;
    digitalWrite(ledPin, ledState);
    noTone(buzzpin);
  }
}
GND5VSDASCLSQWRTCDS1307+