//Medicine Reminder using Arduino Uno
// Reminds to take medicine at 8am, 2pm, 8pm 

#include <Wire.h>
#include <RTClib.h>
//#include <EEPROM.h>
#include <SPI.h>
#include <Servo.h>

RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int pushVal = 1;                           
int val;
int val2;
int addr = 0;
int addrt = 1;
int nmed_t;
int med_tray = 0;
int posn = 0;  

int blinked8am = 0;
int blinked2pm = 0;
int blinked8pm = 0;

Servo servo1;  // create servo object to control
Servo servo2;
Servo servo3;

int pushpressed = 0;
const int ledPin =  3;                       // buzzer and led pin
int ledState = LOW;
int Signal = 0;
int buzz = 2;                                      
int push1state, push2state, push3state, stopinState = 0;     //              // push button flags 
int push1pin = 7;
int push2pin = 6;
int push3pin = 5;
int stopPin  = 4;

long previousMillis = 0;           
long interval = 700;                   // buzzing interval
unsigned long currentMillis;

//   Set Reminder Change Time
int buzz8amHH = 8;          //    HH - hours         ##Set these for reminder time in 24hr Format 
int buzz8amMM = 00;          //    MM - Minute
int buzz8amSS = 00;          //    SS - Seconds
int buzz2pmHH = 8;          //    HH - hours
int buzz2pmMM = 6;          //    MM - Minute
int buzz2pmSS = 00;          //    SS - Seconds
int buzz8pmHH = 10;          //    HH - hours
int buzz8pmMM = 00;          //    MM - Minute
int buzz8pmSS = 00;          //    SS - Seconds 
int nowHr, nowMin, nowSec;                     // to show current mm,hh,ss

void servo_move(int &med_ti) { 

  Serial.print("med_tray inside fun =");Serial.println(med_ti);

  if (med_ti == 1){ 
  servo1.write(0);
  delay(2000);
  servo1.write(90);
  delay(2000);
  servo1.write(0);
  //nmed_ti = med_ti +1;
  //if (nmed_ti == 7) {
  //  nmed_ti = 1;
  //}
  delay(10);
  }

  if (med_ti == 2){ 
  servo2.write(0);
  delay(2000);
  servo2.write(90);
  delay(2000);
  servo2.write(0);
  //nmed_ti = med_ti +1;
  //if (nmed_ti == 7) {
  //  nmed_ti = 1;
  //}
  delay(10);
  }
  if (med_ti == 3){ 
  servo3.write(0);
  delay(2000);
  servo3.write(90);
  delay(2000);
  servo3.write(0);
  //nmed_ti = med_ti +1;
  //if (nmed_ti == 7) {
  //  nmed_ti = 1;
  //}
  delay(10);
  }
}

void display_time() {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print("0");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print("0");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
Serial.println();
delay(1000);
}

void setup() {
  Serial.begin(9600);
  // initial servo condition;
 servo1.attach(13);  // (pin)
 servo2.attach(12);  // (pin)
 servo3.attach(11);  // (pin)
 servo1.write(0);
 servo2.write(0);
 servo3.write(0);
 // RTC init;
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
  }  
    rtc.adjust(DateTime(2014, 1, 21, 7, 59, 00));
  
  delay(4000);
 
  pinMode(push1pin, INPUT);                                    // define push button pins type
  pinMode(push2pin, INPUT);
  pinMode(push3pin, INPUT);
  pinMode(stopPin, INPUT);
  pinMode(ledPin, OUTPUT);
  delay(200);

// Serial.println(EEPROM.read(addr));

display_time();

  //val2 = EEPROM.read(addr);                         // read previosuly saved value of push button to start from where it was left previously
  val2 = 3;
  switch (val2) {
    case 1:
      Serial.println("Set for 1/day");
      push1state = 0;
      push2state = 1;
      push3state = 1;
      pushVal = 1;
      break;
    case 2:
      Serial.println("Set for 2/day");
      push1state = 1;
      push2state = 0;
      push3state = 1;
      pushVal = 2;
      break;
    case 3:
      Serial.println("Set for 3/day");
      push1state = 1;
      push2state = 1;
      push3state = 0;
      pushVal = 3;
      break;
  }
}

void loop() {
  push1();                                             //call to set once/day 
  push2();                                             //call to set twice/day 
  push3();                                             //call to set thrice/day 
    if (pushVal == 1) {                                // if push button 1 pressed then remind at 8am
    at8am();
                                                       //function to start uzzing at 8am 
  }
  else if (pushVal == 2) {                             // if push button 2 pressed then remind at 8am and 8pm
    at8am();                                            
    at8pm();                                           //function to start uzzing at 8mm
  }
  else if (pushVal == 3) {                             // if push button 3 pressed then remind at 8am and 8pm
    Serial.print("blinkstat8a = ");Serial.println(blinked8am);
    Serial.print("blinkstat2p = ");Serial.println(blinked2pm);
    Serial.print("blinkstat8p = ");Serial.println(blinked8pm);


    if (blinked8am == 1 && blinked2pm ==0 && blinked8pm ==0 ) {
    at8am();
    }
    if (blinked2pm ==1 && blinked8am ==0 && blinked8pm ==0  ) {
    at2pm();  
    }  
    if (blinked8pm ==1 && blinked2pm ==0 && blinked8am ==0  ) {                                           //function to start uzzing at 8mm
    at8pm();
    }
    if ( blinked8pm ==0 && blinked2pm ==0 && blinked8am ==0    )
     {
      at8am();
      at2pm();
      at8pm();
    }
  }
  
  //currentMillisLED = millis();                         // start millis for LCD screen switching at defined interval of time
  push1state = digitalRead(push1pin);                  // start reading all push button pins
  push2state = digitalRead(push2pin);
  push3state = digitalRead(push3pin);
  stopinState = digitalRead(stopPin);
  Serial.print(" Stop state before fun stop"); Serial.println(stopinState);
  stopPins(pushpressed,blinked8am,blinked2pm,blinked8pm);                                            // call to stop buzzing
  //changeScreen();                                        // screen cycle function
}

// push buttons

void push1() {                   // function to set reminder once/day 
  if (push1state == 0) {
    push1state = 1;
    push2state = 1;
    push3state = 1;
//    pushPressed = true;
    //EEPROM.write(addr, 1);
    Serial.print("Push1 Written : ");// Serial.println(EEPROM.read(addr));  // for debugging
    pushVal = 1;                                             //save the state of push button-1 
    //display.clearDisplay();   
    //display.setCursor(0, 0);  
    Serial.print("Reminder set");
    Serial.println("Reminder set for Once/day !");
    //display.display();
    delay(1200);
    //display.clearDisplay();
  }
}

void push2() {                      //function to set reminder twice/day
  if (push2state == 0) {
    push2state = 1;
    push1state = 1;
    push3state = 1;
//    pushPressed = true;
    //EEPROM.write(addr, 2);
    Serial.print("Push2 Written : ");// Serial.println(EEPROM.read(addr));
    pushVal = 2;
    //display.clearDisplay();
    //display.setCursor(0, 0);
    //display.print("Reminder set");
    Serial.println("Reminder set for Twice/day !");
    //display.display();
    delay(1200);
    //display.clearDisplay();
  }
}

void push3() {                    //function to set reminder thrice/day
  if (push3state == 0) {
    push3state = 1;
    push1state = 1;
    push2state = 1;
//    pushPressed = true;
    //EEPROM.write(addr, 3);
    Serial.print("Push3 Written : "); //Serial.println(EEPROM.read(addr));
    pushVal = 3;
    //display.clearDisplay();
    //display.setCursor(0, 0);
    //display.print("Reminder set");
    Serial.println("Reminder set for Thrice/day !");
    //display.display();
    delay(1200);
    //display.clearDisplay();
  }
}

void stopPins(int pushpressedi,int &blinked8ami,int &blinked2pmi,int &blinked8pmi) {                   //function to stop buzzing when user pushes stop push button
  if (stopinState == 0) {
//    stopinState = 0;
//    pushPressed = true;   
    pushpressedi = 1;
    blinked8ami = 0;
    blinked2pmi = 0;
    blinked8pmi = 0;
    //display.clearDisplay();
    //display.setCursor(0, 0);
    //display.print("Take Medicine");
    //display.println("with Warm Water");
    //display.display();
    servo_move(med_tray);
    //med_tray = nmed_t;
    //delay(1200);
    //display.clearDisplay();
  }
}

void startBuzz_1(int &blinked8amii,int &blinked2pmii,int &blinked8pmii) {                 // function to start buzzing when time reaches to defined interval
//  if (pushPressed == false) {
 if (pushpressed == 0 && med_tray == 1) {
    Serial.println("pushpressed is false in blink");
    blinked8amii = 1;
    blinked2pmii = 0;
    blinked8pmii = 0;
    // servo moved and disable.
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;         // save the last time you blinked the LED
      Serial.println("Start Buzzing");
      //ledState = HIGH;
      if (ledState == LOW) {                  // if the LED is off turn it on and vice-versa:
        ledState = HIGH;
      }  else {
        ledState = LOW;
      }
      digitalWrite(ledPin, ledState);
      //delay(5000);
      //ledState = LOW;
    }
  }
  else if (pushpressed == 1) {
    Serial.println("pushpressed is true");
    ledState = LOW;
    digitalWrite(ledPin, ledState);
    // enable servo here;
  }
}

void startBuzz_2(int &blinked8amjj,int &blinked2pmjj,int &blinked8pmjj) {              // function to start buzzing when time reaches to defined interval
//  if (pushPressed == false) {
 if (pushpressed == 0 && med_tray == 2) {
    Serial.println("pushpressed is false in blink");
     blinked8amjj = 0;
    blinked2pmjj = 1;
    blinked8pmjj = 0;
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;         // save the last time you blinked the LED
      Serial.println("Start Buzzing");
      if (ledState == LOW) {                  // if the LED is off turn it on and vice-versa:
        ledState = HIGH;
      }  else {
        ledState = LOW;
      }
      digitalWrite(ledPin, ledState);
    }
  }
  else if (pushpressed == 1) {
    Serial.println("pushpressed is true");
    ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

void startBuzz_3(int &blinked8amkk,int &blinked2pmkk,int &blinked8pmkk ) {                    // function to start buzzing when time reaches to defined interval
//  if (pushPressed == false) {
 if (pushpressed == 0 && med_tray == 3) {
    Serial.println("pushpressed is false in blink");
    blinked8amkk = 0;
    blinked2pmkk = 0;
    blinked8pmkk = 1;
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;         // save the last time you blinked the LED
      Serial.println("Start Buzzing");
      blinked8pm  = 1;
      if (ledState == LOW) {                  // if the LED is off turn it on and vice-versa:
        ledState = HIGH;
      }  else {
        ledState = LOW;
      }
      digitalWrite(ledPin, ledState);
    }
  }
  else if (pushpressed == 1) {
    Serial.println("pushpressed is true");
    ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

void at8am() {                      // function to start buzzing at 8am
  DateTime now = rtc.now();
  if (int(now.hour()) == buzz8amHH) {
    if (int(now.minute()) == buzz8amMM) {
      if (int(now.second()) > buzz8amSS) {
        /////////////////////////////////////////////////////
        med_tray = 1;
        startBuzz_1(blinked8am,blinked2pm,blinked8pm);        
        /////////////////////////////////////////////////////
      }
      else {
        pushpressed = 0;
        med_tray =0;
        Serial.print("med_tray11 =  ");Serial.println(med_tray);
        Serial.print("pushpressed updated =");Serial.println(pushpressed);
        display_time();
      }
    }
    else {
      pushpressed =0;
      med_tray =0;
      Serial.print("med_tray12 =  ");Serial.println(med_tray);
      Serial.print("pushpressed updated =");Serial.println(pushpressed);
      display_time();
    }
  }
  else {
    pushpressed =0;
    med_tray =0;
    Serial.print("med_tray13 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
  }
}

void at2pm() {                          // function to start buzzing at 2pm
  DateTime now = rtc.now();
  if (int(now.hour()) == buzz2pmHH) {
    if (int(now.minute()) == buzz2pmMM) {
      if (int(now.second()) > buzz2pmSS) {      
        ///////////////////////////////////////////////////
        med_tray = 2;
        startBuzz_2(blinked8am,blinked2pm,blinked8pm);
        //////////////////////////////////////////////////
      }
      else {
        pushpressed = 0;
        med_tray =0;
            Serial.print("med_tray21 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
      }
    }
    else {
        pushpressed = 0;
        med_tray =0;
            Serial.print("med_tray22 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
      }
  }
  else {
        pushpressed = 0;
        med_tray =0;
            Serial.print("med_tray23 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
      }
}

void at8pm() {                           // function to start buzzing at 8pm
  DateTime now = rtc.now();
  if (int(now.hour()) == buzz8pmHH) {
    if (int(now.minute()) == buzz8pmMM) {
      if (int(now.second()) > buzz8pmSS) {
        
        /////////////////////////////////////////////////////
        med_tray = 3;
        startBuzz_3(blinked8am,blinked2pm,blinked8pm);
        /////////////////////////////////////////////////////
      }
      else {
        pushpressed = 0;
        med_tray =0;
            Serial.print("med_tray31 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
      }
    }
    else {
        pushpressed = 0;
        med_tray =0;
            Serial.print("med_tray32 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
      }
  }
  else {
        pushpressed = 0;
        med_tray =0;
            Serial.print("med_tray33 =  ");Serial.println(med_tray);
    Serial.print("pushpressed updated =");Serial.println(pushpressed);
    display_time();
      }
}

//end --------------------------------------------------*
GND5VSDASCLSQWRTCDS1307+