/*
"SMART PILL REMINDER SYSTEM"
This system reminds users to take medication at scheduled intervals,
visual/audio alerts, and confirms when medication is taken.
This system is integrated with Blynk IoT for remote monitoring.
*/
//Blynk Template Configuration
#define BLYNK_TEMPLATE_ID "TMPL61VRRt4c1"
#define BLYNK_TEMPLATE_NAME "Smart Pill Reminder"
#define BLYNK_AUTH_TOKEN "NN60TwdkBQqkMjgxkBwEuKkaGmbv7pep"
#define BLYNK_PRINT Serial
/*Including necessary libraries for wifi functionality,Blynk IoT integration,
I2C communication and LCD Control.*/
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize LCD with I2C Address
// Pin definitions
const int buzzerPin = 15;
const int buttonPin = 4;
const int greenLedPin = 2;
const int redLedPin = 0;
// Timing and state Variables
unsigned long lastReminderTime = 0; // Last reminder trigger time
const unsigned long reminderInterval = 30000; // 30 seconds between reminders (demo)
bool reminderActive = false; // Current reminder state
unsigned long lastBuzzerTime = 0; // Last buzzer toggle time
unsigned long medicationAckTime = 0; // When medication was acknowledged
bool isShowingMedicationTaken = false; // Confirmation message state
int buzzerState = 0; // Buzzer tone alternator
String pillName = "Medication"; // Default pill name
#define PILL_NAME V3 // Virtual pin for pill name
// WiFi Credentials (for Wokwi)
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// Blynk virtual pins for IoT control
#define BUTTON_PIN V0 // Manual reminder trigger
#define PILL_STATUS V1 // Current medication status (1=dose due)
#define LED_INDICATOR V2 // Visual indicator state
// Start serial communication for debugging
void setup() {
Serial.begin(115200);
// Initialize hardware pins
pinMode(buzzerPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(greenLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
// Initialize LCD display
lcd.init(); // Start the LCD
lcd.backlight(); // Turn on backlight
displayMessage("Smart Pill", "Reminder Ready"); // Show welcome message
// Connect to WiFi
WiFi.begin(ssid, pass);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
// Initialize Blynk IoT connection
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// Set initial values
lastReminderTime = millis(); // Start timing
Blynk.virtualWrite(PILL_STATUS, 0); // Initial status: no dose due
Blynk.virtualWrite(LED_INDICATOR, 0); // LED indicator off
}
// Maintain Blynk connection
void loop() {
Blynk.run();
// Check for scheduled reminder
if (millis() - lastReminderTime >= reminderInterval && !reminderActive) {
triggerReminder();
}
// Handle buzzer beeping pattern when reminder is active
if (reminderActive && !isShowingMedicationTaken) {
if (millis() - lastBuzzerTime >= 500) { // Beep every 500ms
lastBuzzerTime = millis();
if (buzzerState == 0) {
tone(buzzerPin, 1000, 200); // High pitch beep
buzzerState = 1;
} else {
tone(buzzerPin, 800, 200); // Lower pitch beep
buzzerState = 0;
}
}
}
// Check for medication acknowledgment button press
if (digitalRead(buttonPin) == LOW && reminderActive && !isShowingMedicationTaken) {
medicationAckTime = millis();
isShowingMedicationTaken = true;
acknowledgeMedication();
}
// Show "Medication Taken" after 2 seconds
if (isShowingMedicationTaken && (millis() - medicationAckTime >= 2000)) {
completeMedicationAck();
}
}
/*
Activates the medication reminder system and turns on red LED.
Starts buzzer pattern,shows reminder message and updates Blynk status.
*/
void triggerReminder() {
reminderActive = true;
isShowingMedicationTaken = false;
buzzerState = 0;
lastBuzzerTime = millis();
// Visual indicators
digitalWrite(redLedPin, HIGH);
digitalWrite(greenLedPin, LOW);
// LCD Display - Updated to show pill name
displayMessage("TAKE YOUR PILL:", pillName);
// Blynk Notification - Updated to include pill name
Blynk.virtualWrite(PILL_STATUS, 1);
Blynk.virtualWrite(LED_INDICATOR, 1);
Blynk.logEvent("pill_reminder", String("Time to take ") + pillName);
}
/*
Handles immediate response to medication acknowledgment and stops reminder buzzer.
Keeps red LED on for 2 seconds before switching and plays confirmation melody.
*/
void acknowledgeMedication() {
// Immediate actions
reminderActive = false;
noTone(buzzerPin);// Silence the buzzer
// Play new confirmation melody (3-tone sequence)
tone(buzzerPin, 1319, 200); // E6
delay(200);
tone(buzzerPin, 1568, 200); // G6
delay(200);
tone(buzzerPin, 2093, 300); // C7
}
/*
* Completes the medication acknowledgment sequence after 2-second delay.
Turns on green LED,shows confirmation message and plays success tone.
Updates Blynk status and resets the reminder timer
*/
void completeMedicationAck() {
// Final confirmation after 2-second delay
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, HIGH);
displayMessage("TAKEN:", pillName);
// Play short success tone
tone(buzzerPin, 2637, 150); // E7
delay(150);
noTone(buzzerPin);
// Update Blynk
Blynk.virtualWrite(PILL_STATUS, 0);
Blynk.virtualWrite(LED_INDICATOR, 0);
// Reset system for next reminder
lastReminderTime = millis(); // Reset the timer
reminderActive = false;
isShowingMedicationTaken = false;
}
//Displays a two-line message on the LCD
void displayMessage(String line1, String line2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
}
/*Blynk virtual pin handler for manual reminder trigger.
Allows remotely triggering a reminder through the Blynk app.*/
BLYNK_WRITE(BUTTON_PIN) {
if (param.asInt() == 1 && !reminderActive) {
triggerReminder();
Blynk.virtualWrite(BUTTON_PIN, 0);
}
}
/*Blynk virtual pin handler for pill name updates*/
BLYNK_WRITE(PILL_NAME) {
pillName = param.asStr();
Serial.print("Pill name updated to: ");
Serial.println(pillName);
}