Build a Multi-Sensor Health Analyzer With ESP32 (Temp + SpO2 + Heart Rate)
by sxmnath in Circuits > Electronics
942 Views, 6 Favorites, 0 Comments
Build a Multi-Sensor Health Analyzer With ESP32 (Temp + SpO2 + Heart Rate)
What if a few sensors could do more than just show numbers — what if they could interpret your health in real time?
In this project, you’ll build a smart health monitoring system using ESP32 that measures temperature, heart rate, and blood oxygen — and combines them to detect conditions like stress, fever risk, and respiratory issues.
Unlike typical sensor projects, this system doesn’t just display data — it analyzes it, sends it to the cloud, and shows meaningful insights on a live dashboard.
What makes this different from a basic Arduino serial monitor demo:
- Uses multiple sensors together (not isolated readings)
- Converts raw data into health insights
- Fully connected system: ESP32 → Cloud → Dashboard
- Supports multiple devices
- No WiFi hardcoding (plug-and-play setup)
This Can Be Used For:
- Remote patient monitoring
- Elderly care
- Fitness tracking
- Early illness detection
Supplies
Hardware
- ESP32 development board (38-pin, any variant)
- TMP117 High-Accuracy Temperature Sensor — SparkFun or Adafruit I2C breakout
- MAX30102 Pulse Oximeter and Heart-Rate Sensor module
- Breadboard + jumper wires
- Micro USB cable
- USB power bank or 5V adapter for standalone use
Arduino Libraries (install via Library Manager)
- SparkFun_MAX3010x_Sensor_Library
- Adafruit TMP117
- WiFiManager by tzapu
Software & Services (all free)
- Arduino IDE 2.x with ESP32 board support installed
- Node.js v18+ — for running the backend locally
- MongoDB Atlas — free M0 tier cloud database
- Render.com — free tier for hosting the backend (serves the dashboard too)
- GitHub account — to deploy to Render
How It All Fits Together
Fig. Architecture block diagram
Before touching any hardware, here is the full system architecture. Everything flows in one direction: sensors → ESP32 → cloud backend → dashboard.
Key design decisions: both sensors share the same I2C bus (SDA GPIO21, SCL GPIO22). The backend serves the frontend — no separate hosting needed. The sensor fusion engine runs server-side so the dashboard stays simple.
How This Project Uses Sensors
- TMP117 → measures precise body temperature
- MAX30102 → measures heart rate and SpO₂ using light
- ESP32 reads both sensors via I2C
- Data is combined to detect:
- Stress
- Fever risk
- Respiratory issues
Wiring the Sensors
Fig. Wiring diagram or Fritzing schematic Fig. Breadboard wiring close-up
Both the TMP117 and MAX30102 run on 3.3V and use I2C. They share the same two data lines on the ESP32 — just 4 wires total for both sensors.
Pinout Table
Default I2C addresses: TMP117 = 0x48, MAX30102 = 0x57. No conflicts. SparkFun and Adafruit breakout boards have onboard pull-up resistors — no external resistors needed.
Install Libraries
Install Libraries in Arduino IDE
Go to Sketch → Include Library → Manage Libraries and search for:
- Adafruit TMP117
- SparkFun MAX3010x Pulse and Proximity Sensor Library by SparkFun Electronics
- WiFiManager by tzapu
Install these and you'll be all set to upload the firmware on the ESP32.
Flash the Firmware
Fig. Arduino IDE Serial Monitor showing live readings
Firmware Code
Create a new sketch, paste the code below. Only one thing to change: update serverURL to your own Render backend URL after deployment.
Downloads
Connect ESP32 to WiFi (First Boot Setup)
Fig. WiFi Manager Page
This step connects your ESP32 to your home WiFi using WiFiManager — no coding required.
Steps
1.Power ON your ESP32
2.On your phone, open WiFi settings
3.Connect to:
4.A browser page will open automatically
(If not, go to 192.168.4.1)
5.Select your home WiFi network
6.Enter your password and click Save
-> if you cant see the "HealthMonitor-Setup" network, restart the ESP32.
Backend — Node.js + MongoDB Atlas
Fig. Render dashboard showing backend deployed and live
MongoDB Atlas Setup
1. Create a free account at mongodb.com/atlas and create an M0 (free) cluster.
2. Add a database user and set network access to 0.0.0.0/0.
3. Copy your connection string — it looks like:
File structure
models/SensorData.js
fusion/healthFusion.js — the sensor fusion engine
This is the most interesting backend file. It takes all three vitals together and applies rule-based logic to flag health conditions:
Risk score thresholds used by the dashboard: 0-1 = Normal, 2-3 = Mild Risk, 4-6 = Moderate Risk, 7+ = High Risk.
routes/dashboard.js
server.js
package.json dependencies
Deploy to Render
1. Push the full repo to GitHub.
2. On Render.com create a new Web Service, connect your repo.
3. Set Root Directory to esp32-backend, Build Command to npm install, Start Command to node server.js.
4. Add environment variable: MONGO_URI = your Atlas connection string.
5. Deploy. Render gives you a public URL — paste it into the serverURL in your firmware.
The Dashboard
Fig. Full Dashboard and Its Mobile View
The dashboard is pure HTML + CSS + JS — no framework, no build step. It is served directly by the Express backend via express.static, so there is nothing extra to deploy.
How it works
app.js polls GET /api/dashboard every 3 seconds. The response includes the latest vitals and the fusion result. The dashboard renders vitals as large numbers with animated progress bars, and the fusion indicators as insight cards with color-coded risk status.
app.js -core polling logic
The dashboard also supports multiple devices via a deviceNameMap object — ESP32_01 shows as Patient 1, ESP32_02 as Patient 2, and so on.
Testing & Results
Fig. Serial Monitor showing Data and sending it with confirmation 200 And Final Working Model
With firmware flashed and backend deployed:
- On first boot connect your phone to the HealthMonitor-Setup WiFi hotspot and enter your credentials in the portal
- Open the Serial Monitor at 115200 baud — you should see WiFi connected, both sensors initialised, and readings printing every loop
- Place your fingertip firmly on the MAX30102 sensor (the red/IR emitter side) and hold still
- If HR or SpO2 shows -1, the finger is not fully detected — keep still for 5-10 seconds until the algorithm validates the signal
- Open your Render URL in any browser to see the live dashboard
- The dashboard updates every 3 seconds, the ESP32 posts every 5 seconds
Expected readings at rest:
- Body temperature: 36.0°C – 37.5°C (fingertip reads slightly lower than core temp)
- Heart rate: 60–100 BPM
- SpO2: 95–100% for healthy individuals
- Fusion status: Normal (risk score 0-1)
How the Sensors Work
TMP117 — Why precision matters
The TMP117 is not a hobbyist temp sensor. It uses a silicon bandgap reference and a 16-bit ADC to achieve ±0.1°C accuracy with NIST-traceable calibration — the same spec used in medical devices. Compare that to DHT22 (±0.5°C) or LM35 (requires external calibration). For body temperature where 0.5°C is the difference between normal and low-grade fever, this accuracy is not a luxury. The Adafruit library wraps it in the Adafruit unified sensor abstraction (sensors_event_t), making it drop-in compatible.
MAX30102 — Photoplethysmography (PPG)
The MAX30102 shines red (660nm) and infrared (880nm) LEDs through your fingertip and measures reflected light. Oxygenated and deoxygenated haemoglobin absorb these wavelengths at different ratios. The pulsatile component of the signal gives heart rate (peaks = beats), and the red-to-IR absorption ratio gives SpO2. Maxim's spo2_algorithm.h handles all the DSP — it needs 100 samples to calculate a result, which is why the firmware fills a buffer of 100 before running the calculation. The validHeartRate and validSPO2 flags tell you whether the finger contact was good enough to trust the result.
Sensor fusion
Most health monitors just display raw numbers. healthFusion.js cross-references all three vitals simultaneously. For example: high HR + normal SpO2 + normal temp = likely stress, not fever. Low SpO2 + normal HR = respiratory concern, not exertion. This multi-variable logic is what makes the AI Health Insights section meaningful rather than just repeating the numbers.
Possible Improvements
- Add an OLED display (SSD1306) for standalone readings without needing a phone — the I2C bus already has capacity
- Use FreeRTOS tasks to read TMP117 and MAX30102 concurrently instead of sequentially
- Add Telegram or email alerts when SpO2 drops below 94% or temperature exceeds 38°C
- Expand the fusion rules in healthFusion.js — add dehydration heuristics, recovery tracking
- Add a chart view to the dashboard showing historical trends using Chart.js
- Switch from polling to WebSockets for true push-based updates
- Add a second ESP32 node and test the multi-device deviceId routing
- 3D print a wearable enclosure
Source Code & Live Demo
GitHub: github.com/sxmnath/healthMonitor
Live dashboard: health-monitor-server-2pbh.onrender.com
Conclusion
This project covers the full IoT stack from sensor hardware to cloud backend to live dashboard — and adds a layer of intelligence with the sensor fusion engine that most similar projects skip entirely. The TMP117 and MAX30102 are genuinely capable sensors, WiFiManager makes the device actually deployable without recompiling for every new WiFi network, and the multi-device architecture means it scales beyond a single node.
Everything runs for free: MongoDB Atlas free tier, Render.com free tier, and the ESP32 itself costs under ₹500. If you build it, share your readings in the comments — especially if you extend the fusion rules or add new sensors.