Cirkit Designer Logo
Cirkit Designer
Your all-in-one circuit design IDE
Home / 
Project Documentation

Arduino UNO Based Medicine Dispenser with I2C LCD, RTC, and Servo Control

Image of Arduino UNO Based Medicine Dispenser with I2C LCD, RTC, and Servo Control

Circuit Documentation

Summary

This circuit is designed to operate a medicine dispenser system that includes an Arduino UNO microcontroller, a 16x2 I2C LCD for display, a real-time clock (RTC DS3231) for timekeeping, a micro servo for dispensing actions, a buzzer for audible alerts, and pushbuttons for user input. The system is capable of dispensing medicine at predetermined times and allows the user to set or adjust the dispensing schedule.

Component List

Arduino UNO

  • Microcontroller board based on the ATmega328P
  • Used as the main controller for the medicine dispenser system

16x2 I2C LCD

  • Alphanumeric liquid crystal display with I2C communication
  • Displays the current time and dispensing status

Buzzer

  • An audible signaling device
  • Provides an alert when medicine is dispensed

Micro servo 9G

  • A small and lightweight servo motor
  • Actuates to dispense the medicine

RTC DS3231

  • A highly accurate real-time clock module with I2C communication
  • Keeps track of the current time for the dispenser

Pushbuttons

  • Simple switches for user input
  • Used to set and adjust the dispensing schedule

Resistors (10k Ohms)

  • Electrical components providing resistance
  • Used for pull-up configurations and to limit current

Wiring Details

Arduino UNO

  • 5V and GND are used to power the micro servo, I2C LCD, RTC module, and pushbuttons.
  • A4 (SDA) and A5 (SCL) are connected to the I2C bus for communication with the LCD and RTC.
  • D9 controls the micro servo via PWM.
  • D6 is connected to the buzzer.
  • D2, D3, and D4 are connected to pushbuttons through 10k Ohm resistors for user input.

16x2 I2C LCD

  • GND and VCC for power supply.
  • SDA and SCL for I2C communication with the Arduino UNO.

Buzzer

  • POSITIVE connected to D6 on the Arduino UNO.
  • NEGATIVE connected to the common ground net.

Micro servo 9G

  • GND and +5V for power supply.
  • PWM connected to D9 on the Arduino UNO for control signals.

RTC DS3231

  • GND and VCC for power supply.
  • SDA and SCL for I2C communication with the Arduino UNO.

Pushbuttons

  • One side of each pushbutton is connected to 5V.
  • The other side of each pushbutton is connected to an Arduino UNO digital pin (D2, D3, D4) through a 10k Ohm resistor to ground.

Resistors (10k Ohms)

  • Connected between the pushbutton and ground to form a pull-up resistor configuration.

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, and servo, and sets up the pushbuttons with pull-up resistors. The main loop checks the current time against preset alarm times to trigger the dispensing mechanism. It also handles button inputs to set and adjust the alarm times. The dispenseMedicine function actuates the servo to dispense medicine and sounds the buzzer. The handleButtonInput function allows the user to set the dispensing times.