#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <RTClib.h>
#include <AccelStepper.h>
#include <ESP32Servo.h>
// 📌 TFT Display (ILI9341 - SPI)
#define LCD_CS 5
#define LCD_DC 17
#define LCD_RST 16
Adafruit_ILI9341 tft(LCD_CS, LCD_DC, LCD_RST);
// 📌 Stepper Motor (A4988 Driver)
#define STEP_PIN 19
#define DIR_PIN 18
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
// 📌 Servo Motors
Servo servo1;
Servo servo2;
#define SERVO1_PIN 21
#define SERVO2_PIN 22
// 📌 Pushbuttons
#define SWEEP_BUTTON 15
#define PUSH_BUTTON 4
// 📌 Potentiometer
#define POT_PIN 34
// 📌 Buzzer
#define BUZZER_PIN 32
// 📌 RTC Clock (DS3231)
RTC_DS3231 rtc;
// 📌 Stores last dispense time
unsigned long lastDispenseTime = 0;
const int dispenseInterval = 2000; // 2 seconds
void setup() {
Serial.begin(115200);
Serial.println("Initializing...");
// 🔹 Initialize I2C for RTC
Wire.begin(21, 22);
Serial.println("Wire.begin() - I2C Initialized");
// 🔹 Initialize TFT Display
tft.begin();
Serial.println("TFT initialized successfully.");
tft.setRotation(1);
tft.fillScreen(ILI9341_WHITE);
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(20, 20);
tft.println("Pill Dispenser Ready");
// 🔹 Initialize Stepper Motor
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
stepper.setMaxSpeed(500);
stepper.setAcceleration(300);
Serial.println("Stepper motor initialized");
// 🔹 Initialize Servo Motors
servo1.attach(SERVO1_PIN);
servo2.attach(SERVO2_PIN);
servo1.write(90);
servo2.write(90);
Serial.println("Servos initialized");
// 🔹 Initialize Buttons
pinMode(SWEEP_BUTTON, INPUT_PULLUP);
pinMode(PUSH_BUTTON, INPUT_PULLUP);
Serial.println("Buttons initialized");
// 🔹 Initialize Potentiometer
pinMode(POT_PIN, INPUT);
Serial.println("Potentiometer initialized");
// 🔹 Initialize Buzzer
pinMode(BUZZER_PIN, OUTPUT);
Serial.println("Buzzer initialized");
// 🔹 Initialize RTC
if (!rtc.begin()) {
Serial.println("RTC not found! Check wiring.");
tft.setCursor(20, 60);
tft.println("RTC ERROR!");
} else {
Serial.println("RTC initialized.");
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting default time.");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Set to compile time
}
}
updateTimeDisplay();
}
void loop() {
DateTime now = rtc.now();
// 🚀 Automatic pill dispensing every 2 seconds
if (millis() - lastDispenseTime >= dispenseInterval) {
dispensePills();
sweepPills();
lastDispenseTime = millis(); // Update last dispense time
}
// 🖲 Manual pill sweeping
if (digitalRead(SWEEP_BUTTON) == LOW) {
sweepPills();
delay(500);
}
// 🖲 Manual pill pushing
if (digitalRead(PUSH_BUTTON) == LOW) {
pushPills();
delay(500);
}
updateTimeDisplay();
delay(1000); // Update every second
}
void dispensePills() {
Serial.println("🔹 Dispensing Pills...");
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 40);
tft.println("Dispensing Pills...");
// 🔄 Rotate stepper motor to move pill container
stepper.move(200);
stepper.runToPosition();
// 📤 Open servo to drop pills
servo1.write(0);
delay(1000);
servo1.write(90);
// 🔔 Alert with buzzer
for (int i = 0; i < 3; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(200);
}
}
void sweepPills() {
Serial.println("🌀 Sweeping Pills...");
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 40);
tft.println("Sweeping...");
stepper.move(100);
stepper.runToPosition();
}
void pushPills() {
Serial.println("📤 Pushing Pills...");
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 40);
tft.println("Pushing...");
servo2.write(0);
delay(1000);
servo2.write(90);
}
void updateTimeDisplay() {
DateTime now = rtc.now();
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 20);
tft.print("Current Time: ");
tft.print(now.hour());
tft.print(":");
tft.println(now.minute());
tft.setCursor(20, 50);
tft.print("Next Pill in: 2s");
}
// #include <Wire.h>
// #include <SPI.h>
// #include <Adafruit_GFX.h>
// #include <Adafruit_ILI9341.h>
// #include <RTClib.h>
// #define LCD_CS 5
// #define LCD_DC 17
// #define LCD_RST 16
// Adafruit_ILI9341 tft(LCD_CS, LCD_DC, LCD_RST);
// // RTC
// RTC_DS3231 rtc;
// void setup() {
// Serial.begin(115200);
// // Initialize TFT display
// tft.begin();
// tft.setRotation(1);
// tft.fillScreen(ILI9341_WHITE);
// tft.setTextSize(2);
// tft.setTextColor(ILI9341_BLACK);
// // Initialize RTC
// if (!rtc.begin()) {
// Serial.println("Couldn't find RTC");
// tft.setCursor(20, 20);
// tft.println("RTC ERROR");
// while (1); // Halt the program if RTC is not found
// }
// if (rtc.lostPower()) {
// Serial.println("RTC lost power, setting the time!");
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Set RTC to compile time
// }
// delay(1000); // Initial delay to avoid display glitch
// }
// void loop() {
// DateTime now = rtc.now();
// // Print date and time to Serial Monitor
// Serial.print(now.year(), DEC);
// Serial.print('/');
// Serial.print(now.month(), DEC);
// Serial.print('/');
// Serial.print(now.day(), DEC);
// Serial.print(" ");
// Serial.print(now.hour(), DEC);
// Serial.print(':');
// Serial.print(now.minute(), DEC);
// Serial.print(':');
// Serial.print(now.second(), DEC);
// Serial.println();
// // Update the TFT display with current time
// tft.fillScreen(ILI9341_WHITE); // Clear the screen
// tft.setCursor(20, 20);
// tft.setTextSize(2);
// tft.setTextColor(ILI9341_BLACK);
// tft.print("Date: ");
// tft.print(now.month(), DEC);
// tft.print('/');
// tft.print(now.day(), DEC);
// tft.print('/');
// tft.print(now.year(), DEC);
// tft.setCursor(20, 60); // Move to the next line
// tft.print("Time: ");
// tft.print(now.hour(), DEC);
// tft.print(':');
// tft.print(now.minute(), DEC);
// tft.print(':');
// tft.print(now.second(), DEC);
// delay(1000); // Delay 1 second before updating again
// }
// #include <ESP32Servo.h>
// Servo servo1;
// Servo servo2;
// #define SERVO1_PIN 21
// #define SERVO2_PIN 22
// void setup() {
// Serial.begin(115200);
// servo1.attach(SERVO1_PIN);
// servo2.attach(SERVO2_PIN);
// servo1.write(90);
// servo2.write(90);
// delay(1000);
// servo1.write(0);
// delay(1000);
// servo2.write(0);
// delay(1000);
// }
// void loop() {
// }
// #include <ESP32Servo.h>
// Servo servo1; // Servo for sweeping
// Servo servo2; // Servo for pushing
// #define SERVO1_PIN 21 // Pin for sweeping servo
// #define SERVO2_PIN 22 // Pin for pushing servo
// #define SWEEP_BUTTON 15 // Pushbutton for sweeping
// #define PUSH_BUTTON 4 // Pushbutton for pushing
// void setup() {
// Serial.begin(115200);
// // Attach servos to pins
// servo1.attach(SERVO1_PIN);
// servo2.attach(SERVO2_PIN);
// // Initialize servos to 90 degrees
// servo1.write(90);
// servo2.write(90);
// delay(1000);
// // Set up button pins
// pinMode(SWEEP_BUTTON, INPUT_PULLUP);
// pinMode(PUSH_BUTTON, INPUT_PULLUP);
// Serial.println("System Initialized.");
// }
// void loop() {
// // Manual sweeping with button press
// if (digitalRead(SWEEP_BUTTON) == LOW) {
// Serial.println("Sweep Button Pressed");
// sweepPills(); // Call the sweepPills function
// delay(500); // Debounce delay
// }
// // Manual pushing with button press
// if (digitalRead(PUSH_BUTTON) == LOW) {
// Serial.println("Push Button Pressed");
// pushPills(); // Call the pushPills function
// delay(500); // Debounce delay
// }
// }
// // Function to sweep pills (move servo1)
// void sweepPills() {
// Serial.println("Sweeping Pills...");
// servo1.write(0); // Move servo1 to 0 degrees (sweep position)
// delay(1000); // Wait for 1 second
// servo1.write(90); // Return servo1 to 90 degrees
// delay(1000); // Wait for 1 second
// }
// // Function to push pills (move servo2)
// void pushPills() {
// Serial.println("Pushing Pills...");
// servo2.write(0); // Move servo2 to 0 degrees (push position)
// delay(1000); // Wait for 1 second
// servo2.write(90); // Return servo2 to 90 degrees
// delay(1000); // Wait for 1 second
// }
// #include <AccelStepper.h>
// // Define the stepper motor pins (using A4988 motor driver)
// #define STEP_PIN 19
// #define DIR_PIN 18
// // Create an AccelStepper instance
// AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
// void setup() {
// Serial.begin(115200); // Initialize serial monitor for debugging
// stepper.setMaxSpeed(1000); // Set maximum speed of stepper
// stepper.setAcceleration(500); // Set acceleration of stepper
// Serial.println("Stepper motor test started.");
// }
// void loop() {
// // Move stepper motor 1000 steps forward
// Serial.println("Moving forward...");
// stepper.moveTo(1000);
// while (stepper.distanceToGo() != 0) {
// stepper.run(); // Keep running the motor until the desired position is reached
// }
// delay(1000); // Wait for a second
// // Move stepper motor 1000 steps backward
// Serial.println("Moving backward...");
// stepper.moveTo(-1000);
// while (stepper.distanceToGo() != 0) {
// stepper.run(); // Keep running the motor until the desired position is reached
// }
// delay(1000); // Wait for a second
// }
// #define SWEEP_BUTTON 15
// #define PUSH_BUTTON 4
// void setup() {
// Serial.begin(115200); // Start the serial communication
// pinMode(SWEEP_BUTTON, INPUT_PULLUP); // Set the sweep button pin as input with pull-up resistor
// pinMode(PUSH_BUTTON, INPUT_PULLUP); // Set the push button pin as input with pull-up resistor
// Serial.println("Button Test Initialized.");
// }
// void loop() {
// // Test for Sweep Button
// if (digitalRead(SWEEP_BUTTON) == LOW) {
// Serial.println("Sweep Button Pressed");
// }
// // Test for Push Button
// if (digitalRead(PUSH_BUTTON) == LOW) {
// Serial.println("Push Button Pressed");
// }
// delay(200); // Small delay to avoid spamming serial output
// }
// #include <AccelStepper.h>
// #define STEP_PIN 19
// #define DIR_PIN 18
// AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
// void setup() {
// Serial.begin(115200);
// pinMode(STEP_PIN, OUTPUT);
// pinMode(DIR_PIN, OUTPUT);
// stepper.setMaxSpeed(200);
// stepper.setAcceleration(100);
// Serial.println("Stepper Motor Test Started.");
// }
// void loop() {
// Serial.println("Moving Forward...");
// stepper.move(1000);
// while (stepper.distanceToGo() != 0) {
// stepper.run();
// delay(1); // Small delay for better stepping
// }
// Serial.println("Reached Forward Position");
// delay(1000);
// Serial.println("Moving Backward...");
// stepper.move(-1000);
// while (stepper.distanceToGo() != 0) {
// stepper.run();
// delay(1); // Small delay for better stepping
// }
// Serial.println("Reached Backward Position");
// delay(1000);
// }
pushing
SG90 Servo motor: tilts for discard