#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>
#include <EEPROM.h>
// LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// RTC
RTC_DS1307 rtc;
// Pines
const int btn1 = 9; // 1 vez/día
const int btn2 = 8; // 2 veces/día
const int btn3 = 7; // 3 veces/día
const int btnStop = A0; // detener alarma
const int buzzerPin = 13;
const int ledPin = LED_BUILTIN;
const int EEPROM_ADDR = 0;
// Configuración
int reminderMode = 0;
bool alarmActive = false;
bool alarmAcknowledged = false;
// Pantallas
unsigned long lastScreenChange = 0;
int currentScreen = 0;
const unsigned long screenInterval = 3000;
// Anti rebote
unsigned long lastButtonTime = 0;
const unsigned long debounce = 250;
// Horarios
const int HOUR1 = 23;
const int MIN1 = 52;
const int HOUR2 = 00;
const int MIN2 = 56;
const int HOUR3 = 23;
const int MIN3 = 46;
// Evitar repetir alarma el mismo día
int lastAlarmDay1 = -1;
int lastAlarmDay2 = -1;
int lastAlarmDay3 = -1;
void setup() {
Serial.begin(9600);
pinMode(btn1, INPUT_PULLUP);
pinMode(btn2, INPUT_PULLUP);
pinMode(btn3, INPUT_PULLUP);
pinMode(btnStop, INPUT_PULLUP);
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
lcd.begin(16, 2);
if (!rtc.begin()) {
lcd.print("RTC ERROR");
while (1);
}
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
reminderMode = EEPROM.read(EEPROM_ADDR);
if (reminderMode < 1 || reminderMode > 3) {
reminderMode = 1;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RECUERDE TOMAR");
lcd.setCursor(0, 1);
lcd.print("LOS MEDICAMENTOS");
delay(2000);
}
void loop() {
readButtons();
checkAlarms();
updateAlarm();
if (millis() - lastScreenChange > screenInterval) {
lastScreenChange = millis();
currentScreen++;
if (currentScreen > 2) currentScreen = 0;
showScreen();
}
}
// ------------------- BOTONES --------------------
void readButtons() {
if (millis() - lastButtonTime < debounce) return;
if (digitalRead(btn1) == LOW) {
reminderMode = 1;
EEPROM.write(EEPROM_ADDR, 1);
lcd.clear();
lcd.print("1 vez por dia");
delay(1200);
lastButtonTime = millis();
}
if (digitalRead(btn2) == LOW) {
reminderMode = 2;
EEPROM.write(EEPROM_ADDR, 2);
lcd.clear();
lcd.print("2 veces por dia");
delay(1200);
lastButtonTime = millis();
}
if (digitalRead(btn3) == LOW) {
reminderMode = 3;
EEPROM.write(EEPROM_ADDR, 3);
lcd.clear();
lcd.print("3 veces por dia");
delay(1200);
lastButtonTime = millis();
}
if (digitalRead(btnStop) == LOW) {
alarmActive = false;
alarmAcknowledged = true;
noTone(buzzerPin);
digitalWrite(ledPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Medicamento");
lcd.setCursor(0, 1);
lcd.print("Tomado");
delay(1500);
lastButtonTime = millis();
}
}
// ------------------- ALARMAS --------------------
void checkAlarms() {
DateTime now = rtc.now();
if (reminderMode >= 1) {
triggerAlarm(
now,
HOUR1,
MIN1,
lastAlarmDay1
);
}
if (reminderMode >= 3) {
triggerAlarm(
now,
HOUR3,
MIN3,
lastAlarmDay3
);
}
if (reminderMode >= 2) {
triggerAlarm(
now,
HOUR2,
MIN2,
lastAlarmDay2
);
}
}
void triggerAlarm(
DateTime now,
int hourTarget,
int minuteTarget,
int &lastDay
) {
if (
now.hour() == hourTarget &&
now.minute() == minuteTarget &&
now.second() == 0 &&
now.day() != lastDay
) {
alarmActive = true;
alarmAcknowledged = false;
lastDay = now.day();
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("Hora de tomar");
// lcd.setCursor(0, 1);
// lcd.print("medicina!");
}
}
// ------------------- BUZZER --------------------
void updateAlarm() {
static unsigned long previous = 0;
static bool state = false;
if (!alarmActive) return;
if (millis() - previous > 400) {
previous = millis();
state = !state;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hora de tomar");
lcd.setCursor(0, 1);
lcd.print("medicina!");
digitalWrite(ledPin, state);
if (state) {
tone(buzzerPin, 1200);
} else {
noTone(buzzerPin);
}
}
}
// ------------------- LCD --------------------
void showScreen() {
DateTime now = rtc.now();
switch (currentScreen) {
case 0:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MANTENTE SANO :)");
lcd.setCursor(0, 1);
lcd.print("MEJORATE PRONTO:)");
break;
case 1:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo:");
if (reminderMode == 1)
lcd.print("1 vez");
if (reminderMode == 2)
lcd.print("2 veces");
if (reminderMode == 3)
lcd.print("3 veces");
lcd.setCursor(0, 1);
lcd.print("Botones 1-2-3");
break;
case 2:
lcd.clear();
lcd.setCursor(0, 0);
char timeBuffer[17];
sprintf(
timeBuffer,
"%02d:%02d:%02d",
now.hour(),
now.minute(),
now.second()
);
lcd.print(timeBuffer);
lcd.setCursor(0, 1);
char dateBuffer[17];
sprintf(
dateBuffer,
"%02d/%02d/%04d",
now.day(),
now.month(),
now.year()
);
lcd.print(dateBuffer);
break;
}
}