Skip to content

Commit

Permalink
Merge pull request #37 from 0xMihir/master
Browse files Browse the repository at this point in the history
perf: Only use Red & IR arrays from function param
  • Loading branch information
aromring authored Sep 9, 2022
2 parents f6160ab + d41d941 commit 872a3c1
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 23 deletions.
6 changes: 3 additions & 3 deletions RD117_ARDUINO.ino
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ const byte oxiInt = 10; // pin connected to MAX30102 INT

uint32_t elapsedTime,timeStart;

uint32_t aun_ir_buffer[BUFFER_SIZE]; //infrared LED sensor data
uint32_t aun_red_buffer[BUFFER_SIZE]; //red LED sensor data
float aun_ir_buffer[BUFFER_SIZE]; //infrared LED sensor data
float aun_red_buffer[BUFFER_SIZE]; //red LED sensor data
float old_n_spo2; // Previous SPO2 value
uint8_t uch_dummy,k;

Expand Down Expand Up @@ -143,7 +143,7 @@ void setup() {
dataFile.println(measuredvbat);
dataFile.println(my_status);
#ifdef TEST_MAXIM_ALGORITHM
dataFile.print(F("Time[s]\tSpO2\tHR\tSpO2_MX\tHR_MX\tClock\tRatio\tCorr\tTemp[C]));
dataFile.print(F("Time[s]\tSpO2\tHR\tSpO2_MX\tHR_MX\tClock\tRatio\tCorr\tTemp[C]"));
#else // TEST_MAXIM_ALGORITHM
dataFile.print(F("Time[s]\tSpO2\tHR\tClock\tRatio\tCorr\tTemp[C]"));
#endif // TEST_MAXIM_ALGORITHM
Expand Down
34 changes: 16 additions & 18 deletions algorithm_by_RF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "algorithm_by_RF.h"
#include <math.h>

void rf_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer, int32_t n_ir_buffer_length, uint32_t *pun_red_buffer, float *pn_spo2, int8_t *pch_spo2_valid,
void rf_heart_rate_and_oxygen_saturation(float *pun_ir_buffer, int32_t n_ir_buffer_length, float *pun_red_buffer, float *pn_spo2, int8_t *pch_spo2_valid,
int32_t *pn_heart_rate, int8_t *pch_hr_valid, float *ratio, float *correl)
/**
* \brief Calculate the heart rate and SpO2 level, Robert Fraczkiewicz version
Expand All @@ -57,9 +57,7 @@ void rf_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer, int32_t n_ir_b
float f_ir_mean,f_red_mean,f_ir_sumsq,f_red_sumsq;
float f_y_ac, f_x_ac, xy_ratio;
float beta_ir, beta_red, x;
float an_x[BUFFER_SIZE], *ptr_x; //ir
float an_y[BUFFER_SIZE], *ptr_y; //red


// calculates DC mean and subtracts DC from ir and red
f_ir_mean=0.0;
f_red_mean=0.0;
Expand All @@ -71,35 +69,36 @@ void rf_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer, int32_t n_ir_b
f_red_mean=f_red_mean/n_ir_buffer_length ;

// remove DC
for (k=0,ptr_x=an_x,ptr_y=an_y; k<n_ir_buffer_length; ++k,++ptr_x,++ptr_y) {
*ptr_x = pun_ir_buffer[k] - f_ir_mean;
*ptr_y = pun_red_buffer[k] - f_red_mean;
for (k=0; k<n_ir_buffer_length; ++k) {
pun_ir_buffer[k] -= f_ir_mean;
pun_red_buffer[k] -= f_red_mean;
}

// RF, remove linear trend (baseline leveling)
beta_ir = rf_linear_regression_beta(an_x, mean_X, sum_X2);
beta_red = rf_linear_regression_beta(an_y, mean_X, sum_X2);
for(k=0,x=-mean_X,ptr_x=an_x,ptr_y=an_y; k<n_ir_buffer_length; ++k,++x,++ptr_x,++ptr_y) {
*ptr_x -= beta_ir*x;
*ptr_y -= beta_red*x;
beta_ir = rf_linear_regression_beta(pun_ir_buffer, mean_X, sum_X2);
beta_red = rf_linear_regression_beta(pun_red_buffer, mean_X, sum_X2);
for(k=0,x=-mean_X; k<n_ir_buffer_length; ++k,++x) {
pun_ir_buffer[k] -= beta_ir*x;
pun_red_buffer[k] -= beta_red*x;
}

// For SpO2 calculate RMS of both AC signals. In addition, pulse detector needs raw sum of squares for IR
f_y_ac=rf_rms(an_y,n_ir_buffer_length,&f_red_sumsq);
f_x_ac=rf_rms(an_x,n_ir_buffer_length,&f_ir_sumsq);
f_x_ac=rf_rms(pun_ir_buffer,n_ir_buffer_length,&f_ir_sumsq);

f_y_ac=rf_rms(pun_red_buffer,n_ir_buffer_length,&f_red_sumsq);

// Calculate Pearson correlation between red and IR
*correl=rf_Pcorrelation(an_x, an_y, n_ir_buffer_length)/sqrt(f_red_sumsq*f_ir_sumsq);
*correl=rf_Pcorrelation(pun_ir_buffer, pun_red_buffer, n_ir_buffer_length)/sqrt(f_red_sumsq*f_ir_sumsq);

// Find signal periodicity
if(*correl>=min_pearson_correlation) {
// At the beginning of oximetry run the exact range of heart rate is unknown. This may lead to wrong rate if the next call does not find the _first_
// peak of the autocorrelation function. E.g., second peak would yield only 50% of the true rate.
if(LOWEST_PERIOD==n_last_peak_interval)
rf_initialize_periodicity_search(an_x, BUFFER_SIZE, &n_last_peak_interval, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq);
rf_initialize_periodicity_search(pun_ir_buffer, BUFFER_SIZE, &n_last_peak_interval, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq);
// RF, If correlation os good, then find average periodicity of the IR signal. If aperiodic, return periodicity of 0
if(n_last_peak_interval!=0)
rf_signal_periodicity(an_x, BUFFER_SIZE, &n_last_peak_interval, LOWEST_PERIOD, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq, ratio);
rf_signal_periodicity(pun_ir_buffer, BUFFER_SIZE, &n_last_peak_interval, LOWEST_PERIOD, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq, ratio);
} else n_last_peak_interval=0;

// Calculate heart rate if periodicity detector was successful. Otherwise, reset peak interval to its initial value and report error.
Expand Down Expand Up @@ -299,4 +298,3 @@ float rf_Pcorrelation(float *pn_x, float *pn_y, int32_t n_size)
r/=n_size;
return r;
}

3 changes: 1 addition & 2 deletions algorithm_by_RF.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const int32_t LOWEST_PERIOD = FS60/MAX_HR; // Minimal distance between peaks
const int32_t HIGHEST_PERIOD = FS60/MIN_HR; // Maximal distance between peaks
const float mean_X = (float)(BUFFER_SIZE-1)/2.0; // Mean value of the set of integers from 0 to BUFFER_SIZE-1. For ST=4 and FS=25 it's equal to 49.5.

void rf_heart_rate_and_oxygen_saturation(uint32_t *pun_ir_buffer, int32_t n_ir_buffer_length, uint32_t *pun_red_buffer, float *pn_spo2, int8_t *pch_spo2_valid, int32_t *pn_heart_rate,
void rf_heart_rate_and_oxygen_saturation(float *pun_ir_buffer, int32_t n_ir_buffer_length, float *pun_red_buffer, float *pn_spo2, int8_t *pch_spo2_valid, int32_t *pn_heart_rate,
int8_t *pch_hr_valid, float *ratio, float *correl);
float rf_linear_regression_beta(float *pn_x, float xmean, float sum_x2);
float rf_autocorrelation(float *pn_x, int32_t n_size, int32_t n_lag);
Expand All @@ -79,4 +79,3 @@ void rf_initialize_periodicity_search(float *pn_x, int32_t n_size, int32_t *p_la
void rf_signal_periodicity(float *pn_x, int32_t n_size, int32_t *p_last_periodicity, int32_t n_min_distance, int32_t n_max_distance, float min_aut_ratio, float aut_lag0, float *ratio);

#endif /* ALGORITHM_BY_RF_H_ */

0 comments on commit 872a3c1

Please sign in to comment.