The SparkFun MAX30105 Particle Sensor is a flexible, powerful sensor enabling sensing of distance, heart rate, particle detection and even the blinking of an eye. The MAX30105 has been equipped with three LEDs as well as a very sensitive photon detector. The idea is to pulse the different LEDs, then detect what shines back. Based on the reflected signature it's possible to detect different types of particles or materials (such as oxygenated blood or smoke from a fire).
The MAX30105 utilizes a red LED, a green LED, and an IR (Infrared) LED for presence sensing, heart-beat plotting and heart-rate monitoring among its multitude of uses, including Pulse Oximetry. The MAX30105 is designed to operate at 5V and can communicate with both 3.3V and 5V microcontrollers. We’ve also written an Arduino library for the MAX30105 Breakout which takes care of all of the I2C communication, bit shifting, register writing and sample reading.
We welcome your comments and suggestions below. However, if you are looking for solutions to technical questions please see our Technical Assistance page.
Based on 2 ratings:
This little sensor is working GREAT for my project.
Durable too! i usually fry something new pretty quickly,
and i have wired this on up wrong a bunch of times while trying to extend the length of the leads going to it, and its still ALIVE!!!
The supplemental library and sketches work GREAT too, which is really the most important element!
With a few tweeks to some code i have this thing firing off 12 volt water valve solenoids like a clock! (I'm not even using the oximetry part of it, just the pulse sensor, but im sure the SPO2 works fine too).
Thanks for the solid product, and the support!
Kevin Leeser RN University of Michigan
Board works well in the dark. No ambient light.
Did someone let the intern play with the shiny hyper-photogenic quarter again?
I was working on something where I needed a blink sensor and was looking at reflectance sensors, but the question comes up with invisible light (IR) if it's eye safe. Do you know how eye safe this is in continuous use and what distance we can expect from it for blink sensing? http://www.intersil.com/content/dam/Intersil/documents/an17/an1737.pdf
Your app note link is fantastic! Thanks for posting. As I was designing the MAX30105 breakout I was excited to get the ability to sense blinking. We used it on a friend's Halloween mask to great effect. We did consider the effects of longterm IR exposure but we didn't have the app note to work with. Here's what I calculate:
For our project we used the Example2_Presence_Sensing sketch. We turned on the red LED to 0x02 (very low) just to let us know the sensor was operating the IR LED. We were able to bring the IR LED power down to 0x0A or approximately 2mA with a sample rate of 400Hz and pulse width of 411us and were still able to detect blinking.
This equates to 1107us channel timing (page 26 of datasheet). I calculate 740uA equivalent current going to the LED. Assuming forward voltage of 1.35V (page 7) power is 1mW. Selecting various configurations on the Intersil XLS I am able to set an effective avg emitted power of 1.62mW (so more than my setup) using the ISL29038 set to 6.25ms sleep and 110mA IRDR current. Assuming 30mm distance from sensor mounted on Halloween mask to the eye, we get corneal exposure of 1.8W/m2 and an exposure limit of 100W/m2. We should be good for any length of time.
That said, less is better. We had very rudimentary filtering and with some better FIRs we could probably bring the sample rate down and overall exposure time quite a bit lower.
My setup example depends heavily on the distance from sensor to eye. The further away the sensor can be the less exposure the eye will have to IR, but you'll need to increase the IR LED power (so six of one, half-dozen of the other). I'd recommend placing the sensor closer to the eye and turning the IR power way down so that you get a cleaner signal, filter more, and see if you can get the sampling rate as low as possible.
I'm using this to extract PPG signal for my final year project, Please someone help me with the code to extract a proper PPG signal from this sensor. (project title- non invasive hemoglobin concentration measurement)
I love it! I need it to trigger a relay on the peak of each pulse... is there a simple sketch that will get this to happen? I had luck with the MAX30100 chip, that one that was wired wrong, but my soldering job fell apart and that board is dead.
thanks! I will post that sketch as soon as i can find it.
Kevin Leeser
Hello,
Running the example 8 SPO2 code, I am getting this error:
Example8_SPO2:96: error: cannot convert 'uint16_t* {aka unsigned int}' to 'uint32_t {aka long unsigned int}' for argument '1' to 'void maxim_heart_rate_and_oxygen_saturation(uint32_t, int32_t, uint32_t*, int32_t*, int8_t*, int32_t*, int8_t*)'
Is there a fix for this error?
Thank You
Yep. Discussed and fixed on this issue on the repo.
Hi ..wondering if this sensor would be best to use to detect smoke and how much smoke would be required to sense it?
if not do you have any suggestions on what would work?
Thanks
The sensor is advertised by Maxim as being 'capable' of detecting smoke. The issue is that there is not currently an open source algorithm that I know of that has been developed. So the sensor can certainly give you data (I see green, red, and IR LED light be reflected at these levels) but it's a challenge that has not yet been solved turning those ADC values into information (I see 7% smoke in the air!).
I'm trying to use this sensor together with an arduino pro micro. However, arduino pro micro has not neither SCL and SDA nor A4 and A5. Can I change something in the code to make the connexions to A2 and A3 instead? I am unable to find where to set this information. Thanks.
What you need is SCL and SDA which are the I2C lines. On the ATMega328 they happen to be on pins A4 and A5. On the Pro Micro they are on D2 and D3. It looks like they are not labeled on the board because of the size, but check out the graphical datasheets on the Pro Micro for more information.
Thanks!
Has anyone tried using this to measure pulse, but not on a finger? Like on the wrist? Would love to know if that will work for my project!
Following the Hookup Guide on Example 1: Basic Readings when I open Serial Monitor, instead of R[xxxxxx] IR[xxxxxx] G[xxxxxx], I am getting a long line of strange characters, such as:
¹ãþñøêøÿþ÷ãøþüÊòþÊ
I tried on 2 seperate Arduino's, with the same result. Could this a problem with the I2C? Or my hardware?
Sounds like you have a baud rate mismatch. Double check to see you have the Serial Monitor set to 115200 baud and see if that clears things up for you.
That solved the problem. Thank you!
Hey there... I was wondering if I could use this sensor to measure the paint-output of a spray can. And what distance would it need to do that. And does it work behind a protective glass? Because obviously I don't want to ruin the sensor with color. And last but not least.. would it work with every color, even transparent colors? Thanks for your help!
Frickin awesome question, unfortunately I don't have a definitive answer.
The sensor has a glass lens to protect the inside bits but an additional layer to isolate the SMD components is a great idea.
You should be able to detect a binary 'do I see paint?' easily enough but calibrating that to the amount of paint is tricky. We haven't seen full-blown particle detection projects yet and I'm not sure of the flow rate out of the nozzle and whether the sensor (at 500Hz) would be fast enough to properly capture it.
As long as the transparent particles reflect IR/Red/Green differently (and I bet they do) then the sensor would be able to detect them.
Hey Nate, thanks a lot for your quick reply! Assuming that the color-output of a new can is max I think I can use that to calibrate the system for each can. It's just that I need to figure out when the can gets empty so I get an alarm. You didn't answer my question about the distance though. Any idea about that?
I suspect the paint cloud will have a good IR signature meaning you should be able to detect the 'cloud' over multiple inches. If all you need is a 'is it shooting paint?' sensor you could probably set the sensor multiple (6) inches to the side at a right angle to the spray. I worry that the spray would be very diffuse after traveling 5 or 6 inches from the nozzle. I would try to capture the spray within one inch of the paint exiting the nozzle to try to get as dense of a material to sense as possible.
Hi! I am using this sensor and this works perfectly in Arduino but if I use samd21, I get this error: libraries/SparkFun_MAX3010x_Pulse_and_Proximity_Sensor_Library/src/MAX30105.cpp:628:19: error: 'BUFFER_LENGTH' was not declared in this scope if (toGet > BUFFER_LENGTH) Do you know what is the problem? Thank you.
Hmm. Your SAMD21 platform is not pulling in the BUFFER_LENGTH define that is usually in Wire.h. The quickest fix is to throw a
at the top of MAX30105.h. I'll do some more testing (Wire.h should already have this) and update the repo as needed.
So it took me awhile to find where Arduino was pulling in the Wire.h for the SAMD21 platform. Because I'm using our SAMD21 Mini Breakout the header file was located in the User directory under windows (yours will vary but: C:\Users\nathan.seidle\AppData\Roaming\Arduino15\packages\SparkFun\hardware\samd\1.2.2\libraries)
Next, the SAMD version of Wire.h does not define BUFFER_LENGTH and is pulling in RingBuffer instead. RingBuffer uses a 64 byte buffer so re-defining BUFFER_LENGTH of 32 is safe but less than the actual buffer size of 64.
I've updated the MAX3010x library to define the I2C_BUFFER_LENGTH correctly based on the platform being used. The library should be updated in 24 hours (or however long Arduino takes to pull in lib updates). You can see the changes here in the mean time.
Thank you very much Nate. Now it is working. One more question, In the code of SPO2, I have this error: maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate); ^ exit status 1 cannot convert 'uint16_t* {aka short unsigned int}' to 'uint32_t {aka long unsigned int}' for argument '1' to 'void maxim_heart_rate_and_oxygen_saturation(uint32_t, int32_t, uint32_t*, int32_t*, int8_t*, int32_t*, int8_t*)'
Fixed pushed to github. The SpO2 algorithm is largely untested and is heavily based on Maxim's code. I tweaked it to work with in Arduino v1.6.xx but left out an important define that declares the sensor arrays as 32-bit for platforms (SAMD21) that can handle it. Should work now.
Now, it is working. Thank you very much Nate.