A full-stack IoT system designed for automated medicine dispensing, patient adherence tracking, and real-time alerts. This system seamlessly integrates an ESP8266-based hardware dispenser, a Node.js API server, a MySQL database, and a responsive web dashboard for nurses/caregivers to manage medication schedules efficiently.
- Automated Dispensing: Dispenses medicine reliably at exact scheduled times using a high-precision DS3231 RTC and a servo motor mechanism.
- Adherence Tracking: An IR sensor validates if the patient actually picked up the medication after it was dispensed.
- Real-time Status Updates: Medication statuses transition seamlessly through
PENDING→DISPENSED→TAKEN. If the patient fails to take the medication within an allotted time, it triggers aNOT_TAKENalert. - Nurse Dashboard: A responsive web interface for managing patient schedules, beds, and tracking real-time dispensing events.
- Offline Tolerance: Uses RTC time to safely trigger dispenses even if internet connectivity momentarily drops.
- Hardware (Firmware): ESP8266 (NodeMCU 1.0), C++ (Arduino Framework), Servo Motor, DS3231 RTC Module, IR Obstacle Sensor, Buzzer.
- Backend: Node.js, Express.js, RESTful API.
- Database: MySQL.
- Frontend: HTML5, CSS3, Vanilla JavaScript.
New folder/
├── database/
│ └── schema.sql ← Run this first in MySQL to create the db and tables
├── backend/
│ ├── .env ← Database connection configuration
│ ├── server.js ← Main API server entry point
│ ├── db.js ← MySQL database connection pool
│ └── routes/
│ ├── schedule.js ← Schedule CRUD API routes
│ └── status.js ← Status updates & alerts API routes
├── frontend/
│ ├── index.html ← Nurse Dashboard UI
│ ├── style.css ← Dashboard styles
│ └── app.js ← Dashboard interactive logic
└── firmware/
└── medicine_dispenser/
└── medicine_dispenser.ino ← Firmware to flash to ESP8266
- Open MySQL Workbench or your preferred MySQL CLI.
- Execute the provided schema file to create the database and tables:
source database/schema.sql;
- Navigate to the
backenddirectory. - Create or edit the
.envfile to match your MySQL credentials:DB_PASS=your_mysql_password PORT=3000
- Install dependencies and start the server:
cd backend npm install npm start - The API Server will run at
http://localhost:3000. The frontend dashboard is statically served at the same URL.
Instead of manually setting up MySQL and Node.js (Steps 1 & 2), you can spin up the entire application stack using Docker Compose:
- Make sure you have Docker and Docker Compose installed.
- Build and start the containers from the project root:
docker-compose up --build -d
- This will automatically start:
medisync-db: A MySQL database container (automatically initialized and seeded withdatabase/schema.sql).medisync-backend: The Node.js API server and static Nurse Dashboard container.
- The dashboard and API will be available at
http://localhost:3000.
- Open
firmware/medicine_dispenser/medicine_dispenser.inoin the Arduino IDE. - Update the configuration variables at the top of the sketch:
const char* WIFI_SSID = "Your_WiFi_SSID"; const char* WIFI_PASS = "Your_WiFi_Password"; const char* SERVER_HOST = "http://<YOUR_PC_IP_ADDRESS>:3000"; // Find your local IP via 'ipconfig' const char* BED_ID = "BED-01";
- Install required libraries via the Arduino Library Manager (Tools → Manage Libraries):
ArduinoJsonby Benoit Blanchon (v6.x)RTClibby AdafruitServoby Michael Margolis
- Select your board: NodeMCU 1.0 (ESP-12E Module).
- Compile and Upload the code to your ESP8266.
Warning
Safety First: The firmware uses modem sleep instead of deep sleep to save power while keeping the RTC state intact. Do NOT connect the DS3231 INT/SQW pin to the ESP8266 RST pin, nor D0 to RST, as it is unsafe without proper diode+resistor isolation and is not needed for this setup.
| Component | NodeMCU Pin | ESP8266 GPIO |
|---|---|---|
| DS3231 SDA | D2 | GPIO4 |
| DS3231 SCL | D1 | GPIO5 |
| Servo Signal | D4 | GPIO2 |
| IR Sensor OUT | D5 | GPIO14 |
| Buzzer (+) | D6 | GPIO12 |
| VCC | 3V3 (or Vin if using 5V modules) | — |
| GND | GND | — |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/schedules |
Create a new medication schedule |
GET |
/api/schedules |
List all schedules (supports filtering) |
GET |
/api/schedules/beds |
Retrieve a list of all managed beds |
GET |
/api/schedules/device/:bedId |
Device fetches its daily schedule |
DELETE |
/api/schedules/:id |
Delete a specific schedule |
POST |
/api/status/update |
Device reports dispensing status back to server |
GET |
/api/status/alerts |
Dashboard polls for NOT_TAKEN alerts |
GET |
/api/status/logs |
Fetch full activity/event history |
GET |
/api/health |
Backend health check endpoint |
PENDING: Scheduled time is in the future.DISPENSED: Motor has activated to drop the pill, waiting for the patient to pick it up (IR sensor check).TAKEN: IR sensor confirms the patient's hand disrupted the beam, meaning the pill was retrieved.NOT_TAKEN: If the IR sensor is not triggered within a set timeout (e.g., 20 mins) after dispensing, an alert is raised on the Nurse Dashboard.