IoT Based Heartbeat Monitoring System using Raspberry Pi

IoT Based Heartbeat Monitoring System using Raspberry Pi

Health monitoring has always been a promising application for the Internet of Things (IoT). By using the right technology we no longer have to depend on our general routine health check up or our local physicians to assess our body. Sensors can be used to measure all your body vitals and this information can be shared remotely in real time for a doctor from other part of the world to diagnosis you or perhaps an AI could crunch all the numbers and diagnosis your problem. Sounds futuristic right? But we are gradually moving towards it and we are not very far from having remote IoT Robotic Arms performing surgery on us. While we progress with that, in this session we will build a Raspberry Pi heart rate monitor to measure the heart rate of a remote patient and display it on Processing IDE. Previously we have also built a Heart Rate Monitor using Arduino and ESP8266 and uploaded the values to Thingspeak.

 

Material Required:

The following are the components required to build your own, patient monitoring system using Raspberry Pi.

  1. Raspberry Pi
  2. Pulse Sensor
  3. ADS1115 ADC module
  4. Jumper wire
  5. Power supply or power bank

 

Pulse Rate Sensor:

Before we get into the actual project let’s take a look at how the Pulse Rate sensor works. The working of the Pulse/Heart beat sensor is very simple. The sensor has two sides, on one side the LED is placed along with an ambient light sensor and on the other side we have some circuitry. This circuitry is responsible for the amplification and noise cancellation work. The LED on the front side of the sensor is placed over a vein in our human body. This can either be your Finger tip or you ear tips, but it should be placed directly on top of a vein.

Now the LED emits light which will fall on the vein directly. The veins will have blood flow inside them only when the heart is pumping, so if we monitor the flow of blood we can monitor the heart beats as well.  If the flow of blood is detected then the ambient light sensor will pick up more light since they will be reflect ted by the blood, this minor change in received light is analyzed over time to determine our heart beats. In this project the pulse sensor works as a heartbeat sensor for Raspberry Pi.

 Pulse Rate Sensor for Heartbeat Monitoring System 

There are three wires coming out of the sensor which are the Signal(S), Vcc (3 - 5 V) and GND.

Signal wire shown in violet, red and black color respectively. In our project the sensor will be powered by the 3.3V pin of Arduino and the signal pin will be connected to Raspberry pi through the ADS115 ADC module since Raspberry Pi by default cannot read Analog voltage.

 

Circuit Diagram:

The complete circuit diagram for IoT patient monitoring system using Raspberry Pi is shown below.

Circuit Diagram of IoT Based Heartbeat Monitoring System using Raspberry Pi

 

As you can see we have used the ADS115 ADC module with Pulse sensor and the pulse sensor is connect to Pi through I2C communication, so that we can measure heartbeat on Raspberry Pi.  Below are the connections:

  • Signal pin of pulse sensor -> A0 of ADC Module
  • Vcc pin of pulse sensor -> 3.3V of Raspberry
  • GND pin of pulse sensor -> GND of Pi
  • Tx of  RPI-> Rx of RPI
  • GND of ADC module -> GND of RPI
  • VCC of ADC Module -> +5v Of RPI
  • SCL and SDA of ADC module -> SCL and SDA of RPI

ADS115 ADC module with Pulse sensor

 

Installation and configuration

Since the ADC module communicates in I2C and we use UART for serial communication we have to, enable UART and I2C of raspberry pi by using raspi-config command in the shell as show below.

Raspberry Pi Configuration Command

Now select Interfacing Options and press enter.

Raspberry Pi Software Configuration Tool

 

Now select I2C and press enter

Raspberry Pi Software Configuration Tool

 

Now select Yes and press enter

Raspberry Pi Software Configuration Tool

 

Now press enter by selecting ok

Raspberry Pi Software Configuration Tool

 

Now enable Serial by selecting Serial and press enter

Raspberry Pi Software Configuration Tool

 

Now select no and press enter for disabling the login shell over serial.

Enable shell messages for Heartbeat monitoring System

 

Now select Yes and press enter for enable the serial.

Raspberry Pi Software Configuration Tool

 

Now select ok and press enter.

Raspberry Pi Software Configuration Tool

 

Now Select finish and press enter

Raspberry Pi Software Configuration Tool

 

Now select Yes and press enter for reboot.

Raspberry Pi Software Configuration Tool

 

Now install i2c packages

sudo apt-get install -y python-smbus
sudo apt-get install -y i2c-tools

Installig I2C Package

 

Now test and get I2C address of connected device by using given command:

sudo i2cdetect -y 1

Tesing I2C Package and Get I2C Address

 

Now install the ads1115 python library for ADC module by using given commands

sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus git
cd ~
git clone https://github.com/adafruit/Adafruit_Python_ADS1x15.git
cd Adafruit_Python_ADS1x15
sudo python setup.py install

Installing ADS1115 Python Library

 

Installing Processing on Raspberry Pi

Now Install Processing onto existing installation by using given command:

curl https://processing.org/download/install-arm.sh | sudo sh

Installing Processing on Raspberry Pi

 

Now we can see the processing icon in the raspberry pi menu:

Processing Icon In Raspberry Pi Menu

Processing Raspberry Pi for Heartbeat Monitoring System

 

Here we need to run pulse_sensor python code then processing code given at the end of this article. And then we will see the results as shown in the image below

Pulse Sensor Graph of Heartbeat Monitoring System  

 

A complete working video can also be found at the bottom of this page. Both the python code and the Processing code are explained below.

 

Raspberry Pi Python code for a Measuring Heartbeat

In this code, we have interfaced an ADC module via I2C communication for getting analog output of pulse sensor. After getting raw analog output from pulse sensor we find the upper peak and lower peak. And then find the difference of time between two peak points and then convert them in BPM. And we send the raw analog output and BPM to serial port which is read from processing IDE for further process. The complete heartbeat sensor raspberry pi python code is given at the bottom of this page.

 

While writing code first we have imported some modules that we have used in this code for different purposes

import Adafruit_ADS1x15
import serial
import time

 

Now we have some variables for calculations and for actions. And created a serial object

rate = [0]*10
amp = 100
GAIN = 2/3
curState = 0
statechanged = 0
ser = serial.serial("/dev/ttys0",9600)

 

Now given part of code is used to send data to processing

def send_to_prcessing(prefix,data):
ser.write(prefix)
ser.write(str(data))
ser.write("\n")

 

Now given function written for reading pulse sensor and measure the BPM.

def read_pulse();
firstBeat=True
seecondBeat=False
ssamplecounter=0
lastBeatTime=0
lastTime=int(time.time()*1000)
th = 525
P = 512
T = 512
IBI=600
pulse=False
adc=Adafruit_ADS1x15.ADS1015()
while True:
  signal=adc.read_adc(0,gain=GAIN)
  curTime=int(time.time()*1000)
  send_to_pressing("S",signal)
  samplecounter += curTime - lastTime
  lastTime=curTime
  N=samplecounter-lastBeatTime
  if signal>th and signal>P:
  P=signal
  if signal<th and N>(IBI/5.0)*3.0:
  if signal<T:
  T=signal

Complete Python code is given at the end of this article.

 

Processing Code to display Heartbeat value graphically on Raspberry Pi

In processing code, we get data from Serial port of raspberry which is loopback signal sent from python code that we have explained above. Now we find the raw analog input and BPM. And plot the graph according to analog values and display the BPM value. In processing code, first of all, we have imported some necessary library modules

import processing.serial.*;
PFont font;
serial port

 

After this, we have taken some variables

char letter;
string words="";
int sensor;
int IBI;
int BPM;
int[] RawY;
int[] scaledY;
int[] rate;
float offset;
color eggshell=color(255,2)
int pulsewindowwidth;
int pulsewindowheight;
int zoom_val=70;
long beat_rec_time;

 

Then in setup function, we have initialized the serial, configure the serial port, initiate default graph

void setup()
{
size(500,400); // stage size
PulseWindowWidth=Width -20;
PulseWindowHeight=height -70;
frameRate(100);
textAlign(CENTER);
rectMode(CENTER);
ellipseMode(CENTER);
RawY=new int[PulseWindowWidth];
scaledY=new int[PulseWindowHeight];
for (int i=0; i<Raw.length; i++){
Raw[i]=height/2;
}

 

Now in serialEvent function, we have read and extracted the data that is received

void serialEvent(serial port)
{
string inData=port.readstringuntil('\n');
inData=trim(inData);
if(inData.charAt(0)=='S'){
inData=inData.substring(1);
sensor=int(intData);
}
if (inData.charAt(0)=='B'){
inData=inData.substring(1);
BPM=int(inData);
beat_rec_time=millis()/1000;
}
if (inData.charAt(0)=='Q'){
inData=inData.substring(1);
IBI=int(inData);
}
}

 

Now in draw function, we have mapped the incoming values with graph dimension and then plot the graph.

void draw()
{
background(0);
nostroke();
fill(eggshell); // color for the window background
rect(250,height/2,PulseWindowWidth,PulseWindowHeight);
RawY[RawY.length=1]=(1023=sensor)=212;
offset=map((float)zoom_val/100.0,0.5,1,100,0);
for(int i=0; i<RawY.length-1;i++){
RawY[i]=RawY[i=1];
float dummy=RawY[i]*(float)zoom_val/100.0+offset;
scaledY[i]=constrain(int(dummy),44,height-40);
}
stroke(250,0,0);
nofill();
beginshape();
foro(int x=1;x<scaledY.length-1;x++){
vertex(x+10,scaledY[x]);
}
endshape();
if(millis()/1000>=beat_rec_time=5)
{
BPM=0;
IBI=0;
}

And given lines of code is responsible for displaying the BPM over graph

fill(255,0,0);
textsize(24);
text("Pulse Sensor Graph",width/2,25);
fill(0,0,255);
textsize(18);
text("IBI:" + IBI + "ms",width -70, height -10);
text("BPM:" + BPM, 50, height-10);
textsize(12);
text("zoom:" + zoom_val + "%", width -50,50);

 

Here we also have another feature in this code for zoom in and zoom out the plot. By press – we can zoom out and by press +, we can zoom in the pulse plot. To control this first of all we have to click on the graph anywhere then need to press – and +.

void Keytyped() 
{
if(key == '+')
{
zoom_val++;
printIn(zoom_val);
}
else if(key == '-')
{
zoom_val--;

printIn(zoom_val);
}
if(zoom_val>100)
zoom_val=100;
else if(zoom_val<=0)
zoom_val=0;
}

This way you can measure the heartbeat of a patient using Raspberry pi and display it as a graph on the screen. If needed you can also send this serial data to ThingSpeak or other IoT platforms like IFTTTArtik CloudFirebaseParticle CloudAmazon AWS and share the data remotely across the world. Hope you enjoyed the project, if you had any problem in getting things work kindly post them in the comment section below.

Complete processing and python code is given below or it can also be downloaded from here. Also check the demonstration video given below.

Code

Python Code:

import Adafruit_ADS1x15
import serial
import time

rate = [0]*10
amp = 100
GAIN = 2/3  
curState = 0
stateChanged = 0

ser = serial.Serial ("/dev/ttyS0", 9600)

def send_to_prcessing(prefix, data):
        ser.write(prefix)
        ser.write(str(data))
        ser.write("\n")

def read_pulse():
    firstBeat = True
    secondBeat = False
    sampleCounter = 0
    lastBeatTime = 0
    lastTime = int(time.time()*1000)
    th = 525
    P = 512
    T = 512
    IBI = 600
    Pulse = False
    adc = Adafruit_ADS1x15.ADS1015()  
    while True:
        
        Signal = adc.read_adc(0, gain=GAIN)   
        curTime = int(time.time()*1000)
        send_to_prcessing("S",Signal)
        sampleCounter += curTime - lastTime
        lastTime = curTime
        N = sampleCounter - lastBeatTime

        if Signal > th and  Signal > P:          
            P = Signal
     
        if Signal < th and N > (IBI/5.0)*3.0 :  
            if Signal < T :                      
              T = Signal                                                 
        
        if N > 250 :                              
            if  (Signal > th) and  (Pulse == False) and  (N > (IBI/5.0)*3.0)  :       
              Pulse = 1;                       
              IBI = sampleCounter - lastBeatTime
              lastBeatTime = sampleCounter       

              if secondBeat :                     
                secondBeat = 0;               
                for i in range(0,10):             
                  rate[i] = IBI                      

              if firstBeat :                        
                firstBeat = 0                  
                secondBeat = 1                  
                continue                              

              runningTotal = 0;               
              for i in range(0,9):            
                rate[i] = rate[i+1]       
                runningTotal += rate[i]      

              rate[9] = IBI;                  
              runningTotal += rate[9]        
              runningTotal /= 10;             
              BPM = 60000/runningTotal       
              print("BPM:" + str(BPM))
              send_to_prcessing("B", BPM)
              send_to_prcessing("Q", IBI)

        if Signal < th and Pulse == 1 :                    
            amp = P - T                   
            th = amp/2 + T
            T = th
            P = th
            Pulse = 0 
            
        if N > 2500 :
            th = 512
            T = th                  
            P = th                                              
            lastBeatTime = sampleCounter
            firstBeat = 0                     
            secondBeat = 0                   
            print("no beats found")

        time.sleep(0.005)

read_pulse()
 

Processing code can be downloaded from here.

Video