These days we are a little spoiled. There are many sensors you can grab, hook up to your favorite microcontroller, load up some simple library code, and you are in business. When [Raivis] got a MAX30100 pulse oximeter breakout board, he thought it would go like that. It didn’t. He found it takes a lot of processing to get useful results out of the device. Lucky for us he wrote it all down with Arduino code to match.
A pulse oximeter measures both your pulse and the oxygen saturation in your blood. You’ve probably had one of these on your finger or earlobe at the doctor’s office or a hospital. Traditionally, they consist of a red LED and an IR LED. A detector measures how much of each light makes it through and the ratio of those two quantities relates to the amount of oxygen in your blood. We can’t imagine how [Karl Matthes] came up with using red and green light back in 1935, and how [Takuo Aoyagi] (who, along with [Michio Kishi]) figured out the IR and red light part.
The MAX30100 manages to alternate the two LEDs, regulate their brightness, filter line noise out of the readings, and some other tasks. It stores the data in a buffer. The trick is: how do you interpret that buffer?
[Raivis] shows the code to take the output from the buffer, remove the DC component, pass it through a couple of software filters, and detect the heart rate. To read the oxygen reading, you have even more work to do. You can find the code for the device on GitHub.
If you want to build your own without a dedicated IC, grab a clothespin. Or try this more polished build.
I think the concept of finding that it takes a lot of processing to get useful results out of devices might stem from feeling that these days we are a little spoiled and that there are many sensors you can grab, hook up to your favorite microcontroller, load up some simple library code, and you are in business?
^this^
Any time I buy a new breakout board or component I write my own code to operate them instead of just downloading someone else’s code, I find it more interesting that way.
Interesting? Probably. Better? Probably. But faster? Very rarely. One of my biggest frustrations with open source code (or code in general) is the fact that it is frequently sloppily and quickly written and almost never optimized or tested or sometimes even documented at all. Yes, it typically “works” but the idea that it will be quick and you can just slap some existing code in and you are ready to go very rarely works out once you need to do anything else with said code except the single thing it was written to do.
It’s like trying to put together LEGO blocks with Tinkertoys, DUPLO blocks and Lincoln logs and expecting it to work smoothly.
Usually better and faster to just write your own code. It is just that there is still a time commitment involved to do so, negating the advantage you were hoping to achieve in the first place.
“Faster” is why there is a flood of crap gadgets out there that almost work. It is also why the job market is saturated with “ingeneers” who cannot really engineer much.
I have the exact same notion when it comes to breakout boards. I really do like to write my own code to interface it. Not only it is more fun and educational, but after I’ve written the code to arduino for example, it is much easier to port the code to a different micro, like ARM.
Exactly, otherwise just buy a finished product. It boils down to why you are doing this. If all you do is buy things, selecting from your favorite supplier, then rummage around and find somebody elses driver, what is the point?
Can anyone find that breakout board on Tindie?
deepenmind has them on ebay
I have one of those oximeters and I believe the more accurate is the one that measure not only the oxygen level but the carbon dioxide level as well.
The MAX30101 and MAX30102 do have PPG capabilities and are the same footprint/pin layout.
Huh? How do you measure CO2 with a finger probe????
Absolutely excellent write-up.
A joy to read and the code was well presented and clear.
I doesn’t take much imagination to think colored light of opposites as a probe when as looks at skin color as a means of observing condition.
Pulse is the easy part, oximetry is the tough part
Making one of my own some years back was a tangled mess of analog and digital
I assume most of the analog is handled in the module and that’s a big help
The tough bit comes from filtering the slight difference in permissivity between oxyhaemoglobin and deoxyhaemoglobin, at just the right time in the pulse cycle, and matching that to environmental variables (what’s their blood concentration, how far are you from your sensor? Are you looking at reflected, refracted, or scattered light, and how much of each? Which part of the pulse cycle represents the arteriolar saturation, and how does that change with peripheral vasoactivity?)
Then you need to compensate for hardware limitations, the messy wavelengths of driven LEDs, and the finicky nature of phototransistors.
All of which only works within a certain set of assumptions (usually that anyone with saturations <90% are all equally borked,and a certain ratio of adipose to connective tissue). Pity I work in kids whose blood is mixed down to 60-70% (on direct chemical measurement) and do things to them that makes the blood shift more or less from the arteriolar or venule part of the cycle.
Some systems use a broader array of wavelengths, by measuring more you can solve for a more complex model, but you still end up with a bunch of assumptions.
Indeed, getting pulse is simple. And yes you are correct, the MAX30100 just handles the anlog part, and nothing else. It still reduces your PCB footprint quite a bit.
And this is why medical devices are expensive: The code is not only difficult, but it has to *provably* work, with studies of accuracy and dependability. This happens to be on the simpler end of medical devices, with no patient safety issues (you can’t die from having a couple LEDs strapped to your finger) — a lot more work is required to get approval on implantable, active devices such as pacemakers or the pumps that deliver pain drugs, a lot less for a tongue depressor — yes, it’s considered a medical device, and a new one has to go through a simple approval that says, “this is pretty much just like others on the market with merely these changes. For more info, google “510K” for the simple end, and “IMDRF” for how international plans are going for electronic filing of device approvals.
The medical device that drives the LEDs and reads the sensor might be expensive, but the LEDs and sensor are really cheap now. The local hospitals now use a sticker based system, that wraps around a finger or ear. They then throw out the LED/sensor when you leave the hospital. Something to do with drug resistant bacteria, I suspect.
Before you rush out to grab one, they aren’t using them in doctor’s offices yet. But if you know someone in the hospital, or are friendly with the supply folks who know when they are going to hit the ‘no longer guaranteed sterile’ date, you can probably grab a few for free.
I wrote the code for the pulse oximeter for a patient monitor (Invivo). Getting it right is VERY difficult. The hardest part is getting the light level right. Think about it: Your patient may be a little old white lady with skin you can almost see through. Another might be a big black iron worker with fingers the size of my thumbs. The pulse oximeter needs to adapt to both extremes.
For that matter, your patient may be a neonatal and your probe may clip to his earlobe.
It’s an easy thing to write code that will ramp the light levels up slowly until it finds the optimal level, but nobody wants to wait that long. So the trick is to set the level FAST, and that’s not easy. My first try was to use successive approximation, but even that was too slow.
You also need to recover from any number of events. Patient raises or lowers his arm; heart skips beats, etc., etc.
Finally, how do you test the thing to make sure it’s working, and is accurate? You have to test as many test subjects as possible, and compare the output with values taken from blood tests. In other words, clinical trials.
Yup, this what I was trying to stress out in the article as well. The SpO2 concentration is just a guess. Since I don’t have any means of calibrating the sensor, at all.
If you have a feedback loop, and it oscillates … consider adding the rest of the PID controller (and tuning it) rather than just decreasing the gain.
Note that this IC is NRND (Not Recommended for New Designs). You’d be wise to use the MAX30102, instead.
Interesting project. As for calibrating finger pulse oximeters are cheap, also are ideal starting point when seeying what’s going on.
pls how can i download max30100 library on proteus