A full-stack IoT system for real-time health monitoring using ESP32, MAX30102, Raspberry Pi, MQTT, SQLite, Flask, and a React-based dashboard.
It streams heart rate, SpO₂, temperature, and steps from a wearable device to a Raspberry Pi, stores the data locally, and visualizes it in a beautiful web UI.
┌────────┐ I2C ┌──────────────┐ MQTT ┌───────────────┐
│ MAX30102│────────────▶│ ESP32 │──────────────▶│ Mosquitto │
└────────┘ │ Firmware │ │ (MQTT Broker) │
└──────────────┘ └──────┬─────────┘
│
SQLite Store ◀──┘
(Flask Backend)
│
▼
React Dashboard (Live UI)
/
├── esp32/ # ESP32 firmware
│ └── esp32_max30102_mqtt.ino
│
├── raspberry-pi/ # Backend server (MQTT + SQLite + Flask)
│ ├── main.py
│ ├── requirements.txt
│ └── app/
│ ├── api.py
│ ├── mqtt_handler.py
│ ├── database.py
│ └── config.py
│
└── web-dashboard/ # React + Vite frontend
├── src/
│ ├── pages/
│ │ ├── Dashboard.tsx
│ │ ├── Devices.tsx
│ │ ├── History.tsx
│ │ ├── Index.tsx
│ │ └── NotFound.tsx
│ └── components/health/
│ ├── VitalCard.tsx
│ ├── LiveChart.tsx
│ └── HealthStatusCard.tsx
└── package.json
- Reads Heart Rate & SpO₂ using MAX30102
- Reads temperature sensor
- Step counter (optional)
- Publishes values via MQTT as JSON
esp32/health
{
"heartRate": 82,
"spo2": 98,
"temperatureC": 36.5,
"steps": 24
}- SparkFun MAX3010x Sensor Library
- PubSubClient
Install via Arduino IDE → Library Manager.
Upload at 115200 baud.
Runs three key services:
Receives ESP32 readings and stores them in SQLite.
Stores timestamped health data.
Used by the dashboard to fetch live and historical vitals.
sudo apt update && sudo apt upgrade -ysudo apt install mosquitto mosquitto-clients -y
sudo systemctl enable mosquittosudo apt install python3 python3-pip -y
pip install -r requirements.txtflask
flask-cors
paho-mqtt
python3 main.pyhttp://<raspberry-pi-ip>:5000
Returns the most recent reading.
Returns the last 10 readings.
Manual data insert.
Payload:
{
"heartRate": 75,
"spo2": 98,
"temperatureC": 36.8,
"steps": 4
}#3. Web Dashboard (React + Tailwind + ShadCN)
A modern, responsive UI showing:
- Live heart rate + SpO₂
- Step count
- Real-time charts
- Device management
- Health evaluation (healthy / caution / critical)
- History export to CSV
npm installnpm run devThe dashboard will be available at:
http://localhost:5173
Make sure your Raspberry Pi backend is running on:
http://localhost:5000
(or replace API_BASE_URL)
Values flagged as:
- Healthy
- Caution
- Critical
Used in:
- Dashboard alerts
- Status badges
- CSV export
Backend config:
raspberry-pi/app/config.py
MQTT_BROKER = "localhost"
MQTT_PORT = 1883
MQTT_TOPIC = "esp32/health"
SQLITE_DB = "health_data.db"
FLASK_PORT = 5000
Dashboard config:
src/pages/Dashboard.tsx
const API_BASE_URL = "http://localhost:5000";
Change these if hosting on different devices.