-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Not work with higher sampling frequency #2
Comments
It happens because of this: #define FS 25 //sampling frequency then int8_t i; The index "i" is just an 8-bit signed integer. As such, it can't exceed 127. If you want to use higher sampling rates, then you have to replace all "int8_t" by integer types with higher byte count. |
@aromring thank you for the hint, but there is no int8_t i, it is int32_t in the code https://github.com/aromring/MAX30102_by_RF/blob/master/algorithm_by_RF.cpp |
It's in RD117_ARDUINO.ino |
@aromring I replace int8_t with int32_t, it crash. I tested with esp8266 and esp32, remove code with sdcard and change the setting of the sensor to no average(if(!maxim_max30102_write_reg(REG_FIFO_CONFIG,0x00f)) ) and sample rate 100hz, take 400 samples, fix n_last_peak_interval by 25 (because you use the FS for this value). Have you ever try the board with 100hz sample? |
@aromring Never mind. Finally i can make it work. But your code not good with high sample rate, with 100 hz it give like 240 bpm, 70 % and jump to 99% in 1 minute. |
No, I've never tried my circuit with higher sampling rates, since they offer almost no improvement at much higher computing cost. Nevertheless, if you still insist on using 100 Hz, then read on. sum_X2 = S{t=-49.5;49.5} (t^2) = 83325 because FS=25 times 4 seconds gives 100 data points. With 100 Hz sampling rate the number of points increases to 400 and, correspondingly, the sum_X2 spans "t" values from -199.5 to 199.5: sum_X2 = S{t=-199.5;199.5} (t^2) = 5333300 Thus, update the sum_X2 parameter in algorithm_by_RF.h by the above number and your measurements should fall back into the proper range. |
@aromring Yes, after apply your sum_X2 it work. Your code much more reliable than MAXIM code, but it only with SPO2 and not with heart rate. From my test both with 25hz and 100Hz, heart rate from 50 to 61 bpm but the real heart rate is 80. |
Well, I am afraid this perceived discrepancy is not the result of my code, but either an error in your setup, or a misunderstanding. I have checked heart rate results by countless tests not just one, but two independent methods. My MAX30102 provides essentially identical heart rates (HR) when compared to: 1) another medical device, 2) simple count with a stopwatch. |
@aromring I upload the code include the raw IR and RED data here https://www.dropbox.com/s/qakvdpi5cdz6klb/Maxim_SPO2.zip?dl=0. The raw data file RawData2018_4_21_87bpm_99SPO2.txt With the data first column is RED and second is IR. |
Thank you. Hopefully (and finally), I will have some time tonight to take a look at it. |
It is 100Hz |
All right, I know what happened. All the sampling parameters are OK, the problem is your unusually high heart rate (HR). 87 bpm while just sitting on a chair is very high, indeed. Mine, for example, is ~60 bpm while sitting and ~50 bpm while sleeping. First, let me refresh you on how the HR detection algorithm works: it is supposed to detect a local maximum of the first peak in the autocorrelation graph. The X value at this maximum (lag) corresponds to the raw data shifted by the averaged distance between neighbor peaks in the raw R/IR data graphs. This distance (D) is expressed as the number of samples between peaks, therefore heart rate (in bpm) is calculated as Hence, a perfect algorithm would detect the correct maximum of the first peak every time. However, this means a lot of calculations which eat up precious CPU time. My simple device is not equipped with a real time clock, thus I rely on MAX30102 sampling as an approximation of real time clock. For that, all the calculations done by rf_heart_rate_and_oxygen_saturation() must be very fast in order not to delay the measure of real time. The algorithm is successful in this respect, but at the cost of some sacrifices. The D detection routine, rf_signal_periodicity(), relies on an initial guess, D0, to find the appropriate maximum. The routine looks at autocorrelation values at D0, D0+1, and D0-1 to determine direction in which the peak resides. If, for example, D0=50 in your case, then the routine marches to the right at D1=51, D2=52, etc., until reaching peak at optimal Dn=68. The optimal value is then remembered as a new D0 for the next cycle. Since HR at night does not change much, the cost of obtaining its value from the next batch of samples is quite low - no more than a few evaluations of autocorrelation function. Which brings me back to the initial guess, D0. Ideally, it should be in the range between first two local minima, e.g., 32 and 96 in your case. I tailored it to myself setting it to 25 at the beginning of rf_heart_rate_and_oxygen_saturation() function: static int32_t n_last_peak_interval=FS; // Initialize it to 25, which corresponds to heart rate of 60 bps, RF because HR=60 bpm was quite a safe bet. But in your case 60 bpm is just a bit too low. D0=100 is actually on the wrong side of the local minimum and rf_signal_periodicity() actually finds the second maximum at about 130 samples, which corresponds to twice the distance between heart beats and translates to too low HR=46. I guess, all you have to do to adjust the code to your physiology is to update the D0 to, say, 67? static int32_t n_last_peak_interval=67; or static int32_t n_last_peak_interval=2*FS/3; |
I haven't heard from you in a long time. Hence, I consider this issue to be closed. |
@aromring Thanks you again. |
I test your code with 25 sampling frequency
#define FS 25
But when i change sampling frequency to 50 or 100 it not work always show invalid:
#define FS 100
The text was updated successfully, but these errors were encountered: