Contact sales

How to build a smart pill dispenser with Particle

Learn how to build a smart pill dispenser using Particle technology for automated, reliable medication management.

Shebin Jacob Nekhil R article author avatarShebin Jacob Nekhil RJanuary 10, 2025
How to build a smart pill dispenser with Particle

The problem

Medication management is a critical part of healthcare, yet studies reveal that 50% of patients with chronic illnesses fail to take their medications as prescribed. This non-adherence leads to serious consequences, including 125,000 deaths annually, 10% of hospitalizations, and over $100 billion in preventable healthcare costs.

Traditional methods, like manual pill organizers, often fall short. They rely on memory, offer no reminders, and lack any form of monitoring. For individuals with complex medication schedules—such as morning, afternoon, and evening doses—keeping track of everything can be overwhelming. Missed medications not only disrupt treatment but can also exacerbate health issues, putting lives at risk.

The solution

This is where the Smart Pill Dispenser steps in. By automating the process and sending real-time notifications via a web app, it ensures that users take the right pills at the right time. Designed to address the shortcomings of ordinary medication methods, it’s a step towards better healthcare management and peace of mind.

The Smart Pill Dispenser works by parsing a JSON input from Firebase to retrieve the pill schedule, activating a dispensing mechanism at the correct time, and providing real-time notifications to users. Its intuitive design and user-friendly features make it a game-changer for medication adherence.

The system continuously tracks the current time and checks if a user presses the button. When the button is pressed, the system verifies whether the current time falls within the grace window of a scheduled dispensing time. If the current time is within this window and the pills have not already been dispensed, the system sends a command to the motor driver to activate the appropriate stepper motor, releasing the pills. Notifications are managed separately, reminding users when it’s time to take their pills according to the schedule.

How does the system work?

The pill dispenser system operates based on user interaction and scheduled timing. It starts by parsing a JSON input from Firebase containing the pill schedule, which updates the state of each container with details like pill names, quantities, and scheduled times.

The system continuously tracks the current time and checks if a user presses the button. When the button is pressed, the system verifies whether the current time falls within the grace window of a scheduled dispensing time. If the current time is within this window and the pills have not already been dispensed, the system sends a command to the motor driver to activate the appropriate stepper motor, releasing the pills. It then updates the timestamp to reflect the last dispensing action. If the current time is outside the grace window, the system refrains from dispensing.

Notifications are managed separately, reminding users when it’s time to take their pills according to the schedule. This design ensures that pills are dispensed only upon user confirmation and within the prescribed time frame, maintaining flexibility and accuracy.

Bill of materials

  • Particle Photon 2
  • 28BYJ stepper motors
  • ULN2003 motor drivers
  • 2-inch Waveshare LCD display
  • PLA+ filament for 3D printing
  • Momentary metal push button switch
  • JST connectors
  • Screw terminal blocks
  • 5V 2A power supply
  • EasyEDA for PCB design

Step-by-step tutorial

Step one: Get your Particle Photon 2 ready

The Particle Photon 2 serves as the central microcontroller that powers the Smart Pill Dispenser. It controls the dispensing mechanism, handles communication with the web app, and manages the timing and scheduling of pill dispensing. Additionally, it is a powerful yet lightweight device, ideal for real-time applications. It supports both 2.4 GHz and 5 GHz Wi-Fi for reliable connectivity, and its Realtek RTL8721DM processor with an ARM Cortex M33 CPU running at 200 MHz ensures the processing power necessary for high-speed, complex tasks.

Set-up the Photon:

  • Navigate to setup.particle.io to link your device to your Particle account.
  • Ensure the Photon is powered on and detected as “P2” in the setup interface.

Flash the Firmware:

  • Follow the wizard to flash the necessary firmware in DFU mode (indicated by a blinking yellow LED).

Program the Photon:

  • Use the Particle Workbench and Visual Studio Code to program the device.
  • Follow the Particle Workbench Quickstart for setup.

Step two: Build the pill dispensing mechanism

When developing the Smart Pill Dispenser, the primary challenge was designing a reliable and efficient pill dispensing mechanism. Initially, creating a unique design from scratch was considered. However, due to the time and complexity involved, an alternative approach was taken: exploring existing designs for inspiration and adaptation.

Through research, a mechanism by Makers UPV on Hackster was identified. This design utilized a 28BYJ stepper motor, valued for its precision and reliability in movement control.

The mechanism consists of two main parts:

  • Pill Storage Compartment: Holds the pills to be dispensed.
  • Rotor Part: Dispenses the pills. This part is customizable, so adjust it based on the size and shape of the pills you plan to use.

Design and 3D Print the Components

  • Use a 3D modeling tool to design the pill storage compartment and rotor. The rotor part should have precise cutouts or slots that match the dimensions of your pills.
  • Print the components using PLA+ filament for durability and ease of use. Ensure the parts fit snugly together for smooth operation.

Assemble the Mechanism

  • Attach the stepper motor to the base of the pill storage compartment using screws.
  • Mount the rotor securely onto the motor shaft, ensuring it rotates freely and aligns properly with the pill dispensing slots.
  • Test the alignment by rotating the rotor manually to check if it dispenses pills correctly.

Connect the Electronics

  • Wire the 28BYJ-48 stepper motor to the ULN2003 motor driver.
  • Connect the motor driver to the Particle Photon 2 microcontroller, following the pinout provided in the motor driver documentation.
  • Ensure the connections are secure and the wiring is neat to avoid interference during operation.

Test the Mechanism

Use the following test code to ensure the mechanism works as intended:

#include "Particle.h"

// Define the stepper motor pins
const int IN1 = D0; // Connect to IN1 on ULN2003
const int IN2 = D1; // Connect to IN2 on ULN2003
const int IN3 = D2; // Connect to IN3 on ULN2003
const int IN4 = D3; // Connect to IN4 on ULN2003

// Define step sequence for 28BYJ-48 stepper motor
int steps[8][4] = {
    {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1},
    {1, 0, 0, 1}
};

int stepIndex = 0; // Current step position

// Function to move the motor by one step
void stepMotor(int direction) {
    // Set the pins based on the current step
    digitalWrite(IN1, steps[stepIndex][0]);
    digitalWrite(IN2, steps[stepIndex][1]);
    digitalWrite(IN3, steps[stepIndex][2]);
    digitalWrite(IN4, steps[stepIndex][3]);

    // Update the step index
    stepIndex += direction;
    if (stepIndex > 7) {
        stepIndex = 0;
    } else if (stepIndex < 0) {
        stepIndex = 7;
    }

    // Add a short delay for smooth operation
    delay(2);
}

// Function to rotate the motor by a specific number of steps
void rotateMotor(int steps, int direction) {
    for (int i = 0; i < steps; i++) {
        stepMotor(direction);
    }
}

void setup() {
    // Set stepper motor pins as outputs
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);

    // Initialize the pins to LOW
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);

    // Log to the console
    Serial.begin(9600);
    Serial.println("Stepper motor ready to dispense!");
}

void loop() {
    // Example: Rotate motor clockwise 90 degrees to dispense one pill
    Serial.println("Dispensing a pill...");
    rotateMotor(512, 1); // 512 steps for ~90-degree rotation
    delay(2000);         // Wait 2 seconds between operations
}

Fine-Tune for Reliability

  • If the pills are jamming or dispensing incorrectly, adjust the rotor’s cutouts or the alignment of the motor and compartment.
  • Test with multiple pill sizes if needed to ensure versatility.

Step three: add the display and button

The 2-inch Waveshare LCD display plays a key role in the project by providing vital information to the user. It displays the current time, along with feedback confirming that the pill is being dispensed and showing the pill’s name.

Prepare the LCD display

  • Use a 2-inch Waveshare LCD display to show essential feedback to users.
  • Operates at 3.3V/5V using the SPI interface for communication.
  • Key specifications:
    • Resolution: 240 (V) x 320 (H) RGB.
    • Display area: 30.60 (H) x 40.80 (V) mm.

Connect the display pins

Connect the display pins to the Particle Photon 2:

  • VCC: Connect to 3.3V or 5V pin.
  • GND: Connect to ground.
  • DIN (MOSI): Connect to the MOSI pin (e.g., D2).
  • CLK (SCK): Connect to the SCK pin (e.g., D1).
  • DC: Connect to a GPIO pin (e.g., D4).
  • CS: Connect to a GPIO pin (e.g., D5).
  • RST: Connect to a GPIO pin (e.g., D6).
  • BL: (Optional) Connect to a PWM pin for backlight brightness.

Install the push button

 

  • Four output pins:
    • Two for the LED (positive and ground).
    • Two for the signal output to detect button presses.

Connect the push button

  • Wire the LED pins to a power source (e.g., 3.3V or 5V) and ground.
  • Wire the signal pins to GPIO pins on the Photon (e.g., D7) and ground.

Test code for display and button setup

#include "Particle.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ST7789.h"

// Define pins for the display
#define TFT_CS D5
#define TFT_RST D6
#define TFT_DC D4

// Create display object
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// Define pin for the button
#define BUTTON_PIN D7
#define LED_PIN A5

void setup() {
    // Initialize display
    tft.init(240, 320);
    tft.setRotation(1);
    tft.fillScreen(ST77XX_BLACK);
    tft.setTextColor(ST77XX_WHITE);
    tft.setTextSize(2);
    tft.setCursor(10, 10);
    tft.print("Smart Pill Dispenser");

    // Initialize button and LED
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    // Check button state
    if (digitalRead(BUTTON_PIN) == LOW) {
        digitalWrite(LED_PIN, HIGH); // Turn on LED
        tft.setCursor(10, 50);
        tft.print("Button Pressed");
    } else {
        digitalWrite(LED_PIN, LOW); // Turn off LED
    }
}

Step four: circuit & PCB

Test the system on a breadboard

  • Begin by connecting all components on a breadboard to verify functionality.
  • Use a 5V 2A power supply, which is sufficient since only one stepper motor and the display operate simultaneously.
  • Approximate power consumption:
    • 28BYJ-48 Stepper Motor: 1 Watt (5V, 200 mA).
    • 2-Inch Waveshare Display: 0.2 Watts (5V, 40 mA).
    • Particle Photon 2: Up to 0.9 Watts (5V, 180 mA).
  • The total estimated power consumption is about 2.1 Watts, well within the 10-watt capacity of the power supply.

Choose the powering method

  • The Particle Photon 2 offers several powering options:
    • Micro-USB port: Convenient for temporary setups.
    • VUSB pin: Ideal for a stable 5V input.
    • LiPo battery: Suitable for portable applications.
  • For this project, use the VUSB method to provide a stable 5V input directly to the board.

Design the PCB layout

  • Use EasyEDA software to create a compact and efficient two-layer PCB layout. Ensure:
    • Components are arranged to minimize signal interference.
    • Adequate power distribution to all components.
    • Mounting points for critical components like the motor driver.
  • Guidelines for placement:
    • Motor driver: Mount directly onto the PCB for stability.
    • Display and button: Connect via JST connectors for ease of assembly.
    • Power supply: Use a two-pin screw terminal block for secure connections.

Fabricate the PCB

  • Export the design files from EasyEDA and send them to a PCB manufacturer for fabrication.
  • Once the PCB is fabricated, inspect it for defects or inconsistencies.

Assemble the PCB

  1. Solder all components onto the PCB:
    • Attach JST connectors for the display and button.
    • Mount the ULN2003 motor driver securely.
    • Solder a two-pin screw terminal block for the power supply connection.
  2. Double-check solder joints to ensure solid connections and prevent short circuits.

Test the assembled PCB

Use the following test code to verify functionality:

#include "Particle.h"

// Pin definitions
#define MOTOR_PIN D0
#define DISPLAY_PIN D4
#define BUTTON_PIN D7

void setup() {
    pinMode(MOTOR_PIN, OUTPUT);
    pinMode(DISPLAY_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT_PULLUP);

    Serial.begin(9600);
    Serial.println("Testing PCB connections...");
}

void loop() {
    if (digitalRead(BUTTON_PIN) == LOW) {
        Serial.println("Button pressed! Testing motor...");
        digitalWrite(MOTOR_PIN, HIGH);
        delay(1000);
        digitalWrite(MOTOR_PIN, LOW);

        Serial.println("Testing display...");
        digitalWrite(DISPLAY_PIN, HIGH);
        delay(1000);
        digitalWrite(DISPLAY_PIN, LOW);
    }
}

Finalize integration

  • Secure the PCB into the dispenser housing.
  • Connect all external components (e.g., stepper motor, display, button) to the PCB using pre-soldered connectors.

Step five: design an enclosure

Plan the structure

  • Divide the enclosure into two primary sections:
    1. Upper section: Houses the dispensing mechanism.
    2. Bottom section: Contains the PCB with all connected components.
  • Ensure the design allows for stability and ease of access for assembly and maintenance.

Choose a color scheme

  • Opt for a visually appealing and modern theme.
  • For this project, a green and white color scheme was selected to give the dispenser a clean and professional look.

Design the enclosure

  1. Use 3D modeling software (e.g., Fusion 360 or TinkerCAD) to create the design.
    • Ensure precise measurements to accommodate all components, including:
      • The dispensing mechanism.
      • PCB.
      • Display and button.
  2. Include mounting points or slots for securing components like the PCB and stepper motor.
  3. Add a section for the pill collection cup, ensuring it aligns with the dispensing mechanism.

3D print the parts

  1. Print the enclosure using PLA+ filament for durability and a smooth finish.
  2. Ensure that all printed parts meet the intended dimensions and check for any warping or imperfections.

Test fit components

  1. Fit the PCB, stepper motors, button, and display into their respective sections.
  2. Verify proper alignment of all components within the enclosure.
  3. Make adjustments to the design or reprint parts as necessary.

Step six: put it all together

Assemble the upper section

  1. Attach the momentary button and the display to the upper portion of the dispenser’s body.
    • Ensure the button and display are securely mounted and properly aligned.
  2. Connect the button and display to their respective connectors on the PCB.

Prepare the dispensing mechanism

  1. Connect the stepper motors to the pill dispensing mechanisms.
    • Secure the motors to the mechanism using screws to ensure stability.
  2. Mount the prepared dispensers onto the supporter using M3 screws.

Attach the pill guide

  • Install the pill guide to direct the dispensed pills along a predefined path to the collection cup positioned below.

Prepare the PCB

  1. Solder the necessary headers, JST connectors, and a screw terminal block onto the PCB.
  2. Verify that all components are securely soldered and ready for integration.

Integrate the PCB into the bottom section

  1. Secure the PCB into the bottom portion of the dispenser’s body using screws or standoffs.
  2. Connect all external components (e.g., stepper motors, display, button) to the PCB via pre-soldered connectors.

Combine the upper and bottom sections

  1. Stack the upper and bottom sections together, ensuring all connections are secure.
  2. Use mounting screws to tighten the sections together.
  3. Insert a DC female jack into its designated spot to provide power to the device.

Add the collection cup

  • 3D print a collection cup and attach it beneath the pill dispensing mechanism to catch dispensed pills.

Power and test

  1. Plug in the device using the connected DC jack.
  2. Run a test program to ensure the dispensing mechanism, display, button, and other components function as expected.
    • Verify that pills are dispensed correctly and notifications are sent as programmed.

Step seven: add Firebase

Firebase is an integral part of the pill dispenser system, providing reliable back-end services that simplify development and ensure seamless communication between the web application and the hardware device. Its real-time capabilities and robust features make it an ideal choice for managing and synchronizing schedules, notifications, and user data.

Steps to integrate Firebase with Particle

  1. Set up Firebase Realtime Database:
    • Navigate to the Firebase Console and go to Build → Realtime Database.
    • Create a new database and note your database URL (e.g., https://<your-database-name>.firebaseio.com/).
  2. Create a Firebase webhook in Particle Console:
    • Go to the Particle Integrations page in the Particle Console.
    • Select the Firebase Webhook template.
    • Fill in the required details:
      • Integration Name: Choose a name (e.g., firebase-integration).
      • Firebase Host: Enter your database URL without https:// (e.g., <your-database-name>.firebaseio.com).
      • Firebase Access Token: Obtain your token from Project Settings → Service Accounts → Database Secrets in Firebase. If tokens are unavailable, create a service account and generate a private key JSON to extract the database secret.
  3. Send events to Firebase:
    • Use Particle.publish() in your device firmware to trigger the webhook. For example:
c
Particle.publish("firebase_event", "{\"temperature\": 25, \"humidity\": 60}", PRIVATE);
  • Replace firebase_event with the event name you configured in the webhook, and format the data in JSON.
  1. Verify integration:
    • Trigger an event from your Particle device.
    • Check your Firebase Realtime Database in the Firebase Console to ensure the data is stored correctly.

Web application

The web application acts as an interface for users to configure and manage the pill dispenser system remotely. It provides a seamless and user-friendly platform to set up pill schedules, monitor dispenser activity, and receive notifications.

  1. Pill scheduling:
    • Allows users to create and manage pill schedules with inputs such as:
      • Time of dispensing.
      • Medication name and dosage.
    • Automatically syncs these schedules with the pill dispenser device.
  2. Upcoming schedule viewer:
    • Displays the next scheduled doses at a glance.
    • Lists upcoming doses for the day, ensuring users are prepared.
  3. Notifications:
    • A Node.js API sends timely reminders to the user for their medication.
    • Notifications include details of the medication name, dosage, and scheduled time.
    • Alerts are sent via web push notifications.

Example code for sending events

void sendToFirebase(String pillName, int dose, String time) {
    String eventData = String::format("{\"pill_name\":\"%s\", \"dose\":%d, \"time\":\"%s\"}", pillName.c_str(), dose, time.c_str());
    Particle.publish("pill_schedule", eventData, PRIVATE);
}

 


With Firebase integrated and the web app functional, the Smart Pill Dispenser is ready for operation! Find the source code and assets for replication here: GitHub – Smart Pill Dispenser.


 

Comments are not currently available for this post.