Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Prajakta P
Published

IoT-Based Remote Patient Monitoring System to Measure Vital

When we are talking about major vital signs of a human body, there are four major parameters that we need to be aware of, they are body temp

BeginnerProtip5 hours1,366
IoT-Based Remote Patient Monitoring System to Measure Vital

Things used in this project

Story

Read more

Schematics

screenshot_2023-04-12_at_11_42_55_am_FgYtErDvzz.png

Code

Untitled file

C/C++
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include "MAX30100.h"
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <U8x8lib.h>
#include <avr/dtostrf.h>
#define REPORTING_PERIOD_MS     500   //update rate of hr, spo2, ambient, object, hrv, etc parameters in milli seconds 
#define DISPLAY_INTERVAL        5     //update rate for the i2c display = REPORTING_PERIOD_MS*DISPLAY_INTERVAL
#define COMPENSATION            5     //compensation in object temperature. Different body parts have different temperatures. Fingers are around 5 degF lower than core body temperature
// objects
PulseOximeter pox;    //this offers spo2 and hr calculation 
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
MAX30100 sensor;
//variables
uint32_t tsLastReport = 0;
int hr, spo2, count = 0, flag = 0, PatientID = 0;
float ambient, object, hrv;
long time1 = 0, time2 = 0; 
uint16_t ir = 0, red = 0, ecg = 0, mic; ;
char str_hrv[10], str_object[10], str_ambient[10], str_ir[10], str_red[10];
// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
    time1 = micros() - time2;
    time2 = micros();
}
void setup()
{
    //display connected
    u8x8.begin();
    u8x8.setPowerSave(0);
    u8x8.setFont(u8x8_font_chroma48medium8_r);
    //pinMode(10, INPUT); // Setup for leads off detection LO +
    //pinMode(11, INPUT); // Setup for leads off detection LO -
    Serial.begin(115200);
    /*
    while (!Serial) {
      ; // wait for serial port to connect. Needed for native USB port only
    }
    */
    // Initialize the PulseOximeter instance
    // Failures are generally due to an improper I2C wiring, missing power supply
    // or wrong target chip
    if (!pox.begin(PULSEOXIMETER_DEBUGGINGMODE_RAW_VALUES)) {
        //Serial.println("FAILED");
        for(;;);
    } else {
        //Serial.println("SUCCESS");
    }
    // The default current for the IR LED is 50mA and it could be changed
    //   by uncommenting the following line. Check MAX30100_Registers.h for all the
    //   available options.
    pox.setIRLedCurrent(MAX30100_LED_CURR_11MA);
    // Register a callback for the beat detection
    pox.setOnBeatDetectedCallback(onBeatDetected);
    mlx.begin();
    time2 = micros();
}
void loop()
{
    // Make sure to call update as fast as possible
    pox.update();
    sensor.update();
    //reading continuous functions (signals) every loop
    while (sensor.getRawValues(&ir, &red)) {}
    ecg = analogRead(A0);
    ecg = map(ecg, 250, 500, 0, 100);
    mic = analogRead(A1);
    delay(1);
    // Asynchronously calculate other variables every REPORTING_PERIOD_MS
    // For hr and spo2, a value of 0 means "invalid", for object and ambient temperatures a value less than 70 degF or higher than 110 degF can be considered abnormal
    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        hr = pox.getHeartRate();
        spo2 = pox.getSpO2();
        ambient = mlx.readAmbientTempF();
        object = mlx.readObjectTempF() + COMPENSATION;
        hrv = (60000000/hr - (float)time1)/1000;
        //send_serial();
        tsLastReport = millis();
        count++;
        flag = 0;
    }
    //Display all variables on the display after DISPLAY_INTERVAL seconds
    if ((count%DISPLAY_INTERVAL == 0) && (flag != 1)) {
      flag = 1;   //This flag makes sure the display is updated only once every DISPLAY_INTERVAL seconds
      Wire.end();
      send_display();
      Wire.begin();     
    }
    Telemetry();
}
//serial monitor print function. 
//Not required actually as telemetry function prints all values in csv format on the serial monitor
void send_serial() {
  Serial.print("bpm / SpO2:");
  Serial.print("Heart rate:");
  Serial.print(hr);
  Serial.print(spo2);
  Serial.print("% / hrv:");
  Serial.print(hrv);
  Serial.print("ms / Ambient:");
  Serial.print(ambient); 
  Serial.print("*F / tObject = "); 
  Serial.print(object); 
  Serial.println("*F");
}
//display print function
void send_display() {
  u8x8.clearDisplay();
  u8x8.setCursor(0,1);
  u8x8.print("HRV:"); 
  u8x8.print(hrv);
  u8x8.print(" ms");
  u8x8.setCursor(0,2);
  u8x8.print("SpO2:");
  u8x8.print(spo2);
  u8x8.print(" %");
  u8x8.setCursor(0,3);
  u8x8.print("HR:");
  u8x8.print(hr);
  u8x8.print(" bpm");
  u8x8.setCursor(0,4);
  u8x8.print("Temp:");
  u8x8.print(object);
  u8x8.print(" degF");
  u8x8.setCursor(0,5);
  u8x8.print("ecg:");
  u8x8.print(ecg);
  u8x8.setCursor(0,6);
  u8x8.print("mic");
  u8x8.print(mic);
  //delay(200); 
}
//serial telemetry for edge impulse data forwarder
void Telemetry() {
  char buffer[150];
  dtostrf(hrv, 4, 2, str_hrv);
  dtostrf(object, 4, 2, str_object);
  dtostrf(ambient, 4, 2, str_ambient);
  dtostrf((float)ir/100, 5, 2, str_ir);
  dtostrf((float)red/100, 5, 2, str_red);
  sprintf(buffer,"%d,%d,%d,%d,%s,%s,%s,%s,%s,%d,%d",PatientID,count/10,hr,spo2,str_hrv,str_object,str_ambient,str_ir,str_red,ecg,mic);
  Serial.println(buffer);

Credits

Prajakta P

Prajakta P

1 project • 0 followers
I am passionate about new technology like IoT and Industry 4.0 solutions. Loves to solve problems and get more reliable solutions.

Comments