Software apps and online services
Hand tools and fabrication machines
In this period of isolation, I've built an oximeter with parts already in house. An oximeter after all is just made by two leds and a photodiode.
I'm not an expert of medical knowledge and at this stage of the project I'm notsure that this work has a diagnostic value, but it's a good educational project to study how it works, and probably with a few tips it could become an homemade medical tool.Oxygen saturation and COVID-19
In this incredible period of our life we've learned a lot of things about viruses, lungs, surgical masks, soap and washing hands. Everybody reads about symptoms like coughing, fever and breathing difficulties. We've also known that one way to measure breathing difficulty is reading the amount of oxygen in our blood.
This measure can be read indirectly with a medical device called Oximeter. You have probably already seen it, it's a non invasive device that is placed on a finger with some pulsating lights that do the work. Like this:
Normally, when you're ok, you have a percentage of oxygen saturation (SpO2) near or grater than 95%. When saturation goes down below 90% and you have cough and fever, it's a problem.
If any maker could build an oximeter, discover an infection would be easier and could help people to decide to go to hospital when the problem really exists and not for a panic attack.First, understand how heartbeat sensor works
I've started this project playing with a KY-039 heartbeat sensor that I've found in a kit sensor that many of us have in home. As you can see in the circuit below, it's just a infrared led that lights a photodiode. There are also two resistors to protect the led and read the small signal of the sensor.
So if you don't have a KY-039 sensor you can build your own sensor with few components.
The finger is placed between the sensor and the photodiode like in this photo (originally taken from this site and modified):
The light emitted by the infrared led is partially absorbed by the nail, the skin, and all the other parts of your finger, but it's not constant because it changes following the changes of the blood running in your veins. When your heart makes a beat the blood is pushed in your veins and the light absorption changes. We can measure the current generated by the photodiode illuminated by the infrared light that reach it.
The KY-039 sensor has a S (signal) pin to read that changing value.We can measure heartbeat rate by counting peaks of the signal
Reading a value from a variable signal from a sensor it's not so easy, because there is a lot of noise, the signal is really low, and we need to make some math to find the good values to plot.
I've got to thank this useful post from Johan Ha, which explains how to calculate the average of the signal and it also explains how to remove the noise made by a home lamp (that light is a noise!).
The trick is to make an array in which we push a value and drop a value to make the average of the last X values read from the sensor. He has also describes a way to find the rising of the signal, by counting N growing values. I mean, when a value is grater than the preceding value for N times, it's a peak.
Using the Arduino Serial plot tool or another serial tool to analyze values printed on COM port (such as SerialPlot), and trying different values we can define a correct number N (
rise_threshold constant n the code). If you define a number too big or too small you can miss some beats or count a dicrotic notch as a beat.
Once you've understand how to fine the peaks, just count them, or calculate the time between a small serie of beats to determine your
BPMrate (Beats Per Minute).
Our blood absorbs light in a different way with the change of the wave-length of the light. The red light (
~600nm) is absorbed better by the blood that contains more oxygen, so we can compare the measures made with infrared led (
~950nm) with the ones made with red led and find the percentage of oxygen in our blood. That value is called
Sp02% (peripheral capillary oxygen saturation).
Since I have a KY-039 sensor I've decided to modify it. It has just an infrared led, so I've added a RED led, disconnect the IR led from the Vcc and connect with a
330 ohm resistor the two leds to two different pins of Arduino.
(If you don't have a KY-039 sensor tomodify you can build it, it's just a couple of leds, a photodiode and 3 resistors, and the schematic is really simple!)
Here is the schematic of the modified sensor:
In this way we can turn on the IR led and read the value from the KY-039 S pin, then we can turn off the IR led and turn on the RED led, and read the value from the KY-039 S pin.
Here it is mine:
If you plot the two signals you can see that IR values are always lower than Red values.
To find a good signal remember to place the fingertip correctly on the photodiode and the leds should touch the nail, when you find a comfortable position with good reading on the plot do not change it.
Since the signals are low and noise is very problematic, to get useful mesures I've noticed that a good ambient light is always needed. So, don't move your finger while measuring and don't change the light, just a shadow on the sensor could change everything.How is measured saturation SpO2%
The oxygen saturation level (SpO2) is the fraction of oxygen-saturated hemoglobin relative to total hemoglobin and is a function of a parameter called R (I've found this information in an academic paper from Politecnico of Milan), which is calculated using minimum and maximum values from the two signals:
R = ( (REDmax-REDmin) / REDmin ) / ((IRmax-IRmin) / IRmin)
Each instrument has it's own R and it's needed calibration to find the curve (the function) that connects R with SpO2%.
We've counted the number of peaks, but now we need to find max and min values of the two curves (RED led and IR led).
To accomplish this job we evaluate the "period" of the heartbeat (that is to say how many milliseconds a beat lasts) and divide it for the sampling rate to determine how many samples make a period. The sampling rate is in our case 40 milliseconds because we read the IR led for 20 milliseconds and then the RED led of another 20 milliseconds.
The period of the beat is the time that passes between two rising curves in the signal.
So I can analyze the last L samples (where L = period / 40), which I have saved in an array, to find REDmax, REDmin, IRmax and IRmin values.
With maximum and minimum values I can calculate R.
R, L and period are calculated every beat, so the calculus of R is also done for every beat.From R to SpO2%: How to calibrate the oximeter?
The function that links R with SpO2 can be simplified with a straight line:
SpO2 = K * R + M
So we need two points (two couples of value of SpO2 and R) to determine K and M. The only way to find these 2 points is using another oximeter and read the values from its display.
The new oximeter will be the reference, we read the SpO2 value while measuring the R values from our homemade oximeter.
First breath normally, and read the value of SpO2 and R. Write it down.
Then try to keep the breath and after a 10-20 seconds you will read SpO2 in the new oximeter decreasing, you should also see the R parameter of your oximeter growing. Before faint, write down the values of SpO2 reached and the value of your R parameter.
Solve the 2nd degree equation and found K and M for your oximeter.
Now it's possible to calculate both bpm and SpO2 values for every measure of R.
I've also added a display to show all the the numbers, I show values only if I've found at least 5 measures of periods that doesn't change too much (±
10% of the period length). In this way I remove values that changes too much that depends on the poor components or change of ambient lights or finger movement.
The c value indicates that the values shown are calculated with c stable measures.Project improvement: remove the ambient light variability
After a few days of playing with my project, I've found a way to improve it.
I've notice that with these low costs components (we're using just leds and a photo diode!) the measures are too much ambient-light dependents and this is not a good thing, if we want to read data properly in a real working environment. Since I've notice that in a sunny day the results are better than with cloudy light or in the evening when I use an electrical lamp, I've decided to add a third led, which is always on and provides just light on the finger.
With this 3-leds-sensor the measures are also taken under a black cloth to exclude the ambient light which could always change.
Now, the results are better and do not depend anymore on the ambient light.
I've also had to re-calibrate the oximeter, as you can see from the video after few seconds it correctly finds bpm ans SpO2%: