#include <Wire.h>
#include <RTClib.h>
#include <Servo.h>
#include <Keypad.h>
#include <LiquidCrystal.h> // Use for non-I2C LCD
// Define components
RTC_DS1307 rtc; // Initialize the DS1307 RTC
Servo servo;
const int buzzerPin = PB9;
const int ledPin = PB8;
const int servoPin = PA8;
// Alarm variables
int alarmHour = 0;
int alarmMinute = 0;
bool alarmSet = false;
bool alarmTriggered = false;
// Password variables
const String password = "1234";
String enteredPassword = "";
// Keypad settings
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {PA0, PA1, PA2, PA3}; // Connect to the row pins of the keypad
byte colPins[COLS] = {PA4, PA5, PA6, PA7}; // Connect to the column pins of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Non-I2C LCD settings
LiquidCrystal lcd(PB0, PB1, PB10, PB11, PB12, PB13); // Define pins for non-I2C LCD
void setup() {
Serial.begin(115200);
// Initialize I2C communication
Wire.begin();
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// Adjust the RTC time only once if it’s not set correctly
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Initialize servo
servo.attach(servoPin);
servo.write(0); // Set servo to initial position
// Initialize buzzer and LED
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(buzzerPin, LOW);
digitalWrite(ledPin, LOW);
// Initialize LCD
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Smart Med Dispenser");
lcd.setCursor(0, 1);
lcd.print("Set Alarm: --:--");
Serial.println("Smart Medicine Dispenser Ready!");
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.println(key);
if (key == '#') {
if (!alarmSet) {
int tempHour = enteredPassword.substring(0, 2).toInt();
int tempMinute = enteredPassword.substring(2, 4).toInt();
alarmHour = tempHour;
alarmMinute = tempMinute;
alarmSet = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm set for:");
lcd.setCursor(0, 1);
lcd.print(alarmHour < 10 ? "0" : "");
lcd.print(alarmHour);
lcd.print(":");
lcd.print(alarmMinute < 10 ? "0" : "");
lcd.print(alarmMinute);
Serial.print("Alarm set for: ");
Serial.print(alarmHour);
Serial.print(":");
Serial.println(alarmMinute);
} else {
if (enteredPassword == password) {
Serial.println("Access Granted! Dispensing Medicine.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Access Granted");
lcd.setCursor(0, 1);
lcd.print("Dispensing...");
dispenseMedicine();
resetAlarm();
} else {
Serial.println("Incorrect Password!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Incorrect Password");
delay(2000);
}
}
enteredPassword = "";
} else if (key == '*') {
enteredPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Input Cleared");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Alarm: --:--");
} else {
enteredPassword += key;
lcd.setCursor(10, 1);
lcd.print(enteredPassword);
}
}
// Checking current time
DateTime now = rtc.now();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(now.hour() < 10 ? "0" : "");
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute() < 10 ? "0" : "");
lcd.print(now.minute());
if (now.hour() == alarmHour && now.minute() == alarmMinute && !alarmTriggered) {
triggerAlarm();
}
}
void triggerAlarm() {
alarmTriggered = true;
Serial.println("Alarm triggered! Enter password to dispense.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm Triggered!");
lcd.setCursor(0, 1);
lcd.print("Enter password");
digitalWrite(buzzerPin, HIGH);
digitalWrite(ledPin, HIGH);
}
void resetAlarm() {
digitalWrite(buzzerPin, LOW);
digitalWrite(ledPin, LOW);
alarmTriggered = false;
alarmSet = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm reset.");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Alarm: --:--");
Serial.println("Alarm reset.");
}
void dispenseMedicine() {
// Rotate servo to dispense position
servo.write(90);
delay(2000); // Adjust this delay as needed for dispensing
servo.write(0); // Return servo to original position
}