#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
#define SERVO_PIN_MED1 A4 // Servo for Medication 1
#define SERVO_PIN_MED2 A5 // Servo for Medication 2
#define SERVO_PIN_MED3 6 // Servo for Medication 3
#define SENSOR_IR 1
#define BUZZER 13
Servo servoMed1;
Servo servoMed2;
Servo servoMed3;
bool medicationDispensed = false;
bool med1Selected = false;
bool med2Selected = false;
bool med3Selected = false;
/* Display */
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
/* Keypad setup */
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = {5, 4, 3, 2};
byte colPins[KEYPAD_COLS] = {A3, A2, A1, A0};
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
/* Variables for medication and time */
int med1Quantity = 0; // Cantidad de medicamento 1
int med2Quantity = 0; // Cantidad de medicamento 2
int med3Quantity = 0; // Cantidad de medicamento 3
int dispenseHour = 0;
int dispenseMinute = 0;
unsigned long lastDispenseMillis = 0; // Keeps track of the time since the Arduino started
void showStartupMessage() {
lcd.setCursor(2, 0);
lcd.print("Bienvenido!");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dispensador de");
delay(1000);
lcd.setCursor(0, 2);
lcd.print("medicamentos Dx3");
delay(2000);
}
void selectMedication() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Elige");
lcd.setCursor(0, 2);
lcd.print("medicina (1-3):");
char key = 0;
while (key != 'A') { // Usa '#' para finalizar la selección
key = keypad.getKey();
if (key == '1') {
med1Selected = true;
lcd.setCursor(0, 1);
lcd.print("Med1 elegida ");
} else if (key == '2') {
med2Selected = true;
lcd.setCursor(0, 1);
lcd.print("Med2 elegida ");
} else if (key == '3') {
med3Selected = true;
lcd.setCursor(0, 1);
lcd.print("Med3 elegida ");
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Medicinas listas!");
delay(1000);
}
void selectQuantity() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cantidad Med1:");
med1Quantity = 0;
// Selecciona la cantidad de medicamento 1
while (med1Quantity == 0) {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
med1Quantity = key - '0'; // Convierte char a int
lcd.setCursor(0, 1);
lcd.print("Cantidad: ");
lcd.print(med1Quantity);
}
}
delay(1000);
// Selecciona la cantidad de medicamento 2
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cantidad Med2:");
med2Quantity = 0;
while (med2Quantity == 0) {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
med2Quantity = key - '0'; // Convierte char a int
lcd.setCursor(0, 1);
lcd.print("Cantidad: ");
lcd.print(med2Quantity);
}
}
delay(1000);
// Selecciona la cantidad de medicamento 3
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cantidad Med3:");
med3Quantity = 0;
while (med3Quantity == 0) {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
med3Quantity = key - '0'; // Convierte char a int
lcd.setCursor(0, 1);
lcd.print("Cantidad: ");
lcd.print(med3Quantity);
}
}
delay(1000);
}
void setDispenseTime() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hora (0-23)?");
char hourInput[3] = "";
int idx = 0;
while (idx < 2) {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
hourInput[idx++] = key;
lcd.setCursor(0, 1);
lcd.print("Hora: ");
lcd.print(hourInput);
} else if (key == 'A' && idx > 0) { // Accept input
int enteredHour = atoi(hourInput);
if (enteredHour >= 0 && enteredHour <= 23) {
dispenseHour = enteredHour;
break;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hora Invalida");
idx = 0;
delay(1000);
lcd.clear();
lcd.print("hora (0-23):");
}
}
}
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Minuto (0-59)?");
char minuteInput[3] = "";
idx = 0;
while (idx < 2) {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
minuteInput[idx++] = key;
lcd.setCursor(0, 1);
lcd.print("Minuto: ");
lcd.print(minuteInput);
} else if (key == 'A' && idx > 0) { // Accept input
int enteredMinute = atoi(minuteInput);
if (enteredMinute >= 0 && enteredMinute <= 59) {
dispenseMinute = enteredMinute;
break;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Minuto Invalido");
idx = 0;
delay(1000);
lcd.clear();
lcd.print("Minuto (0-59):");
}
}
}
delay(1000);
}
void displayTime(unsigned long currentMillis) {
int currentHour = (currentMillis / 3600000) % 24; // Convert millis to hours
int currentMinute = (currentMillis / 60000) % 60; // Convert millis to minutes
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tiempo transcurrido:");
lcd.setCursor(0, 1);
lcd.print(currentHour);
lcd.print(":");
if (currentMinute < 10) lcd.print('0'); // Add leading zero for minutes
lcd.print(currentMinute);
delay(1000);
}
void dispenseMedication() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dispensando...");
// Dispensar medicamento 1
for (int i = 0; i < med1Quantity; i++) {
if (med1Selected) {
servoMed1.write(180); // Mueve el servo para dispensar
delay(1000); // Tiempo para completar el movimiento
servoMed1.write(90); // Regresa el servo a la posición inicial (90 grados)
delay(1000); // Tiempo para regresar
}
}
// Dispensar medicamento 2
for (int i = 0; i < med2Quantity; i++) {
if (med2Selected) {
servoMed2.write(180); // Mueve el servo para dispensar
delay(1000); // Tiempo para completar el movimiento
servoMed2.write(90); // Regresa el servo a la posición inicial (90 grados)
delay(1000); // Tiempo para regresar
}
}
// Dispensar medicamento 3
for (int i = 0; i < med3Quantity; i++) {
if (med3Selected) {
servoMed3.write(180); // Mueve el servo para dispensar
delay(1000); // Tiempo para completar el movimiento
servoMed3.write(90); // Regresa el servo a la posición inicial (90 grados)
delay(1000); // Tiempo para regresar
}
}
// Mostrar mensaje de finalización
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Medicamento listo!");
// Activar el buzzer para indicar que se ha dispensado
digitalWrite(BUZZER, HIGH); // El buzzer empieza a sonar
// Mantener el buzzer encendido hasta que el sensor detecte proximidad
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Esperando toma...");
while (digitalRead(SENSOR_IR) == LOW) { // Mientras no haya proximidad detectada
// El buzzer sigue sonando hasta que el sensor de proximidad detecte que alguien está cerca
delay(100); // Pequeña pausa para evitar saturar el bucle
}
// Apagar el buzzer una vez que el sensor detecte proximidad
digitalWrite(BUZZER, LOW); // El buzzer se apaga
// Mostrar mensaje indicando que el medicamento fue tomado
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Medicina");
lcd.setCursor(0, 2);
lcd.print("tomada");
delay(2000); // Tiempo para mostrar el mensaje de confirmación
// Volver al menú principal
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Presiona D para");
lcd.setCursor(0, 1);
lcd.print("volver al menu");
// Espera hasta que el usuario presione 'D' para volver al menú
char key = 0;
while (key != 'D') {
key = keypad.getKey(); // Esperar que el usuario presione 'D'
}
// Volver a la selección de medicación
selectMedication();
}
void setup() {
lcd.begin(16, 2);
servoMed1.attach(SERVO_PIN_MED1); // Attach servo for Medication 1
servoMed2.attach(SERVO_PIN_MED2); // Attach servo for Medication 2
servoMed3.attach(SERVO_PIN_MED3); // Attach servo for Medication 3
showStartupMessage();
selectMedication();
selectQuantity();
setDispenseTime();
lastDispenseMillis = millis(); // Start counting from when the program begins
}
void loop() {
unsigned long currentMillis = millis();
int currentHour = (currentMillis / 3600000) % 24; // Get the current hour
int currentMinute = (currentMillis / 60000) % 60; // Get the current minute
// Show the current time on the LCD
displayTime(currentMillis);
// Check if it's time to dispense the medication
if (currentHour == dispenseHour && currentMinute == dispenseMinute && !medicationDispensed) {
dispenseMedication();
medicationDispensed = true; // Set flag to avoid repeating dispense
} else if (currentHour != dispenseHour || currentMinute != dispenseMinute) {
medicationDispensed = false; // Reset flag when the time changes
}
delay(1000); // Wait for a second before updating the time again
}