Keep Track of Somebody's Heart Rate at Distance

ThingSpeak is a great IoT platform to display our sensor data over the internet at any time and from any place. The reason for being superior to other IoT platforms is that Thingspeak shows real-time data without lagging. In this project, we are going to make a Heart Rate Monitoring System using Arduino, Pulse sensor, and ESP8266 WiFi module. The pulse sensor will detect the heart rate, and Arduino will send it to Thingspeak using the ESP8266 WiFi module.

Do check our amazing projects using other IoT platforms like IFTTT, Artik Cloud, Firebase, Particle Cloud, Amazon AWS.

Components Required

  • Pulse sensor
  • ESP8266 Wi-Fi module
  • Arduino Uno
  • Bread Board
  • 220-ohm resistors
  • LED
  • Connecting wires

Circuit Diagram

IoT based Heart Rate Monitor Circuit Diagram

Connections are given in the below table:

S.NO.

Pin Name

Arduino Pin

1

ESP8266 VCC

3.3V

2

ESP8266 RST

3.3V

3

ESP8266 CH-PD

3.3V

4

ESP8266 RX

TX

5

ESP8266 TX

RX

6

ESP8266 GND

GND

7

Pulse Sensor VCC

3.3V

8

Pulser Sensor Signal

A0

9

Pulse Sensor GND

GND

10

Led +ve Pin

9

11

Led -ve Pin

GND

ThingSpeak Setup for IoT based Heart Rate Monitor

Step 1: ThingSpeak Setup for Heart Rate Monitoring

For creating your channel on ThingSpeak, you first need to sign up on ThingSpeak. In case if you already have an account on ThingSpeak, just sign in using your id and password.

For creating your account go to www.thinspeak.com

ThingSpeak

Click on signup if you don't have an account and if you already have an account, click on sign in.

After clicking on signup, fill in your details.

 Signup for ThingSpeak

After this verify your E-mail id and click on continue.

Step 2: Create a Channel for Your Data

Once you Sign in after your account verification, Create a new channel by clicking the "New Channel" button.

Create Channel on ThingSpeak for IoT based Heart Rate Monitor

After clicking on "New Channel," enter the Name and Description of the data you want to upload on this channel. For example, I am sending my Heart Rate data, so I named it Heart Rate Monitor.

Enter the name of your data 'Rate' in Field1. If you want to use more Fields, you can check the box next to the Field option and enter the name and description of your data.

After this, click on the save channel button to save your details.

Step 3: API Key

To send data to Thingspeak, we need a unique API key, which we will use later in our code to upload our sensor data to Thingspeak Website.

Click on the "API Keys" button to get your unique API key for uploading your sensor data.

ThingSpeak API key for IoT based Heart Rate Monitor

Now copy your "Write API Key." We will use this API key in our code.

Programming Code Explanation

The complete code for IoT based Heart Rate Monitor is given at the end. First of all, install all the required libraries and then enter your Wi-Fi name, password, and thingspeak.com api.

          #include <SoftwareSerial.h>          #include <stdlib.h>          #define DEBUG true          #define SSID "WiFi Name"     // Enter Your WiFi Name Here                    #define PASS "WiFi Password"       // Enter Your WiFi Password Here          #define IP "api.thingspeak.com"// thingspeak.com api          Define the pins where you connected the esp8266 Tx and Rx and enter your Thingspeak API key.          SoftwareSerial ser(2,3);                    String msg = "GET /update?key=Your Api Key"; //Enter your API key        

Define all the integer and volatile variables that will be used to calculate the BPM (Beats Per Minute).

          //Variables          int error;          int sensorPin = 0;         // Connect Pulse Sensor Signal Pin to Analog Pin A0          int ledpin = 9;        //  Connect Led Positive Pin to Arduino Pin 9          volatile int BPM;           // int that holds raw Analog in 0. updated every 2mS          volatile int Signal;              // holds the incoming raw data          volatile int IBI = 600;     // int that holds the time interval between beats                    volatile boolean Pulse = false;     // "True" when heartbeat is detected. "False" when not a "live beat".                    volatile boolean QS = false;        // becomes true when Arduino finds a beat.          …………………………………          …………………………………        

The void updatebeat() function will send data to the serial monitor and also publish it to the thingspeak channel.

          void updatebeat() {                      String cmd = "AT+CIPSTART=\"TCP\",\"";                      cmd += IP;                      cmd += "\",80";                      Serial.println(cmd);                      ser.println(cmd);                      delay(2000);                      if(ser.find("Error")) {                      return;                      }                      cmd = msg ;                      cmd += "&field1=";                                cmd += BPM;                      cmd += "\r\n";                      Serial.print("AT+CIPSEND=");                      ser.print("AT+CIPSEND=");                      Serial.println(cmd.length());                      ser.println(cmd.length());                      if(ser.find(">")) {                      Serial.print(cmd);                      ser.print(cmd);                      }          …………………          …………………        

The below code is used to convert the pulse sensor data into BPM (Beats Per Minute).

          ISR (TIMER2_COMPA_vect){                  // triggered when Timer2 counts to 124                      cli();                                 // disable interrupts while we do this                      Signal = analogRead(sensorPin);              // read the Pulse Sensor                                sampleCounter += 2;                         // keep track of the time in mS                      int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise                      //  find the peak and trough of the pulse wave                      if(Signal < thresh && N > (IBI/5)*3){      // avoid dichrotic noise by waiting 3/5 of last IBI                      if (Signal < T){                         // T is the trough                      T = Signal;                            // keep track of lowest point in pulse wave                                }                      }                      if(Signal > thresh && Signal > P){        // thresh condition helps avoid noise                      P = Signal;                             // P is the peak                      }                                         // keep track of highest point in pulse wave                      if (N > 250){                                   // avoid high frequency noise                      if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){                                Pulse = true;                               // set the Pulse flag when there is a pulse                      digitalWrite(ledpin,HIGH);                // turn on pin 13 LED                      IBI = sampleCounter - lastBeatTime;         // time between beats in mS                      lastBeatTime = sampleCounter;               // keep track of time for next pulse                      if(secondBeat){                        // if this is the second beat                      secondBeat = false;                  // clear secondBeat flag                      for(int i=0; i<=9; i++){             // seed the running total to get a realistic BPM at startup                      rate[i] = IBI;                                }                      }          ………………………………….          ………………………………….        

Copy and paste the above code into Arduino IDE and upload it into Arduino. After successful upload, the serial monitor will look like this:

Serial Monitoring for IoT based Heart Rate Monitor

After this, navigate to the Thingspeak channel.

Monitoring Heart Beat Data on ThingSpeak

Your BPM (Beats Per Minute) is uploaded on the thingspeak channel. Hence, we have successfully monitored BPM using Arduino and ESP8266. Check our more amazing projects using ThingSpeak:

  • IoT Based Temperature and Humidity Monitoring over ThingSpeak using Arduino UNO and ESP8266
  • IoT based Temperature and Humidity Monitoring using ThingSpeak and ESP8266
  • ThingSpeak and ESP32: How to send Data to Cloud using ESP32
  • Raspberry Pi and LM35 based IoT Temperature Monitoring System using Thingspeak
  • How to Send Data to ThingSpeak Cloud using Raspberry Pi

Code

#include <SoftwareSerial.h>
#include <stdlib.h>
#define DEBUG true
SoftwareSerial ser(2,13);
#define SSID "WiFi Name"     // Enter Your WiFi Name Here
#define PASS "WiFi Password"       // Enter Your WiFi Password Here
#define IP "api.thingspeak.com"// thingspeak.com ip

String msg = "GET /update?key=Your Api Key"; //Enter your API key

//Variables
int error;
int sensorPin = 0;         // Connect Pulse Sensor Signal Pin to Analog Pin A0
int ledpin = 9;        //  Connect Led Positive Pin to Arduino Pin 9

volatile int BPM;           // int that holds raw Analog in 0. updated every 2mS
volatile int Signal;              // holds the incoming raw data
volatile int IBI = 600;     // int that holds the time interval between beats
volatile boolean Pulse = false;     // "True" when heartbeat is detected. "False" when not a "live beat".
volatile boolean QS = false;        // becomes true when Arduino finds a beat.

static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse
volatile int rate[10];                    // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P =512;                  // used to find peak in pulse wave, seeded
volatile int T = 512;               // used to find trough in pulse wave, seeded
volatile int thresh = 525;  // used to find instant moment of heart beat, seeded
volatile int amp = 100;     // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

void setup()  {
Serial.begin(115200); //or use default 115200.
ser.begin(115200);
Serial.println("AT");
ser.println("AT");
delay(3000);
if(ser.find("OK"))  {
connectWiFi();
}
interruptSetup();
}

void loop() {
start: //label
error=0;
updatebeat();
//Resend if transmission is not completed
if (error==1) {
goto start;
}

  delay(1000);
}

void updatebeat() {
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
ser.println(cmd);
delay(2000);
if(ser.find("Error")) {
return;
}
cmd = msg ;
cmd += "&field1=";
cmd += BPM;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
ser.print("AT+CIPSEND=");
Serial.println(cmd.length());
ser.println(cmd.length());
if(ser.find(">")) {
Serial.print(cmd);
ser.print(cmd);
}
else{
Serial.println("AT+CIPCLOSE");
ser.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}

boolean connectWiFi() {
Serial.println("AT+CWMODE=1");
ser.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
ser.println(cmd);
delay(5000);
if(ser.find("OK"))  {
Serial.println("OK");
return true;
}else {
return false;
}
}

void interruptSetup() {
// MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
ISR (TIMER2_COMPA_vect){                  // triggered when Timer2 counts to 124
cli();                                 // disable interrupts while we do this
Signal = analogRead(sensorPin);              // read the Pulse Sensor
sampleCounter += 2;                         // keep track of the time in mS
int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
//  find the peak and trough of the pulse wave
if(Signal < thresh && N > (IBI/5)*3){      // avoid dichrotic noise by waiting 3/5 of last IBI
if (Signal < T){                         // T is the trough
T = Signal;                            // keep track of lowest point in pulse wave
}
}
if(Signal > thresh && Signal > P){        // thresh condition helps avoid noise
P = Signal;                             // P is the peak
}                                         // keep track of highest point in pulse wave

     if (N > 250){                                   // avoid high frequency noise
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){
Pulse = true;                               // set the Pulse flag when there is a pulse
digitalWrite(ledpin,HIGH);                // turn on pin 13 LED
IBI = sampleCounter - lastBeatTime;         // time between beats in mS
lastBeatTime = sampleCounter;               // keep track of time for next pulse
if(secondBeat){                        // if this is the second beat
secondBeat = false;                  // clear secondBeat flag
for(int i=0; i<=9; i++){             // seed the running total to get a realistic BPM at startup
rate[i] = IBI;
}
}
if(firstBeat){                         // if it's the first time beat is found
firstBeat = false;                   // clear firstBeat flag
secondBeat = true;                   // set the second beat flag
sei();                               // enable interrupts again
return;                              // IBI value is unreliable so discard it
}
word runningTotal = 0;                  // clear the runningTotal variable
for(int i=0; i<=8; i++){                // shift data in the rate array
rate[i] = rate[i+1];                  // and drop the oldest IBI value
runningTotal += rate[i];              // add up the 9 oldest IBI values
}
rate[9] = IBI;                          // add the latest IBI to the rate array
runningTotal += rate[9];                // add the latest IBI to runningTotal
runningTotal /= 10;                     // average the last 10 IBI values
BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
QS = true;                              // set Quantified Self flag

    }
}
if (Signal < thresh && Pulse == true){   // when the values are going down, the beat is over
digitalWrite(ledpin,LOW);            // turn off pin 13 LED
Pulse = false;                         // reset the Pulse flag so we can do it again
amp = P - T;                           // get amplitude of the pulse wave
thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
P = thresh;                            // reset these for next time
T = thresh;
}
if (N > 2500){                           // if 2.5 seconds go by without a beat
thresh = 512;                          // set thresh default
P = 512;                               // set P default
T = 512;                               // set T default
lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
firstBeat = true;                      // set these to avoid noise
secondBeat = false;                    // when we get the heartbeat back
}
sei();

}

Keep Track of Somebody's Heart Rate at Distance

Source: https://iotdesignpro.com/projects/iot-heart-rate-monitor-project-using-arduino-and-esp8266

0 Response to "Keep Track of Somebody's Heart Rate at Distance"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel