🔥 Build Your Own MAX30100 Pulse Oximeter Webserver with Node MCU ESP8266 – Monitor Heart & SpO2 From your Phone in 2025!
In this project, you will learn how to make a MAX30100 Pulse Oximeter Webserver using NodeMCU ESP8266.
With this project, you can monitor heart rate and oxygen saturation (SpO2) values directly on a web server hosted by the NodeMCU. You can access this web server from any smartphone or PC that has Wi-Fi and a web browser.
This is perfect for Covid-19 monitoring or general health tracking at home.
Hardware Components
-
Node MCU ESP8266
-
MAX30100 Pulse Oximeter Sensor
-
Jumper wires
-
Breadboard or PCB (optional)
-
USB Cable for Node MCU
Code & Libraries
Required Libraries
-
MAX30100 Library – Install via Arduino Library Manager.
-
ESP8266WiFi – Comes with ESP8266 board support.
-
Wire – For I2C communication.
✅ Download Code & Libraries:
#include <ESP8266WebServer.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS 1000
float BPM, SpO2;
/*Put your SSID & Password*/
const char* ssid = "amhar";
const char* password = "Arduino";
PulseOximeter pox;
uint32_t tsLastReport = 0;
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
pinMode(16, OUTPUT);
delay(100);
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
Serial.print("Initializing pulse oximeter..");
if (!pox.begin()) {
Serial.println("FAILED");
for (;;);
} else {
Serial.println("SUCCESS");
}
}
void loop() {
server.handleClient();
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
Serial.print("BPM: ");
Serial.println(BPM);
Serial.print("SpO2: ");
Serial.print(SpO2);
Serial.println("%");
Serial.println("*********************************");
Serial.println();
tsLastReport = millis();
}
}
void handle_OnConnect() {
server.send(200, "text/html", SendHTML(BPM, SpO2));
}
void handle_NotFound() {
server.send(404, "text/plain", "Not found");
}
String SendHTML(float BPM, float SpO2) {
String ptr = "<!DOCTYPE html>";
ptr += "<html>";
ptr += "<head>";
ptr += "<title>ESP8266 WebServer</title>";
ptr += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
ptr += "<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css'>";
ptr += "<link rel='stylesheet' type='text/css' href='styles.css'>";
ptr += "<style>";
ptr += "body { background-color: #fff; font-family: sans-serif; color: #333333; font: 14px Helvetica, sans-serif box-sizing: border-box;}";
ptr += "#page { margin: 20px; background-color: #fff;}";
ptr += ".container { height: inherit; padding-bottom: 20px;}";
ptr += ".header { padding: 20px;}";
ptr += ".header h1 { padding-bottom: 0.3em; color: #008080; font-size: 45px; font-weight: bold; font-family: Garmond, 'sans-serif'; text-align: center;}";
ptr += "h2 { padding-bottom: 0.2em; border-bottom: 1px solid #eee; margin: 2px; text-align: left;}";
ptr += ".header h3 { font-weight: bold; font-family: Arial, 'sans-serif'; font-size: 17px; color: #b6b6b6; text-align: center;}";
ptr += ".box-full { padding: 20px; border 1px solid #ddd; border-radius: 1em 1em 1em 1em; box-shadow: 1px 7px 7px 1px rgba(0,0,0,0.4); background: #fff; margin: 20px; width: 300px;}";
ptr += "@media (max-width: 494px) { #page { width: inherit; margin: 5px auto; } #content { padding: 1px;} .box-full { margin: 8px 8px 12px 8px; padding: 10px; width: inherit;; float: none; } }";
ptr += "@media (min-width: 494px) and (max-width: 980px) { #page { width: 465px; margin 0 auto; } .box-full { width: 380px; } }";
ptr += "@media (min-width: 980px) { #page { width: 930px; margin: auto; } }";
ptr += ".sensor { margin: 12px 0px; font-size: 2.5rem;}";
ptr += ".sensor-labels { font-size: 1rem; vertical-align: middle; padding-bottom: 15px;}";
ptr += ".units { font-size: 1.2rem;}";
ptr += "hr { height: 1px; color: #eee; background-color: #eee; border: none;}";
ptr += "</style>";
//Ajax Code Start
ptr += "<script>\n";
ptr += "setInterval(loadDoc,1000);\n";
ptr += "function loadDoc() {\n";
ptr += "var xhttp = new XMLHttpRequest();\n";
ptr += "xhttp.onreadystatechange = function() {\n";
ptr += "if (this.readyState == 4 && this.status == 200) {\n";
ptr += "document.body.innerHTML =this.responseText}\n";
ptr += "};\n";
ptr += "xhttp.open(\"GET\", \"/\", true);\n";
ptr += "xhttp.send();\n";
ptr += "}\n";
ptr += "</script>\n";
//Ajax Code END
ptr += "</head>";
ptr += "<body>";
ptr += "<div id='page'>";
ptr += "<div class='header'>";
ptr += "<h1>MAX30100 ESP8266 WebServer</h1>";
ptr += "<h3><a href='https://www.instagram.com/incredible_...'>https://www.instagram.com/incredible_...</a></h3>";
ptr += "</div>";
ptr += "<div id='content' align='center'>";
ptr += "<div class='box-full' align='left'>";
ptr += "<h2>Sensor Readings</h2>";
ptr += "<div class='sensors-container'>";
//For Heart Rate
ptr += "<p class='sensor'>";
ptr += "<i class='fas fa-heartbeat' style='color:#cc3300'></i>";
ptr += "<span class='sensor-labels'> Heart Rate </span>";
ptr += (int)BPM;
ptr += "<sup class='units'>BPM</sup>";
ptr += "</p>";
ptr += "<hr>";
//For Sp02
ptr += "<p class='sensor'>";
ptr += "<i class='fas fa-burn' style='color:#f7347a'></i>";
ptr += "<span class='sensor-labels'> Sp02 </span>";
ptr += (int)SpO2;
ptr += "<sup class='units'>%</sup>";
ptr += "</p>";
ptr += "</div>";
ptr += "</div>";
ptr += "</div>";
ptr += "</div>";
ptr += "</div>";
ptr += "</body>";
ptr += "</html>";
return ptr;
}How It Works
-
The MAX30100 sensor measures heart rate and SpO2.
-
NodeMCU reads this data via I2C.
-
NodeMCU runs a web server and serves an HTML page with real-time values.
-
Open a browser on any device connected to the same Wi-Fi to monitor your health.
Conclusion
You now have your own DIY MAX30100 Pulse Oximeter Webserver at home! 🎉
-
Easy to build
-
Monitors your heart rate & oxygen level
-
Access it from your PC, smartphone, or tablet
This is a perfect DIY project for winter
.jpg)
Comments
Post a Comment