Arduino UNO Based Medicine Dispenser with I2C LCD, RTC, and Servo Control
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to operate a medicine dispensing system that includes an Arduino UNO microcontroller, a 16x2 I2C LCD for display, a buzzer for audible alerts, a micro servo for mechanical actuation, a real-time clock (RTC) module for timekeeping, and pushbuttons for user input. The system is capable of dispensing medicine at predetermined times, with the ability to set and confirm these times using the pushbuttons. The RTC module ensures accurate timing, while the servo is used to release the medicine at the set times. The buzzer provides an audible signal when the medicine is dispensed.
Component List
Arduino UNO
- Microcontroller board based on the ATmega328P
- Provides I/O pins for interfacing with other components
- Powers the circuit and controls the servo, buzzer, and LCD
16x2 I2C LCD
- Alphanumeric liquid crystal display with 16 characters by 2 lines
- Uses I2C communication to display information such as time and alarm settings
Buzzer
- An audible signaling device that emits a tone when activated
- Alerts the user when medicine is dispensed
Micro servo 9G
- A small-sized servo motor that provides precise control
- Actuates a mechanism to dispense medicine at set times
RTC DS3231
- A real-time clock module that maintains accurate time
- Provides time data to the Arduino for scheduling dispensing events
Pushbutton
- A momentary tactile switch used for user input
- Allows setting and confirming the dispensing times
Resistor (10k Ohms)
- A passive component used to limit current or divide voltages
- Used for pull-up resistors on the pushbutton inputs
Wiring Details
Arduino UNO
5VandGNDpins provide power to the RTC DS3231, Micro servo 9G, 16x2 I2C LCD, and PushbuttonsA4 (SDA)andA5 (SCL)are used for I2C communication with the RTC DS3231 and 16x2 I2C LCDD9controls the Micro servo 9GD6connects to the BuzzerD2,D3, andD4connect to Pushbuttons through 10k Ohm resistors
16x2 I2C LCD
GNDandVCCfor power connectionsSDAandSCLfor I2C data and clock lines
Buzzer
POSITIVEconnects toD6on the Arduino UNONEGATIVEconnects toGNDthrough a 10k Ohm resistor
Micro servo 9G
GNDand+5Vfor power connectionsPWMconnects toD9on the Arduino UNO
RTC DS3231
GNDandVCCfor power connectionsSDAandSCLfor I2C data and clock lines
Pushbutton
- One side connects to
5V - The other side connects to an Arduino digital input (
D2,D3, orD4) through a 10k Ohm resistor toGND
Resistor (10k Ohms)
- Connects between Pushbutton and
GND - Acts as a pull-up resistor for the Pushbutton inputs
Documented Code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address may vary, check yours
RTC_DS3231 rtc;
Servo dispenserServo;
const int buttonSetHour = 2;
const int buttonSetMinute = 3;
const int buttonConfirmTime = 4;
const int buzzerPin = 6;
const int servoPin = 9;
int alarmHours[3] = {8, 12, 20}; // Example dispensing times (8 AM, 12 PM, 8 PM)
int alarmMinutes[3] = {0, 0, 0}; // Corresponding minutes for each hour set
bool alarmTriggered[3] = {false, false, false}; // Tracks if alarm has triggered
void setup() {
lcd.begin();
rtc.begin();
dispenserServo.attach(servoPin);
pinMode(buzzerPin, OUTPUT);
pinMode(buttonSetHour, INPUT_PULLUP);
pinMode(buttonSetMinute, INPUT_PULLUP);
pinMode(buttonConfirmTime, INPUT_PULLUP);
lcd.print("Medicine Dispenser");
delay(2000);
lcd.clear();
}
void loop() {
DateTime now = rtc.now();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
// Check each alarm time
for (int i = 0; i < 3; i++) {
if (now.hour() == alarmHours[i] && now.minute() == alarmMinutes[i] && !alarmTriggered[i]) {
dispenseMedicine(i);
alarmTriggered[i] = true; // Prevent retriggering in the same minute
}
if (now.minute() != alarmMinutes[i]) {
alarmTriggered[i] = false; // Reset trigger for next day
}
}
handleButtonInput();
}
void dispenseMedicine(int alarmIndex) {
lcd.setCursor(0, 1);
lcd.print("Dispensing Dose ");
lcd.print(alarmIndex + 1);
tone(buzzerPin, 1000); // Sound buzzer
dispenserServo.write(90); // Rotate servo to release pills
delay(1000); // Wait for pill to drop
dispenserServo.write(0); // Return servo to original position
noTone(buzzerPin);
delay(1000); // Extra delay to ensure complete dispensing
}
void handleButtonInput() {
static int settingHour = 8;
static int settingMinute = 0;
static int alarmSettingIndex = 0;
// Increment hour setting
if (digitalRead(buttonSetHour) == LOW) {
settingHour = (settingHour + 1) % 24;
delay(200);
}
// Increment minute setting
if (digitalRead(buttonSetMinute) == LOW) {
settingMinute = (settingMinute + 1) % 60;
delay(200);
}
// Confirm time setting
if (digitalRead(buttonConfirmTime) == LOW) {
alarmHours[alarmSettingIndex] = settingHour;
alarmMinutes[alarmSettingIndex] = settingMinute;
alarmSettingIndex = (alarmSettingIndex + 1) % 3; // Cycle through alarms
lcd.setCursor(0, 1);
lcd.print("Set Alarm ");
lcd.print(alarmSettingIndex);
lcd.print(": ");
lcd.print(settingHour);
lcd.print(":");
lcd.print(settingMinute);
delay(500);
}
}
This code is responsible for controlling the medicine dispenser system. It initializes the LCD, RTC, servo, and sets up the button inputs with pull-up resistors. The main loop checks the current time against preset alarm times and triggers the dispenseMedicine function when it's time to dispense. The handleButtonInput function allows the user to set and confirm the dispensing times using the pushbuttons.