Measuring blood pressure
Table of Contents
1. Introduction
Hi! This will be my fourth blog for the Summer of Sensors Design Challenge. In the last blog (HMS Blog #3 - First Prototype) I finally worked with some hardware for this competition and got the first prototype working. This blog will be a bit different compared to my previous blogs for this Design Challenge, specifically in 2 ways. First off, this blog won't follow up where I left off in the last blog, but will rather take a completely different path. As you can tell from the title of this blog, this blog will focus on trying to measure blood pressure using a sensor. The other way this blog will be different is how I write it. I usually finish everything I have for the blog before I start writing it, or at least get far enough along that I know that everything should work in the end. This time, I'm starting with writing this blog in the middle of experimentation not knowing if this will yield good results or not. I think it's important (and fun!) to show the whole process, both good and bad. So, I hope I'll have it figured out by the end of this blog, but we'll see! Hope you enjoy reading the blog!
2. How do we measure blood pressure?
Measuring blood pressure is something that a lot of people need to do on a daily basis to keep in check, like my grandma, which is the reason for me trying to play with a sensor that can do that. The classical method for measuring blood pressure requires only a stethoscope and an arm cuff hooked up to a manometer to get a reading. The digital blood pressure monitors are in a similar fashion, but rather than using sound from the stethoscope, they use pressure sensors.
Here is a short explanation of how blood pressure is measured. The arm cuff is pumped full of air, cutting off the circulation in the brachial artery. The brachial artery is the artery that is going down the inside side of your biceps on your upper arm, and after the elbow, it splits into the radial and ulnar arteries. By pumping the arm cuff, we cut off the circulation in the brachial artery, once the device does that, it starts to gradually release pressure from the arm cuff.
The first pressure reading is the Systolic blood pressure level. As the pressure starts going down, once it drops below the systolic blood pressure level, the blood flow through the artery will return, but the flow will be turbulent as long as the artery remains partially compressed. From the sensor side, once the pressure in the cuff drops below the systolic blood pressure level, we will have a muffled pulsating (heartbeat) signal, as soon as we notice that phenomenon, we take a reading from our sensor for the systolic pressure.
The second pressure reading is the Diastolic blood pressure level. As we continue releasing pressure after reading the systolic blood pressure, we will continue to read the muffled pulsating signal (due to the turbulent flow) until the pressure in the arm cuff drops enough for us to have smooth blood flow. At the point when we get the smooth flow (when the Korotkoff sounds disappear), we take a reading from our sensor, and that is the diastolic blood pressure.
The above, of course, is just a simplified version of everything, but it's enough for me to go on to try and measure blood pressure.
3. Choosing a sensor
My goal is to tap into the hose leading to the arm cuff on a commercial blood pressure monitor in hope of trying to recreate the numbers from the raw data. In this way, I won't have to worry about the pump and the validity of the results, because I can cross-validate them with the ones from the commercial unit. The first thing we need is to define the range of pressure that our sensor needs to measure. The blood pressure measurements are taken in mmHg. Normal blood pressure is 120/80, but in cases of higher blood pressure, it can go up to 200, so a safe bet would be to have a range of at least 250mmHg, which is around 33kPa.
The sensor I went with is the MPS20N0040D-S, it has a pressure range of up to 40kPa (300mHg), works with 5V, and is used in some commercial blood pressure monitors. As mentioned in my first blog, I ordered a few of them, some with additional electronics, and some just bare sensors from AliExpress, in hopes of receiving anything by the deadline, and I got one of them with the additional electronics.
The additional electronics on the small PCB consist of a 24-bit ADC (HX710B) and a few passive components that go along with it. The HX710B similar to the HX711 is an ADC that is most commonly used for things like scale sensors but is a great pick here too since the pressure sensor is just a resistor network. This also means that the sensor is rather easy to use with an Arduino.
Relevant links:
- https://softroboticstoolkit.com/files/sorotoolkit/files/mps20n0040d-s_datasheet.pdf
- http://langster1980.blogspot.com/2015/09/pressure-sensor-breakout-board.html
- https://www.arduino.cc/reference/en/libraries/hx710b_arduino/
There are a lot of different libraries for the Arduino and the HX710B, while working on this, I managed to find at least 3, and they all gave good results. I linked one of them above.
4. Experimenting with the sensor
Before I get into all of the experimenting, I first need to describe the setup I will be using for this sensor. The arm cuff is connected to the blood pressure monitor with a soft rubber tube. In order to measure the same blood pressure, I either need to make something that goes in between the tube and the blood pressure monitor, or I need a small T joint that I can put somewhere along the tube. Luckily, my dad managed to find me a small T joint, so I went with that approach, which made everything much easier to connect together.
The gray tubing is the tubing from the blood pressure monitor, as you can see in the picture above, it is slightly larger than the black tubing which was designed for this T joint. To make it work, I left a piece of black tubing on the T joint and put the gray tubing over it, and secured it with a small zip tie to make sure it can hold pressure.
The rest of this section will be dedicated to the trial and error method of my trying to get good readings with this sensor so I can get the raw blood pressure data. My general idea is to use the Arduino to just read the data from the sensor in a loop and send them over Serial, where a Python script can run on my computer collecting all of that data and storing it in a CSV file or something similar. But before getting into data logging I used the built-in serial plotter available in the Arduino IDE, it's a great way to easily visualize data in real-time.
Blood pressure measurement - Attempt 1
First of all, I of course just tried to see if I could successfully read the sensor data, which was easy using the HX710B library. After that, all I had to do was connect all of the tubes as shown in the picture below.
After connecting everything, it was time to give this system a try. And this is where I started hitting my first problems. The blood pressure monitor I used has a readout on the screen of the pressure as it's trying to pump up the arm cuff, and when the reading on the blood pressure monitor topped around 100-140mmHg, the sensor readings just topped and didn't measure anything above that. I tried a few times but got the same result every time, which is strange since the advertised sensor range is double what I managed to measure. Before I continue talking about the sensor, let's look at what I actually managed to record with this limited range.
Even though I couldn't use the full range that I need to get the systolic blood pressure, we can still do some analysis on this data. When we look at the graph, we can clearly see that the pressure is having a downward trajectory as the blood pressure monitor is letting air out, but also, we can clearly see the pulses in the readings, which is what I hoped to see all along. Another thing we can notice is how prominent the pulses are in the data. The 2 pictures below show the differences in how we see pulses at the start (first picture) and when we reach the diastolic blood pressure (second picture).
You can see that pulses are much more easily visible compared to the data around in the first picture compared to the second. In the second picture, we can also see a sudden pressure drop at the end, that's the moment when the blood pressure monitor decided the pulses are so faint in the data, that it can read the diastolic blood pressure and let all of the pressure out of the arm cuff. Even though for now, I wasn't able to capture the whole range of data that I wished to capture, this is still a great result in my book. Compared to the MAX30100 and MAX30102 sensors (HR Click and OXI5 Click), I think this method is much more suited for looking at heart rate regularity since it can't be affected that much by how the user is interacting with the sensor.
This is of course where my journey of trying to get the full range of data out of my sensor began. The first thing I did was take the arm cuff off and held it in my hand so I can record the sensor readings topping out while the blood pressure monitor was pumping it up. Here is the video of that.
On the bottom right you can see (and hear) the blood pressure monitor trying to pump the air cuff while I'm holding it in my hand so it can build up pressure. If you stop the video, you can see that already from around 108mmHg to the sensor starter topping out on the serial plotter. Here is a screenshot of that.
And here is a screenshot of the data after the whole test.
As you can clearly see, without changing something, it would be impossible to get the full range of measurements that we need to actually read the blood pressure data from it.
Connecting directly to the sensor - Attempt 1
I tried multiple libraries, but obviously, that won't help, since the reading I was getting was the max reading that the HX710B can provide. Next, I wanted to do was a test if the problem is related to the sensor or the ADC that's on the PCB. To test this out, I had to connect to the sensor directly so I can check if I can get any response for pressures that are above the 108mmHg. To know what kind of pressure is in the system, instead of the arm cuff I put in an analog manometer (from an old manual blood pressure measurement set) and instead of the blood pressure monitor to provide the pressure, I used a syringe.
This way, I can easily control the pressure in the system using the syringe and have a readout of the actual pressure on the analog manometer. In order to get measurements from the sensor, I went the fully analog electronic way and just had a multimeter at the end. Here is a block diagram of the final setup.
Now, of course, comes the fun question, what kind of analog electronics do we need so we can get a reading from the sensor using a multimeter? The first thing I did was take another look at the datasheet for this sensor that I've linked above. Under the pinout of the sensor is this schematic.
On the schematic is a difference amplifier, with all of the resistors of the same value, we just get a voltage difference at the end. By tuning the resistors, we can also get an amplification from this part of the circuit, but I decided to keep those stages separate to keep everything a bit easier to tune. The voltage difference between Vout = V2 - V1 is too small to be useful for us as it is, so, we need a noninverting amplifier added to it. After a bit of playing around, I found that the amplification with which I can see some results is around 170. So here is the full schematic needed to get the measurement I needed.
With everything connected, here is what the final setup looked like.
The analog manometer can go up to 300mmHg which is also the range of our sensor which means we can easily test it through the whole range. The main goal of this test was to see if we can any readings at the top end, above the 100-120mmHg range. So all that was left to do was to put some pressure using the syringe and see if we can see any voltage difference at the end.
As you can see from the video, I have a dead zone now at the lower part of the pressure range, but once I go above around 180-200mmHg, you can see the voltage change with the analog manometer needle moving, and not only that, but if I try keeping it at a certain pressure without moving my finger too much, the voltage doesn't change too much, meaning the sensor is working as it should, and for some reason, I'm either having problems with the ADC or the connection between the sensor and the ADC.
Looking at the HX711
While looking at the HX710 and its specs, I decided to look at the HX711, in hopes of maybe trying to connect the sensor to that ADC with the hope of better results. It turns out, I completely missed one thing that I've seen a lot for the HX711, and that is the gain. The problem was obviously that the sensor just went out of the range of the ADC, hence, why I was getting those cutoff measurements. Reading a bit online, about both the HX710 and HX711, they both communicate in exactly the same way, and there is a function to set the gain for the preamp on the ADC (HX711). Not having seen that in any other library, I tried my luck by using the HX711 library on the HX710 and it worked! Well, for the most part, it worked. The available gains should be 32, 64, and 128 (default), but on the HX710 I could only go as low as 64, which didn't get me the full range that I would need, but still got me a lot closer to what I wanted.
As you can see in the video, I managed to get readings up to 180mmHg, which is a lot higher than I used to get. I just adjusted the values with a single scale factor, and here are the raw values on the serial monitor compared to the values that you can see on the analog manometer.
There is a slight difference, but overall, I'm really happy with how accurate the readings are. I'll take this to be good enough for now, and if I see that It's not, I'll maybe try desoldering the sensor and connecting it to the HX711, since I have a few of them laying around. Here is the code I used for getting the results above.
#include "HX711.h" const int LOADCELL_DOUT_PIN = 3; const int LOADCELL_SCK_PIN = 4; HX711 scale; float pressure; void setup() { Serial.begin(115200); scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); scale.set_gain(64); } void loop() { if (scale.is_ready()) { //pressure = (scale.read() + 8388607) / 93207.00; //pressure = scale.read() + 8388607; pressure = scale.read(); Serial.println(pressure); } }
5. Data
Before I continue with the testing, there's one more part that I need to get worked out, data logging. The 2 simplest ways to do this would be to either have a microSD module on the Arduino to log the data directly to the microSD or the way I chose to go about it, to have the Arduino connected to the laptop, and have a Python script running in the background which just grabs new data as Arduino is sending it (Serial) and logs it into a CSV file.
Data logging
To gather the data, all we need in Python is to use the serial library, and for logging the data into a CSV file, we can use the CSV library. Because this is a program I want to run many times as I'm conducting experiments, the first part of the program will be dedicated to checking what's the latest dataset file and creating a new one with a number higher than the previous max one. This can of course is modified to take additional arguments from the user like who's blood pressure we're measuring during the test, the name of the test, and so on.
import csv import serial import time import os path = 'D:\\Projects\\HMS\\recorded_data' file_name = 'dataset' counter = 1 file_path = '' try: arduino = serial.Serial("COM3", 115200) print('Established communication to the Arduino, COM3, 115200') except: print('Error establishing a communication with the Arduino') print('Exiting') exit() # Creating a new data file path + data + first_free_number while True: file_path = path + '\\' + file_name + str(counter) + '.csv' if os.path.exists(file_path) == False: print('Creating new dataset file: ' + file_path) f = open(file_path, 'w') f.close() break else: counter += 1 print('Starting to record the data') while True: with open(file_path, 'a', newline = '') as csv_file: csv_writer = csv.writer(csv_file) data_point = float(arduino.readline()) csv_writer.writerow([str(data_point)])
The important thing is to check on what COM port our Arduino is (easily done through the device manager or Arduino IDE) and to make sure we're using the same baud rate.
Data plotting
The other thing we need to do is to present the data somehow, and the easiest way to do that is in a plot. For that, I wrote another small Python script that takes the file that we've just recorded and plots the data out. It's easy to modify cosmetic parameters inside the code and the code also saves a high-quality image of the plot in the same folder as our Python script.
import csv import matplotlib.pyplot as plt import scipy as sc data_file = 'dataset13.csv' measurements = [] with open(data_file, 'r') as csv_file: reader = csv.reader(csv_file) flag = True for row in reader: if flag == False: flag = True else: measurements.append(float(row[0])) # plot fig, ax = plt.subplots() ax.grid(axis = 'both', color = 'black', linestyle = '-', linewidth = 0.2) ax.set_title('Blood pressure measurement - Measuring Range') ax.set_xlabel('Reading number') ax.set_ylabel('Pressure [mmHg]') ax.plot(measurements, linewidth = 0.8, color = 'b') #ax.legend() #ax.set(xlim = (10, 30), ylim = (30, 70)) fig.savefig('BloodPressureMeasurement6.png', dpi = 300) plt.show()
Since we need access to the hardware ports on our computer for the first script, we need to run it on a local instance on something like Spyder or Visual Studio Code, while the second script can be run in online compilers as well. I generally try using online compilers like Google Colaboratory since they provide flexibility from where I can edit the code, and library installation is a breeze if there is a need for that at all. Here is a plot showing the pressure I recorded while playing with the Syringe setup that I've shown above.
6. Measuring blood pressure
After all of those tests and setbacks, it's time to finally try and record an actual blood pressure measurement, to see if we can see anything from the data. I'll upload all of the CSV files I talk about here if you wish to give it a try yourself to see what you can do with the data.
Measurement 1 - 120/79/79
This is the first measurement I took, I did the measurement on myself, and my blood pressure was 120/79 with a pulse of 79. That was extremely close to the 120/80, missed it by 1! During the measurement, I recorded 2338 points of data, but that also includes the part until I pressed the start button on the blood pressure monitor, until it pumped up the arm cuff. If you wish to try working with the data yourself, you can download it here (It doesn't allow me to attach CSV files, so I've uploaded it as a code that you can copy and paste into notepad and save as a CSV).
75.81 75.81 75.82 75.81 75.8 75.81 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.81 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.79 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.81 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.81 75.81 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.8 75.93 76.82 78.45 79.93 81.05 81.91 82.46 82.53 82.61 82.97 83.37 83.75 84.1 84.43 84.75 85.08 85.39 85.68 85.97 86.26 86.51 86.76 86.99 87.15 86.93 86.32 85.67 85.05 84.63 84.48 84.44 84.46 84.49 84.56 84.65 84.79 84.97 85.18 85.4 85.63 85.88 86.14 86.39 86.66 86.92 87.2 87.48 87.75 88.05 88.36 88.7 89.03 89.36 89.66 89.95 90.25 90.55 90.86 91.16 91.47 91.79 92.11 92.43 92.77 93.1 93.43 93.75 94.08 94.4 94.72 95.02 95.36 95.73 96.16 96.58 96.96 97.32 97.66 98.0 98.35 98.7 99.05 99.42 99.8 100.19 100.57 100.96 101.36 101.75 102.13 102.52 102.9 103.27 103.64 104.01 104.38 104.83 105.28 105.67 105.97 106.25 106.56 106.85 107.09 107.29 107.55 107.84 108.15 108.52 108.97 109.37 109.75 110.12 110.5 110.9 111.3 111.69 112.08 112.5 112.98 113.45 113.83 114.12 114.38 114.73 115.08 115.35 115.5 115.56 115.74 116.14 116.63 117.12 117.63 118.1 118.53 118.96 119.4 119.82 120.25 120.72 121.33 121.96 122.48 122.96 123.4 123.82 124.26 124.7 125.18 125.68 126.15 126.61 127.12 127.64 128.17 128.67 129.14 129.63 130.1 130.55 131.01 131.51 132.14 132.85 133.45 133.98 134.43 134.86 135.33 135.77 136.17 136.6 137.09 137.6 138.11 138.64 139.15 139.66 140.16 140.64 141.09 141.53 141.99 142.47 143.14 143.99 144.68 145.24 145.72 146.17 146.63 147.04 147.41 147.79 148.21 148.67 149.15 149.64 150.15 150.65 151.12 151.58 151.99 152.37 152.77 153.23 153.98 155.02 155.78 156.27 156.7 157.11 157.5 157.86 158.17 158.45 158.81 159.24 159.71 160.25 160.79 161.3 161.76 162.15 162.5 162.87 163.28 163.95 165.11 166.2 166.82 167.24 167.66 168.03 168.35 168.58 168.73 168.93 169.23 169.62 170.1 170.64 171.19 171.66 172.07 172.45 172.81 173.21 173.8 174.91 176.3 177.34 177.96 178.32 178.59 178.81 178.92 178.89 178.88 178.97 179.18 179.46 179.79 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 179.92 179.81 179.7 179.6 179.5 179.39 179.28 179.2 179.31 179.88 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 180.0 179.82 179.6 179.45 179.33 179.24 179.16 179.02 178.83 178.63 178.42 178.22 178.04 177.88 177.74 177.63 177.52 177.41 177.29 177.19 177.07 176.98 177.11 177.71 178.65 179.38 179.68 179.7 179.59 179.41 179.2 178.93 178.6 178.29 178.08 177.91 177.74 177.6 177.45 177.26 177.04 176.8 176.55 176.31 176.09 175.89 175.71 175.57 175.42 175.28 175.16 175.04 174.93 174.96 175.41 176.3 177.14 177.58 177.67 177.64 177.59 177.51 177.33 177.03 176.7 176.39 176.16 175.98 175.79 175.58 175.38 175.17 174.92 174.67 174.43 174.18 173.95 173.74 173.54 173.35 173.2 173.08 172.96 172.8 172.64 172.52 172.42 172.41 172.82 173.72 174.61 175.05 175.17 175.19 175.2 175.15 174.95 174.62 174.26 173.95 173.67 173.45 173.25 173.07 172.87 172.65 172.43 172.18 171.94 171.7 171.47 171.24 171.03 170.85 170.7 170.55 170.39 170.25 170.09 169.92 169.77 169.75 170.11 170.95 171.83 172.35 172.58 172.68 172.7 172.63 172.42 172.09 171.74 171.44 171.18 170.97 170.79 170.62 170.44 170.26 170.06 169.85 169.64 169.44 169.24 169.04 168.86 168.7 168.56 168.4 168.24 168.08 167.92 167.85 168.09 168.83 169.68 170.22 170.51 170.6 170.53 170.39 170.2 169.91 169.54 169.18 168.9 168.69 168.52 168.38 168.25 168.12 167.94 167.77 167.59 167.39 167.18 166.99 166.79 166.61 166.48 166.34 166.19 166.04 165.87 165.71 165.6 165.71 166.35 167.28 167.95 168.3 168.39 168.35 168.28 168.15 167.89 167.53 167.15 166.81 166.55 166.37 166.23 166.11 165.99 165.84 165.67 165.48 165.28 165.09 164.87 164.65 164.46 164.27 164.11 163.97 163.82 163.66 163.52 163.38 163.25 163.29 163.85 164.79 165.54 165.91 165.99 165.93 165.82 165.67 165.42 165.07 164.69 164.37 164.15 163.99 163.87 163.78 163.67 163.52 163.36 163.21 163.03 162.84 162.66 162.49 162.31 162.16 162.02 161.87 161.72 161.57 161.43 161.38 161.69 162.5 163.32 163.75 163.86 163.83 163.76 163.64 163.44 163.15 162.81 162.5 162.29 162.15 162.05 161.96 161.89 161.8 161.66 161.5 161.33 161.17 161.0 160.83 160.68 160.51 160.32 160.14 159.99 159.85 159.87 160.33 161.16 161.78 162.0 162.03 161.99 161.9 161.76 161.55 161.25 160.96 160.72 160.53 160.42 160.34 160.27 160.19 160.06 159.93 159.78 159.62 159.43 159.24 159.05 158.89 158.74 158.58 158.42 158.26 158.09 157.95 158.04 158.62 159.44 159.9 160.05 160.07 160.0 159.9 159.75 159.5 159.19 158.9 158.67 158.5 158.38 158.29 158.21 158.12 158.0 157.85 157.68 157.5 157.31 157.13 156.97 156.82 156.66 156.47 156.28 156.13 155.99 155.97 156.39 157.16 157.66 157.8 157.83 157.8 157.71 157.55 157.3 157.01 156.74 156.52 156.35 156.24 156.18 156.12 156.03 155.92 155.79 155.66 155.53 155.37 155.2 155.06 154.92 154.79 154.62 154.47 154.35 154.26 154.34 154.83 155.44 155.76 155.89 155.92 155.89 155.81 155.68 155.47 155.22 155.01 154.85 154.75 154.69 154.62 154.57 154.51 154.42 154.32 154.19 154.04 153.9 153.77 153.63 153.5 153.39 153.28 153.16 153.04 152.93 152.84 152.91 153.35 153.93 154.25 154.38 154.41 154.38 154.3 154.18 153.99 153.77 153.55 153.38 153.27 153.21 153.17 153.1 153.01 152.92 152.82 152.69 152.55 152.41 152.25 152.11 151.96 151.82 151.69 151.59 151.51 151.42 151.31 151.2 151.07 150.93 150.91 151.26 151.87 152.26 152.43 152.49 152.47 152.4 152.3 152.14 151.91 151.69 151.51 151.39 151.3 151.23 151.15 151.07 150.98 150.86 150.74 150.61 150.48 150.34 150.2 150.06 149.92 149.8 149.69 149.58 149.49 149.4 149.27 149.13 148.98 148.88 148.99 149.5 150.04 150.3 150.41 150.42 150.35 150.24 150.1 149.9 149.66 149.46 149.3 149.18 149.1 149.03 148.96 148.89 148.79 148.66 148.54 148.41 148.26 148.1 147.95 147.81 147.69 147.6 147.49 147.35 147.21 147.12 147.08 147.27 147.76 148.14 148.35 148.43 148.41 148.36 148.26 148.11 147.9 147.69 147.53 147.42 147.37 147.32 147.27 147.23 147.15 147.04 146.96 146.88 146.77 146.66 146.56 146.45 146.32 146.19 146.08 145.98 145.96 146.19 146.64 146.98 147.17 147.23 147.21 147.15 147.05 146.89 146.68 146.49 146.32 146.19 145.87 142.87 138.83 136.17 133.99 132.12 130.47 128.97 127.59 126.31 125.07 123.88 122.74 121.6 120.46 119.41 118.43 117.54 116.76 115.98 115.12 114.19 113.24 112.36 111.47 110.57 109.65 108.7 107.77 107.04 106.39 105.77 105.25 104.81 104.31 103.72 103.14 102.51 101.75 100.97 100.18 99.31 98.43 97.7 97.09 96.51 95.93 95.32 94.8 94.48 94.25 94.06 93.87 93.78 93.89 93.91 93.73 93.42 93.06 92.92 93.04 93.12 93.1 92.99 92.78 92.63 93.54 94.95 95.0 93.55 91.91 91.21 91.06 90.95 90.85 90.83 90.8 90.33 89.67 89.64 89.68 90.01 90.34 90.47 90.5 90.67 90.91 91.12 90.65 90.94 92.36 94.86 97.87 97.6 97.01 98.12 98.52 95.75 88.9 87.81 93.47 95.4 92.21 87.38 82.48 79.65 78.98 78.84 78.38 77.62 77.61 77.78 77.82 77.63 77.52 77.47 77.45 77.44 77.39 77.26 77.12 77.04 77.03 77.11 77.2 77.17 77.08 76.98 76.94 76.84 76.76 76.75 76.74 76.75 76.85 77.11 77.34 77.44 77.51 77.54 77.6 77.51 77.3 77.13 77.02 76.73 76.38 76.28 76.4 76.48 76.41 76.33 76.44 76.54 76.41 76.19 76.09 76.06 76.11 76.28 76.35 76.35 76.28 76.27 76.29 76.29 76.3 76.3 76.26 76.2 76.19 76.21 76.21 76.21 76.22 76.23 76.24 76.24 76.23 76.21 76.2 76.19 76.18 76.15 76.16 76.29 76.33 76.24 76.16 76.13 76.13 76.17 76.21 76.19 76.13 76.08 76.06 76.04 76.02 76.01 76.01 76.01 76.02 76.03 76.04 76.06 76.07 76.07 76.06 76.05 76.05 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.04 76.03 76.03 76.04 76.04 76.04 76.03 76.03 76.03 76.03 76.03 76.03 76.03 76.03 76.03 76.03 76.03 76.03
Here is what the plotted data looks like.
I managed to get a whole recording, but you can see the cutoff in the middle again. Also, you can notice a pretty large offset at the beginning and the end, which is something I haven't seen at all while working with the analog manometer. So there is still work to be done on the sensor side. Nevertheless, we can still take a look at the data that I've recorded a bit closer, or more specifically at the region where the blood pressure monitor is letting the air out so it can do its measurements.
One thing we can check is the heartbeat since it's clearly visible from the graph. There are 2 potential things that we can look at, and those are the BPM (Beats Per Minute) and the regularity of the heartbeat. To get the first one, we need actual timing to check that, which we can easily do by modifying the setup so that the Arduino also provides "millis() " with the sensor reading. As for the heartbeat regularity, this is something that we can check even from here just by how far the heartbeat detections are from one another. The first thing we need to do is locate all of the peaks in oscillations. We can do that using the scipy library in Python.
import csv import matplotlib.pyplot as plt import scipy as sc import numpy as np data_file = 'dataset11.csv' measurements = [] with open(data_file, 'r') as csv_file: reader = csv.reader(csv_file) flag = True for row in reader: if flag == False: flag = True else: measurements.append(float(row[0])) measurements = measurements[1450 : 2075] #11 x_positions = sc.signal.find_peaks(measurements)[0] y_positions = [measurements[x] for x in x_positions] # plot fig, ax = plt.subplots() ax.grid(axis = 'both', color = 'black', linestyle = '-', linewidth = 0.2) ax.set_title('Blood pressure measurement - Heartbeat detection') ax.set_xlabel('Reading number') ax.set_ylabel('Pressure [mmHg]') ax.plot(measurements, linewidth = 0.8, color = 'b') ax.scatter(x_positions, y_positions, color = 'r', linewidths = 0.1) fig.savefig('BloodPressureMeasurement9.png', dpi = 300) plt.show()
This will look for all local maximums in our dataset. The function that is responsible for that is this one.
x_positions = sc.signal.find_peaks(measurements)[0] y_positions = [measurements[x] for x in x_positions]
This way we get the indexes and from there we can get the values from our data using those indexes. All that's left to do now is to scatter plot these dots onto our data.
Due to the cut-off at 180mmHg and the nature of the measurement, to check the regularity, I won't use the first and last detected heartbeat, but we can use the rest to see how the delta changes between them through the measurement. We're only interested in the time axis, which is the x-axis.
From the plot above, we can see that the heartbeats are around 31-36 readings apart. The thing we're interested in is how wide the range is because that will give us a clue about the irregularity. We can do this by subtracting the mean value from the delta values that we calculated for the plot above.
From this last graf, we can see that the deltas aren't that different as the measurements grow. We can go a step further and try to convert these graphs into time using the average BPM I got from the blood pressure monitor which was 79. Using that, we can calculate the average time between 2 heartbeats and then use that on our data.
avg_bpm = 79 time_between_heartbeats = 60 / avg_bpm time_intervals = len(heartbeats) - 1 num_measurements = heartbeats[-1] - heartbeats[0] avg_time_between_measurements = (time_intervals * time_between_heartbeats) / num_measurements print(avg_time_between_measurements)
We get that the average time between two measurements using the measured heartbeat is 0.023202454 seconds. Again, it would be easier if we used the "millis()" function directly in Arduino, but this is something that we can do with this data. All that's left to do now is to integrate that data into the last 2 plots.
The delta values here are in seconds, which shows how far off the beats are from one another. My goal with these graphs was to look for an irregular heart rate, which would show up on graphs as an extremely short delta followed by a long delta, but something I've learned about while researching this topic is HRV (Heart Rate Variability). If the heartbeats are "too" regular, it usually means that the person is in fight or flight but if there are some smaller differences between the deltas, it means that the person is more relaxed and can be a sign of better cardiovascular health. From the second graph, you can see that my HRV can go upwards of 80ms which is considered healthy. I am no expert on this topic, but I found it interesting as another piece of data that I can pull out from my measurements. Below is the code used for generating the delta plots.
heartbeats = x_positions[1 : -1] print(heartbeats) deltas = [] mean_val = 0 for i in range(0, len(heartbeats) - 1): deltas.append(heartbeats[i + 1] - heartbeats[i]) mean_val += heartbeats[i + 1] - heartbeats[i] mean_val = mean_val / len(deltas) fig, ax = plt.subplots() ax.grid(axis = 'both', color = 'black', linestyle = '-', linewidth = 0.2) ax.set_title('Heartbeat delta') ax.set_xlabel('Reading number') ax.set_ylabel('Delta') ax.plot(deltas, linewidth = 0.8, color = 'b') fig.savefig('BloodPressureMeasurement1-Delta.png', dpi = 300) plt.show() fig, ax = plt.subplots() ax.grid(axis = 'both', color = 'black', linestyle = '-', linewidth = 0.2) ax.set_title('Heartbeat delta') ax.set_xlabel('Reading number') ax.set_ylabel('Delta') ax.plot([delta - mean_val for delta in deltas], linewidth = 0.8, color = 'b') fig.savefig('BloodPressureMeasurement1-DeltaCentered.png', dpi = 300) plt.show() avg_bpm = 79 time_between_heartbeats = 60 / avg_bpm time_intervals = len(heartbeats) - 1 num_measurements = heartbeats[-1] - heartbeats[0] avg_time_between_measurements = (time_intervals * time_between_heartbeats) / num_measurements print(avg_time_between_measurements) fig, ax = plt.subplots() ax.grid(axis = 'both', color = 'black', linestyle = '-', linewidth = 0.2) ax.set_title('Heartbeat delta') ax.set_xlabel('Reading number') ax.set_ylabel('Delta') ax.plot([delta * avg_time_between_measurements for delta in deltas], linewidth = 0.8, color = 'b') fig.savefig('BloodPressureMeasurement1-DeltaTime.png', dpi = 300) plt.show() fig, ax = plt.subplots() ax.grid(axis = 'both', color = 'black', linestyle = '-', linewidth = 0.2) ax.set_title('Heartbeat delta') ax.set_xlabel('Reading number') ax.set_ylabel('Delta') ax.plot([avg_time_between_measurements * (delta - mean_val) for delta in deltas], linewidth = 0.8, color = 'b') fig.savefig('BloodPressureMeasurement1-DeltaCenteredTime.png', dpi = 300) plt.show()
Measurement 2 - 105/68/68
For the second measurement, I asked my mom to volunteer, because she usually has lower blood pressure, and I wanted to see if I can get a better reading due to my sensor problems. Before I get into the plots that I've generated for that dataset, you can find the measurements below. Copy them into the notepad and save the file as a CSV. The code used to process and work with the data is the same as above. One thing I changed here is instead of using the converted values, I used raw readings from the ADC since I didn't have too much confidence in the accuracy of the numbers after the first measurement,
-1295143.0 -1295176.0 -1295158.0 -1295130.0 -1295094.0 -1295017.0 -1294734.0 -1294960.0 -1295093.0 -1295097.0 -1295096.0 -1295201.0 -1295345.0 -1295113.0 -1295090.0 -1295177.0 -1295047.0 -1294921.0 -1294959.0 -1295055.0 -1295015.0 -1294963.0 -1294896.0 -1294785.0 -1294816.0 -1295007.0 -1295047.0 -1295004.0 -1294972.0 -1295030.0 -1295080.0 -1295042.0 -1294998.0 -1294940.0 -1295017.0 -1294913.0 -1294791.0 -1294651.0 -1294761.0 -1294916.0 -1294785.0 -1294719.0 -1294841.0 -1294885.0 -1294827.0 -1294729.0 -1294810.0 -1294815.0 -1294834.0 -1294880.0 -1294776.0 -1294769.0 -1294776.0 -1294692.0 -1294676.0 -1294651.0 -1294758.0 -1294716.0 -1294726.0 -1294831.0 -1294813.0 -1294739.0 -1294634.0 -1294569.0 -1294479.0 -1294563.0 -1294650.0 -1294671.0 -1294608.0 -1294680.0 -1294650.0 -1294605.0 -1294549.0 -1294480.0 -1294468.0 -1294453.0 -1294501.0 -1294388.0 -1294397.0 -1294464.0 -1294525.0 -1294634.0 -1294651.0 -1294591.0 -1294602.0 -1294606.0 -1294567.0 -1294629.0 -1294688.0 -1294664.0 -1294681.0 -1294802.0 -1294824.0 -1294760.0 -1294763.0 -1294817.0 -1294735.0 -1294778.0 -1294853.0 -1294776.0 -1294800.0 -1294913.0 -1294797.0 -1294623.0 -1294764.0 -1294740.0 -1294748.0 -1294773.0 -1294833.0 -1294788.0 -1294784.0 -1295005.0 -1295109.0 -1295242.0 -1295422.0 -1295556.0 -1295470.0 -1295538.0 -1295369.0 -1295288.0 -1295277.0 -1295022.0 -1294868.0 -1294781.0 -1294750.0 -1294798.0 -1294663.0 -1294384.0 -1294250.0 -1294259.0 -1294211.0 -1294046.0 -1293966.0 -1294092.0 -1294383.0 -1294468.0 -1294485.0 -1294527.0 -1294606.0 -1294658.0 -1294579.0 -1294636.0 -1294687.0 -1294632.0 -1294789.0 -1294806.0 -1294736.0 -1294656.0 -1294762.0 -1294847.0 -1294775.0 -1294664.0 -1294732.0 -1294732.0 -1294806.0 -1294760.0 -1294777.0 -1294771.0 -1294800.0 -1294799.0 -1294862.0 -1294930.0 -1294902.0 -1294874.0 -1294757.0 -1294695.0 -1294674.0 -1294691.0 -1294637.0 -1294607.0 -1294577.0 -1294560.0 -1294591.0 -1294544.0 -1294653.0 -1294649.0 -1294597.0 -1294541.0 -1294428.0 -1294479.0 -1294616.0 -1294493.0 -1294369.0 -1294393.0 -1294460.0 -1294318.0 -1294248.0 -1294235.0 -1294176.0 -1294037.0 -1293973.0 -1293997.0 -1293960.0 -1293950.0 -1293980.0 -1293991.0 -1293937.0 -1294089.0 -1294197.0 -1294152.0 -1294103.0 -1294108.0 -1293985.0 -1293991.0 -1294075.0 -1294119.0 -1294056.0 -1294070.0 -1294086.0 -1294053.0 -1294118.0 -1294159.0 -1294105.0 -1294091.0 -1294089.0 -1294018.0 -1294022.0 -1293960.0 -1293970.0 -1294019.0 -1294054.0 -1294009.0 -1293888.0 -1293927.0 -1294049.0 -1294085.0 -1294046.0 -1294017.0 -1293967.0 -1293993.0 -1293967.0 -1294041.0 -1286985.0 -1211189.0 -1038024.0 -869484.0 -774306.0 -711372.0 -669422.0 -642187.0 -619192.0 -597181.0 -575304.0 -554010.0 -533347.0 -513540.0 -494161.0 -474593.0 -455375.0 -435441.0 -414471.0 -391618.0 -368055.0 -343124.0 -317156.0 -289818.0 -262151.0 -233592.0 -204571.0 -177024.0 -150101.0 -123623.0 -98227.0 -71778.0 -44650.0 -17808.0 9137.0 35771.0 61298.0 87064.0 113838.0 140888.0 168612.0 195942.0 222733.0 249906.0 277649.0 305490.0 333384.0 361826.0 389679.0 417566.0 445499.0 473613.0 502115.0 530284.0 558098.0 586271.0 615200.0 644437.0 673494.0 703848.0 736563.0 772054.0 809345.0 847091.0 885454.0 924334.0 963685.0 1003596.0 1042837.0 1082373.0 1123302.0 1163794.0 1203967.0 1244582.0 1285411.0 1326770.0 1368671.0 1410843.0 1452640.0 1494664.0 1536391.0 1577198.0 1618249.0 1660176.0 1702107.0 1743837.0 1785177.0 1827242.0 1870383.0 1913243.0 1956429.0 1999952.0 2044876.0 2090000.0 2134830.0 2179529.0 2224620.0 2270551.0 2318808.0 2367324.0 2418771.0 2470489.0 2522026.0 2572793.0 2623000.0 2673744.0 2725230.0 2775532.0 2825634.0 2875862.0 2925468.0 2976260.0 3027992.0 3079272.0 3132552.0 3187146.0 3241338.0 3296568.0 3351734.0 3406829.0 3460559.0 3515789.0 3570941.0 3626675.0 3682550.0 3738964.0 3795394.0 3851585.0 3909520.0 3966659.0 4022844.0 4078880.0 4136793.0 4195782.0 4255712.0 4318483.0 4385009.0 4452361.0 4517976.0 4580857.0 4643545.0 4706207.0 4768513.0 4829946.0 4889945.0 4946516.0 5002589.0 5061650.0 5119203.0 5177035.0 5237263.0 5299253.0 5360382.0 5420379.0 5479414.0 5537040.0 5596743.0 5655743.0 5711780.0 5768887.0 5828116.0 5884713.0 5942092.0 5998021.0 6051985.0 6105850.0 6158141.0 6211015.0 6264144.0 6316251.0 6371421.0 6436353.0 6518665.0 6611554.0 6705787.0 6791374.0 6872375.0 6946392.0 7014195.0 7078277.0 7138888.0 7200524.0 7258960.0 7317060.0 7373831.0 7427721.0 7483540.0 7543610.0 7604726.0 7663013.0 7719387.0 7773662.0 7826701.0 7883457.0 7942681.0 8004254.0 8068393.0 8130904.0 8194941.0 8265236.0 8337378.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8388607.0 8377811.0 8363923.0 8350053.0 8335821.0 8321616.0 8307568.0 8293871.0 8280322.0 8266602.0 8253101.0 8242178.0 8239812.0 8249079.0 8266395.0 8286878.0 8308026.0 8326235.0 8336639.0 8332628.0 8319360.0 8304353.0 8284951.0 8258034.0 8226571.0 8196123.0 8168472.0 8142089.0 8115210.0 8087654.0 8060745.0 8035220.0 8012377.0 7992663.0 7975977.0 7961533.0 7948494.0 7935940.0 7923428.0 7911203.0 7899062.0 7886430.0 7872974.0 7858473.0 7843945.0 7830159.0 7816739.0 7803987.0 7793300.0 7790442.0 7799325.0 7817738.0 7841137.0 7865840.0 7886792.0 7895408.0 7887224.0 7873803.0 7858416.0 7838144.0 7811670.0 7783233.0 7756498.0 7732387.0 7709640.0 7686674.0 7662633.0 7637642.0 7612340.0 7587083.0 7562354.0 7539081.0 7519140.0 7502963.0 7489104.0 7476767.0 7465476.0 7454614.0 7443066.0 7430590.0 7417389.0 7404338.0 7391401.0 7378408.0 7366891.0 7363070.0 7372247.0 7393315.0 7422661.0 7454961.0 7480585.0 7486065.0 7478496.0 7469455.0 7458736.0 7444932.0 7425486.0 7401691.0 7377896.0 7356102.0 7336087.0 7316632.0 7296785.0 7275770.0 7253166.0 7229700.0 7206014.0 7182490.0 7158535.0 7133975.0 7110188.0 7088062.0 7068137.0 7051129.0 7037297.0 7025444.0 7015044.0 7004717.0 6993697.0 6982503.0 6970793.0 6958931.0 6952197.0 6957877.0 6978295.0 7010924.0 7048709.0 7077994.0 7084374.0 7079973.0 7074036.0 7065723.0 7054534.0 7039751.0 7020579.0 6999966.0 6979762.0 6960444.0 6941885.0 6923531.0 6904724.0 6884961.0 6864433.0 6843653.0 6823479.0 6803381.0 6782557.0 6760659.0 6738996.0 6718505.0 6698128.0 6677340.0 6657279.0 6639021.0 6621141.0 6604681.0 6590974.0 6579054.0 6567841.0 6557078.0 6549259.0 6552187.0 6572183.0 6607231.0 6648651.0 6681936.0 6691638.0 6689877.0 6686263.0 6679894.0 6672645.0 6663720.0 6649822.0 6632743.0 6615518.0 6599404.0 6583246.0 6566021.0 6547901.0 6528976.0 6509505.0 6489908.0 6469860.0 6449396.0 6428836.0 6408631.0 6389219.0 6370532.0 6352413.0 6334435.0 6316630.0 6298545.0 6279508.0 6260647.0 6242260.0 6224259.0 6206352.0 6191812.0 6190015.0 6207406.0 6241852.0 6281399.0 6305508.0 6308223.0 6306706.0 6305720.0 6303815.0 6298030.0 6286228.0 6270262.0 6253178.0 6236759.0 6221702.0 6207102.0 6192055.0 6176706.0 6161054.0 6145266.0 6129396.0 6113107.0 6096450.0 6079328.0 6062147.0 6044796.0 6026890.0 6008772.0 5991229.0 5974517.0 5958018.0 5940788.0 5923217.0 5905627.0 5887813.0 5871126.0 5858979.0 5859062.0 5877812.0 5911666.0 5943343.0 5957421.0 5963715.0 5967490.0 5966846.0 5964248.0 5959341.0 5950498.0 5937156.0 5921582.0 5905730.0 5890781.0 5876176.0 5862111.0 5848412.0 5834233.0 5819076.0 5804142.0 5790048.0 5776266.0 5762009.0 5746507.0 5730171.0 5714642.0 5700091.0 5685179.0 5670180.0 5655194.0 5639458.0 5623016.0 5606520.0 5589995.0 5572909.0 5555731.0 5539279.0 5528592.0 5532701.0 5554549.0 5581178.0 5597544.0 5603517.0 5606233.0 5607724.0 5606908.0 5603465.0 5596988.0 5586858.0 5573040.0 5558283.0 5544357.0 5531858.0 5519800.0 5507430.0 5494917.0 5482467.0 5470084.0 5457506.0 5445141.0 5432820.0 5419917.0 5406739.0 5393282.0 5380804.0 5369055.0 5357045.0 5344162.0 5331658.0 5319223.0 5305792.0 5292047.0 5278838.0 5266201.0 5254592.0 5249685.0 5258060.0 5273684.0 5284020.0 5288597.0 5290120.0 5289703.0 5287754.0 5283499.0 5276812.0 5267306.0 5254204.0 5239258.0 5225303.0 5213181.0 5202121.0 5191232.0 5179484.0 5166609.0 5153746.0 5141671.0 5130217.0 5118138.0 5104998.0 5091372.0 5077993.0 5064939.0 5053084.0 5042249.0 5030856.0 5017961.0 5004860.0 4992708.0 4981417.0 4970951.0 4961142.0 4956578.0 4962118.0 4972537.0 4980939.0 4985238.0 4986327.0 4985678.0 4983996.0 4980657.0 4975433.0 4967445.0 4955644.0 4941936.0 4928650.0 4917018.0 4906727.0 4896671.0 4886143.0 4874985.0 4863573.0 4852706.0 4842412.0 4832164.0 4821944.0 4811471.0 4800583.0 4789527.0 4778697.0 4767884.0 4756817.0 4746195.0 4735897.0 4725180.0 4714448.0 4703524.0 4693019.0 4683321.0 4677657.0 4680538.0 4688778.0 4695685.0 4698532.0 4699220.0 4699649.0 4698904.0 4696017.0 4691275.0 4684859.0 4676044.0 4664638.0 4652009.0 4639854.0 4628863.0 4618818.0 4608620.0 4597930.0 4587247.0 4576465.0 4566109.0 4557075.0 4548496.0 4538177.0 4526151.0 4514402.0 4503949.0 4494212.0 4484094.0 4474076.0 4464422.0 4454848.0 4445521.0 4435916.0 4425872.0 4416229.0 4409020.0 4408997.0 4415835.0 4423072.0 4427156.0 4429350.0 4431037.0 4431668.0 4430737.0 4427839.0 4423064.0 4415802.0 4405316.0 4393624.0 4382709.0 4373093.0 4364134.0 4355141.0 4346188.0 4336966.0 4327356.0 4318165.0 4309466.0 4300683.0 4291132.0 4280957.0 4270719.0 4260658.0 4250884.0 4241335.0 4231577.0 4220966.0 4210203.0 4199968.0 4190218.0 4180870.0 4172330.0 4167889.0 4169921.0 4175658.0 4180866.0 4184021.0 4185930.0 4186992.0 4186994.0 4185591.0 4182147.0 4174713.0 4163530.0 4151694.0 4116756.0 3848607.0 3477507.0 3216053.0 3012520.0 2842350.0 2690927.0 2553517.0 2425313.0 2303442.0 2187951.0 2081721.0 1980085.0 1879177.0 1781116.0 1687115.0 1598484.0 1515454.0 1436460.0 1361902.0 1291565.0 1225180.0 1162391.0 1102644.0 1046466.0 993618.0 942655.0 892418.0 842718.0 794350.0 746671.0 699629.0 653140.0 607579.0 562712.0 518934.0 475996.0 434689.0 395306.0 357307.0 320758.0 284630.0 249175.0 214886.0 182139.0 150733.0 120058.0 90031.0 60935.0 32794.0 5494.0 -20222.0 -44473.0 -68542.0 -92842.0 -116507.0 -138720.0 -160187.0 -180730.0 -199673.0 -216817.0 -232992.0 -248630.0 -263788.0 -278947.0 -293777.0 -307654.0 -320831.0 -334222.0 -348097.0 -362183.0 -376481.0 -390859.0 -404552.0 -417485.0 -429948.0 -442296.0 -454816.0 -467057.0 -479111.0 -491052.0 -502197.0 -513200.0 -523996.0 -534669.0 -545154.0 -555221.0 -565470.0 -575573.0 -585501.0 -595131.0 -604677.0 -614165.0 -622780.0 -630808.0 -638660.0 -646711.0 -654443.0 -661769.0 -668224.0 -674466.0 -680778.0 -686946.0 -692897.0 -698855.0 -705029.0 -711630.0 -718554.0 -725701.0 -733042.0 -740324.0 -747408.0 -754107.0 -760318.0 -766362.0 -772196.0 -777893.0 -783675.0 -789242.0 -794549.0 -799722.0 -804547.0 -809104.0 -813650.0 -818700.0 -823843.0 -828836.0 -833606.0 -838597.0 -843560.0 -848627.0 -853579.0
Here is the first graph showing the data from the whole measurement.
As for the first measurement, we can now first focus on the part where the arm cuff is slowly deflating and where we can see the pulse.
Now, we can find the heartbeats by finding the peaks of all of the oscillations that we can see in the plot.
And in the end, we can take a look at the 2 delta graphs. I just changed the BPM from 79 to 68 for the calculation, since that was the measurement that my mom got on the blood pressure monitor.
As you can see by comparing the results from me and my mom, you can see I have a slightly higher HRV than her, which is normal considering that I'm younger and that she was walking around and working before taking her measurement. But the graphs also show that no irregularities were noticed.
One thing that I have to point out of course is that this was just my curiosity about what I can pull from this data and that for actual medical measurements, there are way better ways of tracking HRV, though, for something like more serious heart rate irregularities, I feel that this method would be sufficient in finding them.
7. Summary
This is where I'll leave this part of the project for now. As I said at the beginning of this blog, I was writing this blog as I went and didn't know how successful it would be. Looking at it now, I didn't achieve my end goal of actually producing the numbers, but it went way better than I expected it to go when I look back at how it started. I didn't manage to get the blood pressure reading, but I did manage to actually record the pulse using the pressure sensor, rather reliably. I left the raw data in the blog if anyone wants to try working with it. I have some other aspects of the project I need to concentrate on now but will come back to this portion as well. The goal with this part will still be to get a blood pressure reading, but looking at the results now, I can say for sure I can at least add a heartbeat buzzer to a commercial blood pressure monitor that doesn't have that feature. It maybe sounds like a gimmick, but this is something that we found incredibly useful when grandma needs to take here blood pressure measurements. Thanks for reading the blog, hope you found it interesting and enjoyed it!
Milos
Top Comments