63 #if defined(ARDUINO_AVR_UNO)
67 int32_t *pn_heart_rate, int8_t *pch_hr_valid)
70 int32_t *pn_heart_rate, int8_t *pch_hr_valid)
90 uint32_t un_ir_mean,un_only_once ;
91 int32_t k, n_i_ratio_count;
92 int32_t i, s, m, n_exact_ir_valley_locs_count, n_middle_idx;
93 int32_t n_th1, n_npks, n_c_min;
94 int32_t an_ir_valley_locs[15] ;
95 int32_t n_peak_interval_sum;
97 int32_t n_y_ac, n_x_ac;
99 int32_t n_y_dc_max, n_x_dc_max;
100 int32_t n_y_dc_max_idx, n_x_dc_max_idx;
101 int32_t an_ratio[5], n_ratio_average;
102 int32_t n_nume, n_denom ;
111 an_x[k] = -1*(pun_ir_buffer[k] - un_ir_mean) ;
115 an_x[k]=( an_x[k]+an_x[k+1]+ an_x[k+2]+ an_x[k+3])/(
int)4;
123 if( n_th1<30) n_th1=30;
124 if( n_th1>60) n_th1=60;
126 for ( k=0 ; k<15;k++) an_ir_valley_locs[k]=0;
128 maxim_find_peaks( an_ir_valley_locs, &n_npks, an_x, BUFFER_SIZE, n_th1, 4, 15 );
129 n_peak_interval_sum =0;
131 for (k=1; k<n_npks; k++) n_peak_interval_sum += (an_ir_valley_locs[k] -an_ir_valley_locs[k -1] ) ;
132 n_peak_interval_sum =n_peak_interval_sum/(n_npks-1);
133 *pn_heart_rate =(int32_t)( (
FS*60)/ n_peak_interval_sum );
137 *pn_heart_rate = -999;
143 an_x[k] = pun_ir_buffer[k] ;
144 an_y[k] = pun_red_buffer[k] ;
148 n_exact_ir_valley_locs_count =n_npks;
155 for(k=0; k< 5; k++) an_ratio[k]=0;
156 for (k=0; k< n_exact_ir_valley_locs_count; k++){
157 if (an_ir_valley_locs[k] > BUFFER_SIZE ){
165 for (k=0; k< n_exact_ir_valley_locs_count-1; k++){
166 n_y_dc_max= -16777216 ;
167 n_x_dc_max= -16777216;
168 if (an_ir_valley_locs[k+1]-an_ir_valley_locs[k] >3){
169 for (i=an_ir_valley_locs[k]; i< an_ir_valley_locs[k+1]; i++){
170 if (an_x[i]> n_x_dc_max) {n_x_dc_max =an_x[i]; n_x_dc_max_idx=i;}
171 if (an_y[i]> n_y_dc_max) {n_y_dc_max =an_y[i]; n_y_dc_max_idx=i;}
173 n_y_ac= (an_y[an_ir_valley_locs[k+1]] - an_y[an_ir_valley_locs[k] ] )*(n_y_dc_max_idx -an_ir_valley_locs[k]);
174 n_y_ac= an_y[an_ir_valley_locs[k]] + n_y_ac/ (an_ir_valley_locs[k+1] - an_ir_valley_locs[k]) ;
175 n_y_ac= an_y[n_y_dc_max_idx] - n_y_ac;
176 n_x_ac= (an_x[an_ir_valley_locs[k+1]] - an_x[an_ir_valley_locs[k] ] )*(n_x_dc_max_idx -an_ir_valley_locs[k]);
177 n_x_ac= an_x[an_ir_valley_locs[k]] + n_x_ac/ (an_ir_valley_locs[k+1] - an_ir_valley_locs[k]);
178 n_x_ac= an_x[n_y_dc_max_idx] - n_x_ac;
179 n_nume=( n_y_ac *n_x_dc_max)>>7 ;
180 n_denom= ( n_x_ac *n_y_dc_max)>>7;
181 if (n_denom>0 && n_i_ratio_count <5 && n_nume != 0)
183 an_ratio[n_i_ratio_count]= (n_nume*100)/n_denom ;
190 n_middle_idx= n_i_ratio_count/2;
193 n_ratio_average =( an_ratio[n_middle_idx-1] +an_ratio[n_middle_idx])/2;
195 n_ratio_average = an_ratio[n_middle_idx ];
197 if( n_ratio_average>2 && n_ratio_average <184){
199 *pn_spo2 = n_spo2_calc ;
209 void maxim_find_peaks( int32_t *pn_locs, int32_t *n_npks, int32_t *pn_x, int32_t n_size, int32_t n_min_height, int32_t n_min_distance, int32_t n_max_num )
220 *n_npks =
min( *n_npks, n_max_num );
232 int32_t i = 1, n_width;
235 while (i < n_size-1){
236 if (pn_x[i] > n_min_height && pn_x[i] > pn_x[i-1]){
238 while (i+n_width < n_size && pn_x[i] == pn_x[i+n_width])
240 if (pn_x[i] > pn_x[i+n_width] && (*n_npks) < 15 ){
241 pn_locs[(*n_npks)++] = i;
263 int32_t i, j, n_old_npks, n_dist;
268 for ( i = -1; i < *pn_npks; i++ ){
269 n_old_npks = *pn_npks;
271 for ( j = i+1; j < n_old_npks; j++ ){
272 n_dist = pn_locs[j] - ( i == -1 ? -1 : pn_locs[i] );
273 if ( n_dist > n_min_distance || n_dist < -n_min_distance )
274 pn_locs[(*pn_npks)++] = pn_locs[j];
291 int32_t i, j, n_temp;
292 for (i = 1; i < n_size; i++) {
294 for (j = i; j > 0 && n_temp < pn_x[j-1]; j--)
309 int32_t i, j, n_temp;
310 for (i = 1; i < n_size; i++) {
312 for (j = i; j > 0 && pn_x[n_temp] > pn_x[pn_indx[j-1]]; j--)
313 pn_indx[j] = pn_indx[j-1];