Hi, I'm doing a project where I have to constantly monitor health (heart rate and spo2) of the patient and also his/her motion i.e. if he/she falls down then I have to notify the caregivers.
In this project, I'm using MAX30100 Pulse oxi sensor, NEO-6M GPS, ESP32, MPU6050 Accelerometer/Gyroscope. Here is the code that I'm using for fall detection and health monitoring -
#include <TinyGPS++.h>
#include "MAX30100_PulseOximeter.h"
#include <Blynk.h>
#include <Arduino.h>
#include <HardwareSerial.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <BlynkSimpleEsp32.h>
#define REPORTING_PERIOD_MS 1000
#define BLYNK_PRINT Serial
void sendSMS();
String serverName = "https://maker.ifttt.com/trigger/FALL/with/key/xxxxxxxxxxxxxxxxxxxxxxxxx";
WidgetLCD lcd(V5);
boolean fall = false; //stores if a fall has occurred
boolean trigger1=false; //stores if first trigger (lower threshold) has occurred
boolean trigger2=false; //stores if second trigger (upper threshold) has occurred
boolean trigger3=false; //stores if third trigger (orientation change) has occurred
byte trigger1count=0; //stores the counts past since trigger 1 was set true
byte trigger2count=0; //stores the counts past since trigger 2 was set true
byte trigger3count=0; //stores the counts past since trigger 3 was set true
int angleChange=0, c=0;
const int MPU_addr=0x68;
int16_t accelX, accelY, accelZ, gyroX, gyroY, gyroZ;
float gForceX, gForceY, gForceZ,rotX, rotY, rotZ,Tmp;
uint32_t tsLastReport = 0;
PulseOximeter pox;
float BPM=1.00, SpO2=1.00;
float latitude , longitude;
String latitude_string , longitiude_string;
char auth[] = "xxxxxxxxxxxxxxxxxxxx";
WidgetMap myMap(V0);
WiFiClient client;
TinyGPSPlus gps;
HardwareSerial SerialGPS(2);
void onBeatDetected()
{
Serial.println("Beat Detected!");
}
void setup()
{
Serial.begin(115200);
WiFi.begin("xxxxxxxxxxx", "cccccccccccc");
uint32_t notConnectedCounter = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.println("Wifi connecting...");
notConnectedCounter++;
if(notConnectedCounter > 50) { // Reset board if not connected after 5s
Serial.println("Resetting due to Wifi not connecting...");
ESP.restart();
}
}
Serial.print("Wifi connected, IP address: ");
Serial.println(WiFi.localIP());
Blynk.begin(auth, "xxxxxxxxxxxxx", "cccccccccccccc");
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
SerialGPS.begin(9600, SERIAL_8N1, 16, 17);
delay(1000);
pinMode(19, OUTPUT);
Serial.print("Initializing Pulse Oximeter..");
if (!pox.begin())
{
Serial.println("FAILED");
for(;;);
}
else
{
Serial.println("SUCCESS");
pox.setOnBeatDetectedCallback(onBeatDetected);
}
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
Blynk.virtualWrite(V0, "clr");
}
void loop()
{
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers
accelX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
accelY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
accelZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
gyroX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
gyroY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
gyroZ=Wire.read()<<8|Wire.read();
gForceX = (accelX-2050) / 16384.0;
gForceY = (accelY-77) / 16384.0;
gForceZ = (accelZ-1947) / 16384.0;
rotX = (gyroX+270) / 131.0;
rotY = (gyroY-351) / 131.0;
rotZ = (gyroZ+136) / 131.0;
// calculating Amplitute vactor for 3 axis
float Raw_Amp = pow(pow(gForceX,2)+pow(gForceY,2)+pow(gForceZ,2),0.5);
int Amp = Raw_Amp * 10; // Mulitiplied by 10 bcz values are between 0 to 1
//Serial.println(Amp);
angleChange = pow(pow(rotX,2)+pow(rotY,2)+pow(rotZ,2),0.5);
///////////// FALL DETECTION //////////////
if (Amp<=2 && trigger2==false){ //if AM breaks lower threshold (0.4g)
trigger1=true;
Serial.println("TRIGGER 1 ACTIVATED");
}
if (trigger1==true){
trigger1count++;
if (Amp>=9){ //if AM breaks upper threshold (3g)
trigger2=true;
Serial.println("TRIGGER 2 ACTIVATED");
trigger1=false; trigger1count=0;
}
}
if (trigger2==true){
trigger2count++;
angleChange = pow(pow(rotX,2)+pow(rotY,2)+pow(rotZ,2),0.5); Serial.println(angleChange);
if (angleChange>=30 && angleChange<=400){ //if orientation changes by between 80-100 degrees
trigger3=true; trigger2=false; trigger2count=0;
Serial.println(angleChange);
Serial.println("TRIGGER 3 ACTIVATED");
}
}
if (trigger3==true){
trigger3count++;
if (trigger3count>=10){
angleChange = pow(pow(rotX,2)+pow(rotY,2)+pow(rotZ,2),0.5);
//delay(10);
Serial.println(angleChange);
if ((angleChange>=0) && (angleChange<=10)){ //if orientation changes remains between 0-10 degrees
fall=true; trigger3=false; trigger3count=0;
Serial.println(angleChange);
}
else{ //user regained normal orientation
trigger3=false; trigger3count=0;
Serial.println("TRIGGER 3 DEACTIVATED");
}
}
}
if (fall==true){ //in event of a fall detection
Serial.println("FALL DETECTED");
sendSMS();
fall=false;
}
if (trigger2count>=6){ //allow 0.5s for orientation change
trigger2=false; trigger2count=0;
Serial.println("TRIGGER 2 DECACTIVATED");
}
if (trigger1count>=6){ //allow 0.5s for AM to break upper threshold
trigger1=false; trigger1count=0;
Serial.println("TRIGGER 1 DECACTIVATED");
}
delay(100);
pox.update();
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
if (SerialGPS.available() > 0)
{
if (gps.encode(SerialGPS.read()))
{
if (gps.location.isValid())
{
latitude = gps.location.lat();
latitude_string = String(latitude , 6);
longitude = gps.location.lng();
longitiude_string = String(longitude , 6);
}
}
}
if (millis() - tsLastReport > REPORTING_PERIOD_MS)
{
Blynk.run();
//Blynk.virtualWrite(V0, 1, latitude, longitude, "Location");
Blynk.virtualWrite(V3, BPM);
Blynk.virtualWrite(V4, SpO2);
Serial.print("Acceleration: ");
Serial.println(Amp);
Serial.print("Angle change: ");
Serial.println(angleChange);
Serial.print("Heart rate:");
Serial.print(BPM);
Serial.print(" bpm / SpO2:");
Serial.print(SpO2);
Serial.println(" %");
Serial.print("Latitude = ");
Serial.println(latitude_string);
Serial.print("Longitude = ");
Serial.println(longitiude_string);
tsLastReport = millis();
}
}
void sendSMS()
{
Serial.println("FALL DETECTED");
HTTPClient http;
String serverPath = serverName + "?value1=1234";
// Your Domain name with URL path or IP address with path
http.begin(serverPath.c_str());
// Send HTTP GET request
int httpResponseCode = http.GET();
Serial.println(httpResponseCode);
http.end();
for(;;);
}
Here the problem is MAX30100 pulse sensor is not working and the rest are working well. When I removed the fall detection code then the pulse sensor works fine but now for some reason it doesn't work. Can you please help me regarding this?