Disclaimers: I am not a health care professional. Nothing in this article is medical advice.
In my previous article Build a DIY Wifi connected MQTT reporting IoT Pulse Oximeter and Heart Rate Monitor I provided code for a pulse oximeter project. That provided code was error-riddled and was not the correct code for the project. Indeed, that provided code simply could not work. However, I did build a functional pulse oximeter with WiFi and MQTT support. The problem was that my workstation used to flash embedded devices at this time experienced hardware failure. I backed up the data, but squirreled it away without much followup thought.
I recently revisited the pulse oximeter project which had me examining my old article, and I was aghast at the code provided in the article. Sadly, I excluded Arduino projects from my personal git server and lack quality documentation associated with Arduino sketches from that time period. I went digging through my code archives and found what I believe to be the most up-to-date and functional version of the code. I believe this is the code that I have on my built embedded device. Again, to make practical use of this, you’ll need to substitute real values for variables for WiFi network, passwords, MQTT server address, user credentials, and you’ll need to define the WiFi hostname also used as the MQTT Topic.
I moderately tested this code on alternate hardware and it ‘appears’ to work, but I’ve not flashed this code to the previous hardware to replace a known good device. This project was posted years ago, now, and like all old code, libraries and IDEs have changed, while my static code has not been updated. I can’t guarantee this code will work, but I wanted to deliver more accurate and reliable code than what was in the original article.
This code is provided with NO WARRANTY.
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS 5000
PulseOximeter pox;
uint32_t tsLastReport = 0;
// Network SSID
const char* ssid = "WIFINETWORKNAME";
const char* password = "WIFINETWORKPASSWORD";
// MQTT
const char* mqttServer = "MQTTSERVERIPADDRESS";
const char* mqttUsername = "MQTTUSERNAME";
const char* mqttPassword = "MQTTPASSWORD";
char pubTopic[] = "MQTTTOPIC";
float bpm;
int os;
WiFiClient espClient;
PubSubClient mqttClient(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void onBeatDetected()
{
Serial.println("Beat!");
}
void setup()
{
Serial.begin(115200);
delay(6000);
Serial.println(espClient);
// Connect WiFi
WiFi.hostname("MQTTTOPIC");
WiFi.begin(ssid, password);
mqttClient.setServer(mqttServer, 1883);
if (mqttClient.connect("MQTTTOPIC", mqttUsername,mqttPassword)){
Serial.println("mqtt Connected");
}
else{
Serial.println("MQTT Connection failed ");
Serial.println(mqttClient.state());
}
Serial.print("Initializing pulse oximeter..");
// client.connect(clientId.c_str(), mqttUsername,mqttPassword)
// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
} else {
Serial.println("SUCCESS");
}
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
}
void loop()
{
// Make sure to call update as fast as possible
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.print("bpm / SpO2:");
Serial.print(pox.getSpO2());
bpm = (pox.getHeartRate());
os = (pox.getSpO2());
Serial.println("%");
Serial.println(bpm);
Serial.println(os);
mqttClient.publish("MQTTTOPIC/os", String(os).c_str());
delay(100);
mqttClient.publish("MQTTTOPIC/bpm",String(bpm).c_str());
tsLastReport = millis();
// mqttClient.publish()
}
}