app_overturn_备份.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "usr_config.h"
  2. #include "hal_battery.h"
  3. #include "nrf_drv_saadc.h"
  4. #include "bsp_time.h"
  5. #include "system.h"
  6. #include "hal_led.h"
  7. #include "hal_ser_imu_mode_manage.h"
  8. #include "app_overturn.h"
  9. #include "hal_wearshoes.h"
  10. #include "ble_comm.h"
  11. #define SLIDE_WINDOW_LEN 5
  12. typedef struct
  13. {
  14. int16_t max_temp;
  15. uint16_t time_count;
  16. }ACC_TIME_TYPE;
  17. typedef struct
  18. {
  19. ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
  20. int window_length;
  21. }SLIDE_WINDOW;
  22. void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t time_count)
  23. {
  24. ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
  25. //检测当前的值是是否是最大值
  26. if(max_slide_window->window_length == 0)
  27. {
  28. max_slide_window->slide_window[0] = acc_time_type_temp;
  29. max_slide_window->window_length = 1;
  30. }
  31. else
  32. {
  33. //先判断长度是否溢出来了
  34. while(time_count - max_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
  35. {
  36. memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
  37. max_slide_window->window_length --;
  38. }
  39. //再检测新的元素需要前面的元素小
  40. while(max_slide_window->window_length > 0)
  41. {
  42. if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
  43. {
  44. max_slide_window->window_length --;
  45. }
  46. else
  47. {
  48. break;
  49. }
  50. }
  51. max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
  52. max_slide_window->window_length ++;
  53. }
  54. //检测当前的值是是否是最大值
  55. if(min_slide_window->window_length == 0)
  56. {
  57. min_slide_window->slide_window[0] = acc_time_type_temp;
  58. min_slide_window->window_length = 1;
  59. }
  60. else
  61. {
  62. //先判断长度是否溢出来了
  63. while(time_count - min_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
  64. {
  65. memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
  66. min_slide_window->window_length --;
  67. }
  68. //再检测新的元素需要前面的元素小
  69. while(min_slide_window->window_length > 0)
  70. {
  71. if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
  72. {
  73. min_slide_window->window_length --;
  74. }
  75. else
  76. {
  77. break;
  78. }
  79. }
  80. min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
  81. min_slide_window->window_length ++;
  82. }
  83. }
  84. /************************ 踮脚显示电量 ***********************************/
  85. //没穿鞋的情况下
  86. void app_BatDispaly_Process_N(void)
  87. {
  88. ser_imu_data_t data;
  89. static uint16_t led_light_count = -1;
  90. static uint16_t station_count;
  91. static int LED_LIVE_TIME = 0;
  92. // DEBUG_LOG("app_BatDispaly_Process_N;\n");
  93. if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_STANDBY))
  94. {
  95. return;//停止状态
  96. }
  97. //获取最新一组前脚加速度
  98. int16_t data_size = 0;
  99. data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
  100. if(data_size > 0){
  101. hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size -1 , &data);
  102. int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
  103. if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536)
  104. {
  105. LED_LIVE_TIME = 3;
  106. }
  107. else
  108. {
  109. LED_LIVE_TIME --;
  110. }
  111. if(LED_LIVE_TIME > 0)
  112. {
  113. // DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
  114. if(GetBatteryPersent()>20){
  115. LED_Start(LED_OVERTURN,COLOR_GREEN);
  116. }
  117. else{
  118. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  119. }
  120. Process_SetHoldOn(app_BatDispaly_Process_N,1);
  121. }
  122. else
  123. {
  124. // DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
  125. LED_Stop(LED_OVERTURN);
  126. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  127. }
  128. if(abs(acc_norm - 4194304) < 262144 && data.acc[2] < -1024)
  129. {
  130. LED_LIVE_TIME = 0;
  131. LED_Stop(LED_OVERTURN);
  132. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  133. }
  134. }
  135. }
  136. //穿鞋的情况下
  137. void app_BatDispaly_Process(void)
  138. {
  139. ser_imu_data_t data={0};
  140. static uint16_t time_count = 0;
  141. static uint16_t station_count= 0;
  142. static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
  143. static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
  144. static uint16_t overturn_180_count = 0;
  145. static uint8_t lED_LIFE_TIME = 0;
  146. if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
  147. {
  148. return;//走路状态
  149. }
  150. // DEBUG_LOG("app_BatDispaly_Process;\n");
  151. //获取最新一组前脚加速度, 有fifo
  152. int16_t data_size = 0;
  153. data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
  154. if(data_size > 0){
  155. // DEBUG_LOG("data_size : %d, hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
  156. hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
  157. //耗时较少的计算滑动窗口的最大值、最小值
  158. sort_silde_window(&max_slide_window, &min_slide_window, data.acc[0], time_count);
  159. if(time_count > SLIDE_WINDOW_LEN){
  160. if(data.acc[0] - min_slide_window.slide_window[0].max_temp < 256 && max_slide_window.slide_window[0].max_temp - data.acc[0] < 256
  161. && max_slide_window.slide_window[0].max_temp - min_slide_window.slide_window[0].max_temp < 256 && data.acc[0] < -308){
  162. station_count ++;
  163. }
  164. else station_count = 0;
  165. }
  166. time_count++;
  167. //在穿鞋状态下,被翻转了
  168. int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
  169. if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536)
  170. overturn_180_count ++;
  171. else
  172. overturn_180_count = 0;
  173. if(station_count > 0 || overturn_180_count >= 5){
  174. if(0 == lED_LIFE_TIME){
  175. lED_LIFE_TIME = (10000/LowPower_Interval);
  176. if(GetBatteryPersent()>20){
  177. LED_Start(LED_OVERTURN,COLOR_GREEN);
  178. }else{
  179. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  180. }
  181. Process_SetHoldOn(app_BatDispaly_Process,1);
  182. }
  183. else if (2 == lED_LIFE_TIME){
  184. LED_Stop(LED_OVERTURN);
  185. Process_SetHoldOn(app_BatDispaly_Process,0);
  186. }
  187. if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
  188. }
  189. else if (lED_LIFE_TIME > 0){lED_LIFE_TIME=0;
  190. LED_Stop(LED_OVERTURN);
  191. Process_SetHoldOn(app_BatDispaly_Process,0);
  192. }
  193. }
  194. }
  195. void app_overturn_Init(void)
  196. {
  197. Process_Start(100,"BatDispaly",app_BatDispaly_Process);
  198. Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
  199. }