Tuesday, May 19, 2015

Lab 6.2 - Wirelessly plotting the heart rate in real time

https://www.youtube.com/watch?v=wu3GdAQlGPE&feature=youtu.be

The idea

By using 2 XBees, an Arduino and an Infrared Pulse Sensor we are able to monitor the heart rate of an individual and send it wirelessly to a computer that plots the data in real time with the use of Python. By extending this to a sensor network, one could monitor the patients in a hospital wirelessly.



How to do it? 
The Infrared Pulse Sensor(Heart rate ear clip) works by sensing variations in the bloodflow of an individual and sending digital HIGH values when this happens. The heart-rate sensor is connected to an Arduino in order to add a timestamp, and the Arduino sends an encapsulated message containing the timestamp and the sensor reading to a connected XBee.

On the other wireless side, an XBee is connected to the computer and a Python application listens for new serial data. As soon as it receives a new message, it decapsulates it and adds the 2 values (timestamp and sensor reading) to 2 different arrays. It then plots them, displaying it in real time.


We had run into many problems during the development of the project, mainly because of the latency that the XBees produce, making the plotting of the data "close to" realtime. Nevertheless, because the Arduino adds a timestamp, the data is displayed correctly, just not in perfect real time.
At the same time, because the data is not always received correctly and in the right order, possible errors must be checked for in the Python application.

Image of real time data



Video



https://www.youtube.com/watch?v=wu3GdAQlGPE&feature=youtu.be


Schematics



Materials used

  • 1 Arduino Uno
  • 2 XBees Explorer
  • 2 XBee
  • 1 Breadboards
  • 1 Heart rate ear clip (Model: MED03212P)

Software needed

  • XCTU - here
  • Python - here.
  • XBee library for Python here.
  • Pyserial library for Python - here.
  • XBee library for Arduino - here.
  • Matplotlib library for Python - here

Steps

  1. Set one XBee to Coordinator API mode
    1. In XCTU - Set PAN ID to BBBB
    2. In XCTU - Set API Mode to 2
    3. Connect this Xbee to Computer
  2. Set one XBee to Router AT mode
    1. In XTCU - Set PAN ID to BBBB
    2. Connect this Xbee to Arduino (Rx to Tx and Tx to Rx)
  3. Connect Heart rate sensor to Arduino as shown in schematics
  4. Upload Arduino code on Arduino
  5. Run Python code on computer

Code:


Arduino:
//define pins
int HRpin = 2; //digital PIN 2
int reading;
long initialTime=0,time;

void setup() {
  Serial.begin(9600);
  // put your setup code here, to run once:
  pinMode(HRpin,INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(initialTime == 0)
    initialTime = millis();
  reading = digitalRead(HRpin);
  time = millis() - initialTime;
  
  String sentData = String("Time:" + String(time) + "\n" + "Value:" + String(reading) + "\n");
  Serial.print(sentData);
  delay(150);

}

Python:
'''
Created on May 19, 2015
@author: goku
'''
import serial
import time
from xbee import ZigBee
import numpy as np
import matplotlib.pyplot as plt

#initialize empty lists x and y to be populated with timestamp and value of heart pulse(true/false)
x = [0]
y = [0]
new_x = new_y = 0
ser = serial.Serial('COM20', 9600)
while True:
    try:
        plt.clf() #clear the plot
        plt.xlabel("Time in miliseconds")
        plt.ylabel("Heart pulse")
        plt.title("Wireless Heart Monitor")
        plt.ylim([-0.2,1.2])
    
        #read data from XBee
        data = ser.readline()
        
        #decapsulate the data
        formated_data = data.split()
        if "Time:" in formated_data[0]:
            #the value of Time that we receive from arduino
            new_x = formated_data[0].split("Time:")[1]
            print new_x
        elif "Value:" in formated_data[0]:
            #the value of the pulse reading that we get from arduino
            new_y = formated_data[0].split("Value:")[1]
            print new_y
        
        #Check if received Y is a correct value
        if (type(new_y) is not str):
            print "y not str: true"
            y.append(new_y)
        else:
            if new_y.isdigit():
                y.append(int(new_y))
                
        #Check if received X is a correct value
        if (type(new_x) is not str):
            print "x not str: true"
            x.append(new_x )
        else:
            if new_x.isdigit():
                x.append(int(new_x)) #plot graph in seconds
        #plot the graph
        plt.plot(x,y, "g")
        plt.xlim([int(x[len(x) - 1])-10000,int(x[len(x) - 1])]) #make x and y axis stable
        #plt.text(x, y, s, fontdict, withdash)
        plt.pause(0.00001)
    except KeyboardInterrupt:
        break
ser.close()

No comments:

Post a Comment