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

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <RTClib.h>
#include <EEPROM.h>
#include <SPI.h>
#include <Servo.h>

void servo_move() { 
Servo servo1;  // create servo object to control a servo1
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
servo1.attach(10,600,2300);  // (pin, min, max)
servo2.attach(13,600,2300);  // (pin, min, max)
servo3.attach(8,600,2300);  // (pin, min, max)
servo4.attach(12,600,2300);  // (pin, min, max)
servo5.attach(9,600,2300);  // (pin, min, max)
servo6.attach(11,600,2300);  // (pin, min, max)
}
int pushVal = 0;                           
int val;
int val2;
int addr = 0;
RTC_DS3231 rtc;
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1   //   QT-PY / XIAO
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define getWellsoon 0                                           
#define HELP_SCREEN 1
#define TIME_SCREEN 2

//bool pushPressed;                               //flag to keep track of push button state 
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;     // 
int push1Flag, push2Flag, Push3Flag = false;              // push button flags 
int push1pin = 7;
int push2pin = 6;
int push3pin = 5;
int stopPin  = 4;
int screens = 0;              // screen to show
int maxScreen = 2;            // screen count
bool isScreenChanged = true;
long previousMillis = 0;           
long interval = 500;                   // buzzing interval
unsigned long currentMillis;

long previousMillisLED = 0;    // for LED screen update
long intervalLED = 8000;          // Screen cycling interval
unsigned long currentMillisLED;

//   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 = 14;          //    HH - hours
int buzz2pmMM = 00;          //    MM - Minute
int buzz2pmSS = 00;          //    SS - Seconds
int buzz8pmHH = 20;          //    HH - hours
int buzz8pmMM = 00;          //    MM - Minute
int buzz8pmSS = 00;          //    SS - Seconds 
int nowHr, nowMin, nowSec;                     // to show current mm,hh,ss



// All messeges

void gwsMessege(){               // print get well soon messege
     oled.clearDisplay();
     oled.setTextSize(1);
     oled.setTextColor(WHITE);
     oled.setCursor(0, 0);
     oled.println("Stay Healthy");// Give some cheers
     oled.setCursor(0, 1);
     oled.println("Get Well Soon");// wish
     oled.display();
    //lcd.clear();
    //lcd.setCursor(0, 0);
    //lcd.print("Stay Healthy :)");     // Give some cheers
    //lcd.setCursor(0, 1);
    //lcd.print("Get Well Soon :)");    // wish 
}

void helpScreen() {              // function to display 1st screen in LCD
     oled.clearDisplay();
     oled.setTextSize(1);
     oled.setTextColor(WHITE);
     oled.setCursor(0, 0);
     oled.println("Press Button");
     oled.setCursor(0, 1);
     oled.println("For Reminder...!");
     oled.display();
    //lcd.clear();
    //lcd.setCursor(0, 0);
    //lcd.print("Press Buttons");
    //lcd.setCursor(0, 1);
    //lcd.print("for Reminder...!");    
 }

void timeScreen() {              // function to display Date and time in LED screen
  DateTime now = rtc.now();             // take rtc time and print in display
    //lcd.clear();
    oled.clearDisplay();
    oled.setTextSize(1);
    oled.setTextColor(WHITE);
    //lcd.setCursor(0, 0);
    oled.setCursor(0, 0);
    //lcd.print("Time:");
    oled.println("Time:");
    //lcd.setCursor(6, 0);
    oled.setCursor(6, 0);
    //lcd.print(nowHr = now.hour(), DEC);
    oled.println(nowHr = now.hour(), DEC);
    //lcd.print(":");
    oled.println(":");
    //lcd.print(nowMin = now.minute(), DEC);
    oled.println(nowMin = now.minute(), DEC);
    //lcd.print(":");
    oled.println(":");
    //lcd.print(nowSec = now.second(), DEC);
    oled.println(nowSec = now.second(), DEC);
    //lcd.setCursor(0, 1);
    oled.setCursor(0, 1);
    //lcd.print("Date: ");
    oled.println("Date: ");
    //lcd.print(now.day(), DEC);
    oled.println(now.day(), DEC);
    //lcd.print("/");
    oled.println("/");
    //lcd.print(now.month(), DEC);
    oled.println(now.month(), DEC);
    //lcd.print("/");
    oled.println("/");
    //lcd.print(now.year(), DEC);
    oled.println(now.year(), DEC);
    oled.display();
}

void setup() {
  Serial.begin(9600);

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.

  delay(250); // wait for the OLED to power up
  //display.begin(i2c_Address, true); // Address 0x3C default

  // initialize OLED display with address 0x3C for 128x64
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }

  oled.setTextSize(1);
  oled.setTextColor(WHITE);

 
  if (! rtc.begin()) {                      // check if rtc is connected 
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
  }

  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));            // uncomment this to set the current time and then comment in next upload when u set the time

  rtc.adjust(DateTime(2024, 1, 10, 7, 59, 30));                // manual time set
  //lcd.begin(16, 2);
  //lcd.clear();
  //lcd.setCursor(0, 0);
  oled.clearDisplay();
  oled.setTextSize(1);
  oled.setTextColor(WHITE);
  oled.setCursor(0, 0);
  oled.println("Welcome To");                                      // print a messege at startup
  oled.setCursor(0, 1);
  oled.println("Pills Alarm Box");
  oled.display();     
  delay(1000);

  pinMode(push1pin, INPUT_PULLUP);                                    // define push button pins type
  pinMode(push2pin, INPUT_PULLUP);
  pinMode(push3pin, INPUT_PULLUP);
  pinMode(stopPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  delay(200);

  Serial.println(EEPROM.read(addr));
  val2 = EEPROM.read(addr);                         // read previosuly saved value of push button to start from where it was left previously
  switch (val2) {
    case 1:
      Serial.println("Set for 1/day");
      push1state = 1;
      push2state = 0;
      push3state = 0;
      pushVal = 1;
      break;
    case 2:
      Serial.println("Set for 2/day");
      push1state = 0;
      push2state = 1;
      push3state = 0;
      pushVal = 2;
      break;
    case 3:
      Serial.println("Set for 3/day");
      push1state = 0;
      push2state = 0;
      push3state = 1;
      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
    at8am();
    at2pm();                                            //function to start uzzing at 8mm
    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);
  
  stopPins();                                            // call to stop buzzing
  changeScreen();                                        // screen cycle function
}

// push buttons

void push1() {                   // function to set reminder once/day 
  if (push1state == 1) {
    push1state = 0;
    push2state = 0;
    push3state = 0;
//    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 
    oled.clearDisplay();   
    oled.setCursor(0, 0);  
    oled.println("Reminder set");
    oled.setCursor(0, 1);
    oled.println("for Once/day !");
    oled.display();
    delay(1200);
    oled.clearDisplay();
  }
}

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

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

void stopPins() {                   //function to stop buzzing when user pushes stop push button
  if (stopinState == 1) {
//    stopinState = 0;
//    pushPressed = true;
    pushpressed = 1;
    oled.clearDisplay();
    oled.setCursor(0, 0);
    oled.println("Take Medicine  ");
    oled.setCursor(0, 1);
    oled.println("with Warm Water");
    oled.display();
    delay(1200);
    oled.clearDisplay();
  }
}

void startBuzz() {                    // function to start buzzing when time reaches to defined interval
//  if (pushPressed == false) {
 if (pushpressed == 0) {
    Serial.println("pushpressed is false in blink");
    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 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) {
        /////////////////////////////////////////////////////
        startBuzz();
        /////////////////////////////////////////////////////
      }
    }
  }
}

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) {      
        ///////////////////////////////////////////////////
        startBuzz();
        //////////////////////////////////////////////////
      }
    }
  }
}

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) {
        
        /////////////////////////////////////////////////////
        startBuzz();
        /////////////////////////////////////////////////////
      }
    }
  }
}

//Screen Cycling
void changeScreen() {                 //function for Screen Cycling
  // Start switching screen every defined intervalLED
  if (currentMillisLED - previousMillisLED > intervalLED)             // save the last time you changed the display
  {
    previousMillisLED = currentMillisLED;
    screens++;
    if (screens > maxScreen) {
      screens = 0;  // all screens over -> start from 1st
    }
    isScreenChanged = true;
  }
  // Start displaying current screen
  if (isScreenChanged)   // only update the screen if the screen is changed.
  {
    isScreenChanged = false; // reset for next iteration
    switch (screens)
    {
      case getWellsoon:
        gwsMessege();                // get well soon message
        break;
      case HELP_SCREEN:              
        helpScreen();               // instruction screen
        break;
      case TIME_SCREEN:
        timeScreen();                  // to print date and time
        break;
      default:
        //NOT SET.
        break;
    }
  }
}
Loading
ssd1306
GND5VSDASCLSQWRTCDS1307+