Open talal44 opened 6 years ago
Did you follow the hookup guide? I'm hoping you used a rubber band or other positive pressure device to hold the sensor against your finger?
Thanks for your prompt reply. I did everything as the guide explains, the spo2 looks great, however the hr is always high. 150 and above, that doesn't seem to be right. I am quite relaxed and alive.....
Let's check the basics.
What platform are you connected to? What voltage are you running at? Do you have a link to the board you purchased?
On Thu, Aug 9, 2018, 9:30 PM talal44 notifications@github.com wrote:
Thanks for your prompt reply. I did everything as the guide explains, the spo2 looks great, however the hr is always high. 150 and above, that doesn't seem to be right. I am quite relaxed and alive.....
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-411964930, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHJbuLs2Isb4S5VlnOV6n5fl-1urX3Bks5uPP43gaJpZM4V3goW .
I have two boards, arduino uno and elegoo mega2560 r3. It doesn't make any difference whether I connect my sparkfun max30105 to 5v or 3.3v. I got almost same reading both ways.
And just to be clear, are you using the SparkFun board?
Looks like you're running example 8. Do you see different output when you run example 5_HeartRate? The IC is configured differently in Example 5.
I am using the red Sparkfun max30105 board. I get better better sensible and logical hr numbers with example 5.
Ah, ok. Sounds like the hardware is functioning. Both examples depend on Maxim's algorithms. We can support the library but you'll need to talk to Maxim for support on the algorithms.
A quick search turned up some other options. This example might get you started down a better Sp02 detection.
Thanks a lot for your guidance. However, I still didn't got it, am I the only one who has this problem with the HR numbers in example_8? even when I use my new Sparkfun esp8266 thing board I get the same results. When I opened this issue I was hoping that there is someone who had the same issue and found a solution somehow.
I have run across the exact same problem. I'm running a MAX30102 on a DIYmall breakout board. http://a.co/d/d31zetS On an ESP8266 (AI-Thinker) - (Adafruit Feather Huzzah equivalent).
All of the examples work as expected except the SPO2 example 8. I get readings like this: red=105481, ir=121830 red=105500, ir=121889 red=105502, ir=121942 red=105521, ir=122030, HR=166, HRvalid=1, SPO2=100, SPO2Valid=1 red=105529, ir=122088, HR=166, HRvalid=1, SPO2=100, SPO2Valid=1 red=105498, ir=121597, HR=166, HRvalid=1, SPO2=100, SPO2Valid=1 red=105229, ir=121368, HR=166, HRvalid=1, SPO2=100, SPO2Valid=1
The calculated values do fluctuate but they seem like complete garbage.
My heart rate during the above measurement was between 50 and 60 bpm with a tight finger strap (velcro) and clean red/ir signals (seen if I switch to plotting them like this): Serial.print(redBuffer[i], DEC); Serial.print(F(",")); Serial.println(irBuffer[i] - 17000, DEC);
The - 17000 on the ir was to move it closer to the red so the plotter is zoomed in better. (I hate you Arduino serial plotter, but you're convenient.)
I was hoping for a quick on chip solution to this so I could move on but looks like I'll have to dig in a bit more. I haven't dug into the yet but I'll share my results when I do.
I'm curious, has ANYONE seen this example work properly?
UPDATE: Tired again on an Adafruit Feather M0, same results.
Having the same issue, same board as ThingEngineer. Anyone find another board/code example that works for SpO2?
Same issue. It is not about the board, it is about the code, or specifically the algorithm. The code from Maxim can work sometimes, but it doesn't work well at the most time ,especially under the external light interference. I had checked the waveform of raw data and found it worse when I turned on the table lamp next to me. So you can use some black item to cover the sensor board and try it again. But I still think the code from Maxim is too sensitive to the interference and we need to improved it.
Hi, couple of years later still finding the same issue with HR with using code from example 8, based on spo2_algorithm.h library. But, I get reasonable good data with example 5, based on "heartRate.h" lib. So, has anyone solved this questions. Is it possible to combine HR calculated from example 5 and spo2 from example 8? BTW both seems to work fin in MAX30100. I hope there is still someone interested in this.
thanks
I am also having the same issue. Heart Rate is just all over the place the Oxygen reading seems good. When i combine 5 and 8 the heart rate is still all over the place. Soluna1 I will keep report back with any additional information.
I am also struggling with this issue! Example 5 works like a charm for HR. Example 8 shows SPO correctly, but HR is completely messed up. I've been trying to combine them, but apparently the issue is when you call setup() with different values. Setup() conf for example 5 doesn't work with spo and setup parameters from example 8 doesn't get correct HR.
I have a new algorithm that seems to work fairly well. I will reply to this email in a little bit.
On Mon, Jun 15, 2020 at 3:51 AM lfssp notifications@github.com wrote:
I am also struggling with this issue! Example 5 works like a charm for HR. Example 8 shows SPO correctly, but HR is completely messed up. I've been trying to combine them, but apparently the issue is when you call setup() with different values. Setup() conf for example 5 doesn't work with spo and setup parameters from example 8 doesn't get correct HR.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-643964972, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNPQOO5XIE5Q4SXPTLDRWXHJTANCNFSM4FO6BILA .
That's a good news @caferrick . Waiting to see your progress.
I did not strip anything out so please use what you like. The program send the SPO2 and HBM via bluetooth. The device that I am using is an Arduino feather.
/**** *
***/
// BlueTooth
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);
MAX30105 particleSensor;
//#define MAX30105 //if you have Sparkfun's MAX30105 breakout board , try
/ BlueTooth service information /
int32_t ServiceId; int32_t hrmMeasureCharId; int32_t hrmLocationCharId; int32_t spoMeasureCharId;
/** heart rate *****/ static double fbpmrate = 0.95; // low pass filter coefficient for HRM in bpm static uint32_t crosstime = 0; //falling edge , zero crossing time in msec static uint32_t crosstime_prev = 0;//previous falling edge , zero crossing time in msec static double bpm = 40.0; static double ebpm = 40.0; static double eir = 0.0; //estimated lowpass filtered IR signal to find falling edge without notch static double firrate = 0.85; //IR filter coefficient to remove notch , should be smaller than frate static double eir_prev = 0.0;
SAMPLING to 1
your finger is not on the sensor
your finger is not on the sensor
crossing is found for filtered IR signal
// A small helper void error(const __FlashStringHelper*err) { Serial.println(err); while (1); }
void setup() {
boolean success; Serial.begin(115200); Serial.println("Initializing...");
Serial.println(F("Adafruit Bluefruit Heart Rate Monitor (HRM) Example")); Serial.println(F("---------------------------------------------------"));
/ Initialise the module / Serial.print(F("Initialising the Bluefruit LE module: "));
if ( !ble.begin(VERBOSE_MODE) ) { error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?")); } Serial.println( F("OK!") );
/ Perform a factory reset to make sure everything is in a known state / Serial.println(F("Performing a factory reset: ")); if (! ble.factoryReset() ){ error(F("Couldn't factory reset")); }
/ Disable command echo from Bluefruit / ble.echo(false); ble.info();
// this line is particularly required for Flora, but is a good idea // anyways for the super long lines ahead! // ble.setInterCharWriteDelay(5); // 5 ms
/ Change the device name to make it easier to find / Serial.println(F("Setting device name to 'Bluefruit HRM': "));
if (! ble.sendCommandCheckOK(F("AT+GAPDEVNAME=HMHS Health Monitor")) ) { error(F("Could not set device name?")); }
/ Add the Heart Rate Service definition / / Service ID should be 1 / Serial.println(F("Adding the Heart Rate Service definition (UUID = 0x180D): ")); success = ble.sendCommandWithIntReply( F("AT+GATTADDSERVICE=UUID=0x180D"), &ServiceId); if (! success) { error(F("Could not add HRM service")); }
/ Add the Heart Rate Measurement characteristic / / Chars ID for Measurement should be 1 / Serial.println(F("Adding the Heart Rate Measurement characteristic (UUID = 0x2A37): ")); success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A37, PROPERTIES=0x10, MIN_LEN=2, MAX_LEN=2, VALUE=00-40"), &hrmMeasureCharId); if (! success) { error(F("Could not add HRM characteristic")); }
/ Add the Body Sensor Location characteristic / / Chars ID for Body should be 2 / // Serial.println(F("Adding SPO2 Sensor characteristic (UUID = 0x2A29): ")); // success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2901, PROPERTIES=0x10, MIN_LEN=2, MIN_LEN=2, VALUE=00-41"), &spoMeasureCharId); // if (! success) { // error(F("Could not add BSL characteristic")); // }
/ Add the Heart Rate Service to the advertising data (needed for Nordic apps to detect the service) / Serial.print(F("Adding Heart Rate Service UUID to the advertising payload: ")); ble.sendCommandCheckOK( F("AT+GAPSETADVDATA=02-01-06-05-02-0d-18-0a-18") );
/ Reset the device for the new service setting changes to take effect / Serial.print(F("Performing a SW reset (service changes require a reset): ")); ble.reset();
Serial.println();
// Initialize sensor if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed { Serial.println("MAX30102 was not found. Please check wiring/power/solder jumper at MH-ET LIVE MAX30102 board. "); while (1); }
//Setup MAX30102 byte ledBrightness =70; //Options: 0=Off to 255=50mA byte sampleAverage = 2; //Options: 1, 2, 4, 8, 16, 32 byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green //Options: 1 = IR only, 2 = Red + IR on MH-ET LIVE MAX30102 board int sampleRate = 400; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200 int pulseWidth = 411; //Options: 69, 118, 215, 411 int adcRange = 4096; //Options: 2048, 4096, 8192, 16384 // Set up the wanted parameters particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
}
double avered = 0; double aveir = 0; double sumirrms = 0; double sumredrms = 0; int i = 0; int Num = 100;//calculate SpO2 by this sampling interval
double ESpO2 = 95.0;//initial value of estimated SpO2 double FSpO2 = 0.7; //filter factor for estimated SpO2 double frate = 0.95; // .95 default low pass filter for IR/red LED value to eliminate AC component
void loop() {
uint32_t ir, red , green; double fred, fir; double SpO2 = 0; //raw SpO2 before low pass filtered int idx=0;
particleSensor.check(); //Check the sensor, read up to 3 samples
int Ebpm = 60;
while (1) {//do we have new data
red = particleSensor.getRed(); //Sparkfun's MAX30105 ir = particleSensor.getIR(); //Sparkfun's MAX30105
red = particleSensor.getRed(); //why getFOFOIR outputs Red data by
MAX30102 on MH-ET LIVE breakout board ir = particleSensor.getIR(); //why getFIFORed outputs IR data by MAX30102 on MH-ET LIVE breakout board
i++;
fred = (double)red;
fir = (double)ir;
avered = avered * frate + (double)red * (1.0 - frate);//average red
level by low pass filter aveir = aveir frate + (double)ir (1.0 - frate); //average IR level by low pass filter sumredrms += (fred - avered) (fred - avered); //square sum of alternate component of red level sumirrms += (fir - aveir) (fir - aveir);//square sum of alternate component of IR level
Ebpm = (int) HRM_estimator(fir, aveir); //Ebpm is estimated BPM
if (ir < FINGER_ON)
ESpO2 = MINIMUM_SPO2; //indicator for finger detached
if ((i % Num) == 0) {
double R = (sqrt(sumredrms) / avered) / (sqrt(sumirrms) / aveir);
SpO2 = -23.3 * (R - 0.4) + 100;
ESpO2 = FSpO2 * ESpO2 + (1.0 - FSpO2) * SpO2;
Serial.print(SpO2);Serial.print(",");Serial.print(ESpO2);
Serial.print(" BPM : "); Serial.print(Ebpm);Serial.print(", R :");Serial.println(R); sumredrms = 0.0; sumirrms = 0.0; i = 0;
Serial.print("Heart Rate: ");
Serial.println(Ebpm);
sendHRData(Ebpm, ESpO2);
//sendSPOData(ESpO2);
break;
}
particleSensor.nextSample(); //We're finished with this sample so move
to next sample
// Serial.println(SpO2); }
}
void sendHRData(int heartRate, int spo2) {
Serial.print("HR : "); Serial.print(heartRate); Serial.print(" SPo2 :"); Serial.println(spo2);
ble.print( F("AT+GATTCHAR=") );
ble.print( hrmMeasureCharId );
ble.print( F(",") );
ble.print(spo2, HEX);
ble.print("-");
ble.println(heartRate, HEX);
if ( !ble.waitForOK() ) {
Serial.println(F("Failed to get response HeartRate ....."));
}
} // end sendData
double HRM_estimator( double fir , double aveir) {
int CTdiff;
// Heart Rate Monitor by finding falling edge eir = eir firrate + fir (1.0 - firrate); //estimated IR : low pass filtered IR signal
if ( ((eir - aveir) * (eir_prev - aveir) < 0 ) && ((eir - aveir) < 0.0)) { //find zero cross at falling edge crosstime = millis();//system time in msec of falling edge //Serial.print(crosstime); Serial.print(",CRT,"); Serial.println(crosstime_prev);
//Serial.print("Cross Time :");
CTdiff = crosstime-crosstime_prev;
//Serial.println(CTdiff);
//if ( ((crosstime - crosstime_prev ) > (60 * 1000 / MAX_BPS)) &&
((crosstime - crosstime_prev ) < (60 * 1000 / MIN_BPS)) ) {
if ( ( CTdiff > 333 ) && ( CTdiff < 1333 ) ) {
bpm = 60.0 * 1000.0 / (double)(crosstime - crosstime_prev) ; //get bpm
// Serial.println("crossed");
ebpm = ebpm * fbpmrate + (1.0 - fbpmrate) * bpm;//estimated bpm by
low pass filtered
if (aveir > FINGER_ON) {
digitalWrite(LEDPORT, HIGH);
tone(BLIPSOUND-(100.0-ESpO2)*10.0);//when SpO2=80% BLIPSOUND drops
200Hz to indicate anormaly }
} else {
//Serial.println("faild to find falling edge");
}
crosstime_prev = crosstime;
} eir_prev = eir; return (ebpm); }
On Mon, Jun 15, 2020 at 3:32 PM lfssp notifications@github.com wrote:
That's a good news @caferrick https://github.com/caferrick . Waiting to see your progress.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-644334118, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNKBGG27YFY7APVZD5LRWZZMNANCNFSM4FO6BILA .
Hi @caferrick , thank you for the updated code!! I'll let you know asap how it works. Sure it's great!
@caferrick Nice job up there! (using MAX30102 + ESP8266) I Eliminated the Bluetooth relevant code, I can see drastic improvement in HR but SpO2 is pretty unstable in for me here (spanning 60-110 randomly)
(using MAX30102 + ESP8266) Example_08 for HR+SpO2 is giving my random values, not even being close to accurate, with SpO2 being -999, invalid for the most part
I noticed with the sensor that I am using my finger has to be fairly stable on the device. Also the 20 seconds or the numbers are all over the place
On Tue, Jun 16, 2020 at 6:04 AM Adeel ahmad notifications@github.com wrote:
@caferrick https://github.com/caferrick Nice job up there! (using MAX30102 + ESP8266) I Eliminated the Bluetooth relevant code, I can see drastic improvement in HR but SpO2 is pretty unstable in for me here (spanning 60-110 randomly)
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-644667399, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNJFEMMXRCDJN3D4M4DRW47UHANCNFSM4FO6BILA .
@caferrick can you share any supporting research/study based on which, you have come up with your algortihm? I'd like to tweak FSpO2
or something there to make SpO2 consistent, a top threshold of 100 is also required.
I found the original Algorithm on the Web and modified it slightly based on the MAX3012 data sheet. I will try to tweak the code a little more and if you have any luck please let me know.
On Tue, Jun 16, 2020 at 7:34 AM Adeel ahmad notifications@github.com wrote:
@caferrick https://github.com/caferrick can you share any supporting research/study based on which, you have come up with your algortihm? I'd like to tweak FSpO2 or something there to make SpO2 consistent, a top threshold of 100 is also required.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-644707421, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNNMQNKZI6SZ6G5C7JTRW5KENANCNFSM4FO6BILA .
@caferrick Can you share the literature/link? That'd help me to better understand various other aspects/factors and i may be able to effectively tweak the code.
here is just on site
https://pdfserv.maximintegrated.com/en/an/AN6409.pdf You can search for spec sheets for MAX30102
On Tue, Jun 16, 2020 at 8:00 AM Adeel ahmad notifications@github.com wrote:
@caferrick https://github.com/caferrick Can you share the literature/link? That'd help me to better understand various other aspects/factors and i may be able to effectively tweak the code.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-644718765, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNOE53SYAXQQSIITZ5DRW5NHNANCNFSM4FO6BILA .
I see, i have the specs sheet, was trying various MAX30101 algorithms to run on MAX30102 by updating registers mapping, didn't get any success yet.
@caferrick which sensor are you using? is it Maxim's 30102 or some other vendor?
30102 5 connector pins on one side the other just had the LED and two mounting holes
On Tue, Jun 16, 2020 at 11:52 AM Adeel ahmad notifications@github.com wrote:
@caferrick https://github.com/caferrick which sensor are you using? is it Maxim's 30102 or some other vendor?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-644851451, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNPMOCV45QXFDYCQ2YTRW6IK3ANCNFSM4FO6BILA .
this is the unit that i am using HiLetgo MAX30102 Low Power Heart Rate Click Sensor Breakout Board Module for Arduino Pulse Oximetry Solution SpO2 Replace MAX30100 https://www.amazon.com/gp/product/B07QC67KMQ/ref=ppx_yo_dt_b_asin_title_o09_s01?ie=UTF8&psc=1
On Tue, Jun 16, 2020 at 8:26 PM Charles Ferrick caferrick@gmail.com wrote:
30102 5 connector pins on one side the other just had the LED and two mounting holes
On Tue, Jun 16, 2020 at 11:52 AM Adeel ahmad notifications@github.com wrote:
@caferrick https://github.com/caferrick which sensor are you using? is it Maxim's 30102 or some other vendor?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-644851451, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNPMOCV45QXFDYCQ2YTRW6IK3ANCNFSM4FO6BILA .
Hello, I just want to confirm the same thing about the examples for the SparkFun library. The heart Rate Plotter and Normal example seems to work nice. But the SPO2 example seems to show very unstable values.
I tried to run different drivers with other algorithms, that I found on instructables and the web, but most algorithms use the interrupt line from the sensor. I found 2 sources that have a very good documentation for the algorithms, I will post them here. I am using the driver on a MAX30102 board that I bought from eBay, the pullups for the I2C signals where wrongly connected to 1.8V so I had to cut the track and solder them to 3.3V. The code is running on a TTGO ESP32 board that has also an OLED display, I hope that I can display the graphic for the heart rate on the display like in the Plotter and make some nice menus for other options, but first I need some reliable algorithms.
Hello,
I took the code posted by caferrick and made a sketch out of it. I made some modifications, added some defines for the BT board and also for various debugging on Serial. The signal for the Heart Beat looks ok from what I can see, but the SPO2 calculation seems to be still wrong. This is running on an ESP32 board, but it should also work on an Arduino without problems.
I wonder why the SPO2 is an issue on my Arduino Feather. My SPO2 seems good. You have wait about 30 seconds for the readings to normalize.
On Thu, Jun 18, 2020 at 10:31 AM bbogdanmircea notifications@github.com wrote:
Hello,
I took the code posted by caferrick and made a sketch out of it. I made some modifications, added some defines for the BT board and also for various debugging on Serial. The signal for the Heart Beat looks ok from what I can see, but the SPO2 calculation seems to be still wrong. This is running on an ESP32 board, but it should also work on an Arduino without problems.
caferrick_max30100.zip https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/files/4799184/caferrick_max30100.zip
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-646056897, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNMAZA55ZJAMPZM725DRXIQM7ANCNFSM4FO6BILA .
I just discovered that chinese replica breakout boards has swapped IR and LED registers! that caused me all the trouble (using MH-ET Live Max30102). Here is my implementation of pulse oximeter, a port of MAX30102_by_RF for NodeMCU that works perfectly for Original Maxim or chinese replica sensors.
I am having the same problem - the number is all over the place 150 to 200, and it cycles thru. Hope the developers upgrade or update the code to newest !
I don't think anyone develops at all :o I just started a project with MAX30102 and try to figure out how to use it (and we want to use it on a horse, don't ask ;) ) IOW: I have the same problems like the others here, HR is somewhere between 125 and 250 on an Arduino Uno (since ESP32 doesn't work)
I am also facing the same problem I.e. the heart rate values are going above 150BPM but the SpO2 value seems to be accurate in the example 8 of spark fun library. So, please anyone can help me if anyone have solved the problem
Did you try the code I listed a few months ago? I am using an Arduino Feather U32 and I am not having the issue.
On Sat, Apr 17, 2021 at 6:21 AM Swadhin Nagulpelli @.***> wrote:
I am also facing the same problem I.e. the heart rate values are going above 150BPM but the SpO2 value seems to be accurate in the example 8 of spark fun library. So, please anyone can help me if anyone have solved the problem
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-821801499, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNNLYM4VGUWKJJJO353TJFOKPANCNFSM4FO6BILA .
actually, I think I didn't try it, I had to find a quick working solution because of deadline reasons and got the sparkfun sensor hub PCB with MAX30101 and MAX32664, this works fine with its lib on ESP32.
after I got the ESP back, I will try your code above.
hello some times with tuning led brightnes and lowest in 0x10 to 0x20 module work fine but not always. i think this module is very sensetive to distance between finger and chip and config parameters
Hi i am also getting issues in accuracy of heart rate. I tried the code shared by caferrick but heart rate is not coming accurate. Even in just sitting positing it is going above 100 using MAX30102 sensor and when i measure with mobile apps which are using mobile flash and mobile camera, the heart rate is coming in normal range.
I am also using MAX30102 with Arduino Feather I am not having the issue that you are seeing. Do you try the suggestion from perohlin. These sensors can be a bit touchy
On Wed, May 12, 2021 at 2:41 AM anuragmehra24 @.***> wrote:
Hi i am also getting issues in accuracy of heart rate. I tried the code shared by caferrick but heart rate is not coming accurate. Even in just sitting positing it is going above 100 using MAX30102 sensor and when i measure with mobile apps which are using mobile flash and mobile camera, the heart rate is coming in normal range.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-839505776, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNPMNLLM2WJ2NK33IG3TNIPKRANCNFSM4FO6BILA .
I just discovered that chinese replica breakout boards has swapped IR and LED registers! that caused me all the trouble (using MH-ET Live Max30102). Here is my implementation of pulse oximeter, a port of MAX30102_by_RF for NodeMCU that works perfectly for Original Maxim or chinese replica sensors.
I bought Max30102 module at Aliexpress. I tried Spo2 sample code on ESP32, but it doesn't seem to work correctly. Also the presence sample code doesn't (Red LED is disabled to be 0 power in this code). So, I changed the followings;
LED1 < --- > LED2 sense.red < --- > sense.IR
MAX30105.cpp
.....
.....
void MAX30105::setPulseAmplitudeRed(uint8_t amplitude) {
writeRegister8(_i2caddr, MAX30105_LED2_PULSEAMP, amplitude);
}
void MAX30105::setPulseAmplitudeIR(uint8_t amplitude) {
writeRegister8(_i2caddr, MAX30105_LED1_PULSEAMP, amplitude);
}
.....
.....
.....
while (toGet > 0)
{
sense.head++; //Advance the head of the storage struct
sense.head %= STORAGE_SIZE; //Wrap condition
byte temp[sizeof(uint32_t)]; //Array of 4 bytes that we will convert into long
uint32_t tempLong;
//Burst read three bytes - RED
temp[3] = 0;
temp[2] = _i2cPort->read();
temp[1] = _i2cPort->read();
temp[0] = _i2cPort->read();
//Convert array to long
memcpy(&tempLong, temp, sizeof(tempLong));
tempLong &= 0x3FFFF; //Zero out all but 18 bits
sense.IR[sense.head] = tempLong; //Store this reading into the sense array
if (activeLEDs > 1)
{
//Burst read three more bytes - IR
temp[3] = 0;
temp[2] = _i2cPort->read();
temp[1] = _i2cPort->read();
temp[0] = _i2cPort->read();
//Convert array to long
memcpy(&tempLong, temp, sizeof(tempLong));
tempLong &= 0x3FFFF; //Zero out all but 18 bits
sense.red[sense.head] = tempLong;
}
Got good results for HR and Spo2 outputs. This is Right???
Nice!
On Tue, May 18, 2021 at 9:53 AM Takanobu Fuse @.***> wrote:
I just discovered that chinese replica breakout boards has swapped IR and LED registers! that caused me all the trouble (using MH-ET Live Max30102). Here is my implementation of pulse oximeter https://github.com/linkindrew/pulseoximeter_max30102, a port of MAX30102_by_RF https://github.com/aromring/MAX30102_by_RF for NodeMCU that works perfectly for Original Maxim or chinese replica sensors.
I bought Max30102 module at Aliexpress. I tried Spo2 sample code on ESP32, but it doesn't seem to work correctly. Also the presence sample code doesn't (Red LED is disabled to be 0 power in this code). So, I changed the followings;
LED1 < --- > LED2 sense.red < --- > sense.IR
max30105.cpp
..... ..... void MAX30105::setPulseAmplitudeRed(uint8_t amplitude) { writeRegister8(_i2caddr, MAX30105_LED2_PULSEAMP, amplitude); }
void MAX30105::setPulseAmplitudeIR(uint8_t amplitude) { writeRegister8(_i2caddr, MAX30105_LED1_PULSEAMP, amplitude); } ..... ..... ..... while (toGet > 0) { sense.head++; //Advance the head of the storage struct sense.head %= STORAGE_SIZE; //Wrap condition
byte temp[sizeof(uint32_t)]; //Array of 4 bytes that we will convert into long uint32_t tempLong; //Burst read three bytes - RED temp[3] = 0; temp[2] = _i2cPort->read(); temp[1] = _i2cPort->read(); temp[0] = _i2cPort->read(); //Convert array to long memcpy(&tempLong, temp, sizeof(tempLong)); tempLong &= 0x3FFFF; //Zero out all but 18 bits sense.IR[sense.head] = tempLong; //Store this reading into the sense array if (activeLEDs > 1) { //Burst read three more bytes - IR temp[3] = 0; temp[2] = _i2cPort->read(); temp[1] = _i2cPort->read(); temp[0] = _i2cPort->read(); //Convert array to long memcpy(&tempLong, temp, sizeof(tempLong)); tempLong &= 0x3FFFF; //Zero out all but 18 bits sense.red[sense.head] = tempLong; }
Got good results for HR and Spo2 outputs. This is Right???
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/17#issuecomment-843191546, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA65HNMNJRO3Y245BHLRUEDTOJWMDANCNFSM4FO6BILA .
what am I missing here? what do I have to adjust to get the right numbers?
@talal44 How did you get correct SpO2 values? I am using example 8 and getting very wrong numbers. please help
Get more accurate value after changing to "byte sampleAverage = 1;" in example 8. (NO. OF SAMPLES AVERAGED PER FIFO SAMPLE 000 1 (no averaging)) Its HR value almost matches with HR value in example 5. This is FIFO sampling issue? (I checked it on ESP32+MAX30102)
MH-ET LIVE, rev: 3 part: 15, esp8266
I confirm that the Chinese MAX30102 sensor assembled on a black scarf has the correct pinout and 3.3 volt pull-ups, but the red LED and infrared are confused with each other from the factory.
Without altering the libraries to a different order of receiving I2C data, the sensor refuses to give adequate values at all, it's not about sampling or configuration, it's about this feature.
Has anyone managed to run max30105 with esp8266? I'm trying but I don't have any results. In the compilation everything happens normally, but when I run it no LED lights up.
@matheuszap I am not using the 30105 but the 30102 and on a custom board with a STM32L processor but I think the setup should be quite the same. Did you set the 0x0C, 0x0D and 0x0E registers? Also check that you are not setting bit 7 to 1 in the 0x09 register.
@caferrick With my group we trying to use your code for sensor max30102 with an Arduino UNO because we really appreciate your code but we have some issues because we aren't expert in this field. Have you any advice for using this code for an Arduino UNO in order to obtain reasonable values of HR and SpO2? Thanks for helping us!
What seems to be your problem? Maybe include some raw red and ir readings (at least 100).
what am I missing here? what do I have to adjust to get the right numbers?