A03_MAX30102_example.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <unistd.h>
  18. #include "max30102.h"
  19. #include "algorithm.h"
  20. #include "cmsis_os2.h"
  21. #include "ohos_init.h"
  22. #define TASK_STACK_SIZE 1024 * 8
  23. #define TASK_PRIO 25
  24. uint32_t aun_ir_buffer[500]; //IR LED sensor data
  25. int32_t n_ir_buffer_length; //data length
  26. uint32_t aun_red_buffer[500]; //Red LED sensor data
  27. int32_t n_sp02; //SPO2 value
  28. int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid
  29. int32_t n_heart_rate; //heart rate value
  30. int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid
  31. uint8_t uch_dummy;
  32. #define MAX_BRIGHTNESS 255
  33. static void ExampleTask(void)
  34. {
  35. //variables to calculate the on-board LED brightness that reflects the heartbeats
  36. uint32_t un_min, un_max, un_prev_data;
  37. int i;
  38. int32_t n_brightness;
  39. float f_temp;
  40. uint8_t temp_num=0;
  41. uint8_t temp[6]={0,0,0,0,0,0};
  42. uint8_t str[100];
  43. uint8_t dis_hr=0,dis_spo2=0;
  44. BoardInit();
  45. maxim_max30102_init();
  46. printf("\r\n MAX30102 init \r\n");
  47. un_min=0x3FFFF;
  48. un_max=0;
  49. n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
  50. //read the first 500 samples, and determine the signal range
  51. for(i=0;i<n_ir_buffer_length;i++)
  52. {
  53. while(GetInit()==1); //wait until the interrupt pin asserts
  54. max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
  55. aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
  56. aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
  57. if(un_min>aun_red_buffer[i])
  58. un_min=aun_red_buffer[i]; //update signal min
  59. if(un_max<aun_red_buffer[i])
  60. un_max=aun_red_buffer[i]; //update signal max
  61. // printf("red=");
  62. // printf("%i", aun_red_buffer[i]);
  63. // printf(", ir=");
  64. // printf("%i\n\r", aun_ir_buffer[i]);
  65. }
  66. un_prev_data=aun_red_buffer[i];
  67. //calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
  68. maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
  69. while(1)
  70. {
  71. i=0;
  72. un_min=0x3FFFF;
  73. un_max=0;
  74. //dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
  75. for(i=100;i<500;i++)
  76. {
  77. aun_red_buffer[i-100]=aun_red_buffer[i];
  78. aun_ir_buffer[i-100]=aun_ir_buffer[i];
  79. //update the signal min and max
  80. if(un_min>aun_red_buffer[i])
  81. un_min=aun_red_buffer[i];
  82. if(un_max<aun_red_buffer[i])
  83. un_max=aun_red_buffer[i];
  84. }
  85. //take 100 sets of samples before calculating the heart rate.
  86. for(i=400;i<500;i++)
  87. {
  88. un_prev_data=aun_red_buffer[i-1];
  89. while(GetInit()==1);
  90. max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
  91. aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
  92. aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
  93. if(aun_red_buffer[i]>un_prev_data)
  94. {
  95. f_temp=aun_red_buffer[i]-un_prev_data;
  96. f_temp/=(un_max-un_min);
  97. f_temp*=MAX_BRIGHTNESS;
  98. n_brightness-=(int)f_temp;
  99. if(n_brightness<0)
  100. n_brightness=0;
  101. }
  102. else
  103. {
  104. f_temp=un_prev_data-aun_red_buffer[i];
  105. f_temp/=(un_max-un_min);
  106. f_temp*=MAX_BRIGHTNESS;
  107. n_brightness+=(int)f_temp;
  108. if(n_brightness>MAX_BRIGHTNESS)
  109. n_brightness=MAX_BRIGHTNESS;
  110. }
  111. //send samples and calculation result to terminal program through UART
  112. if(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101
  113. {
  114. dis_hr = n_heart_rate;
  115. dis_spo2 = n_sp02;
  116. }
  117. else
  118. {
  119. dis_hr = 0;
  120. dis_spo2 = 0;
  121. }
  122. }
  123. // for(i=0;i<500;i++){
  124. // printf("0x%02x,",aun_ir_buffer[i]);
  125. // }
  126. // printf("\r\n");
  127. // printf("--------0-0-----\r\n");
  128. // for(i=0;i<500;i++){
  129. // printf("0x%02x,",aun_red_buffer[i]);
  130. // }
  131. // printf("\r\n");
  132. // printf("--------0-0-----\r\n");
  133. maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
  134. printf("HR=%i, ", n_heart_rate);
  135. printf("HRvalid=%i, ", ch_hr_valid);
  136. // printf("SpO2=%i, ", n_sp02);
  137. // printf("SPO2Valid=%i\r\n", ch_spo2_valid);
  138. sleep(1);
  139. // //显示刷新
  140. // LED0=0;
  141. // if(dis_hr == 0 && dis_spo2 == 0) //**dis_hr == 0 && dis_spo2 == 0
  142. // {
  143. // sprintf((char *)str,"HR:--- SpO2:--- ");//**HR:--- SpO2:---
  144. // }
  145. // else{
  146. // sprintf((char *)str,"HR:%3d SpO2:%3d ",dis_hr,dis_spo2);//**HR:%3d SpO2:%3d
  147. // }
  148. // OLED_ShowString(0,0,str,16);
  149. // OLED_Fill(0,23,127,63,0);
  150. // //红光在上,红外在下
  151. // dis_DrawCurve(aun_red_buffer,20);
  152. // dis_DrawCurve(aun_ir_buffer,0);
  153. // OLED_Refresh_Gram();//更新显示到OLED
  154. }
  155. }
  156. static void ExampleEntry(void)
  157. {
  158. osThreadAttr_t attr;
  159. attr.name = "ExampleTask";
  160. attr.attr_bits = 0U;
  161. attr.cb_mem = NULL;
  162. attr.cb_size = 0U;
  163. attr.stack_mem = NULL;
  164. attr.stack_size = TASK_STACK_SIZE;
  165. attr.priority = TASK_PRIO;
  166. if (osThreadNew((osThreadFunc_t)ExampleTask, NULL, &attr) == NULL) {
  167. printf("Failed to create ExampleTask!\n");
  168. }
  169. }
  170. APP_FEATURE_INIT(ExampleEntry);