app_overturn - 副本.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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 uint8_t led_light_count = -1;
  90. static uint8_t station_count =0;
  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. // station_count =1;
  105. // else
  106. // station_count =0;
  107. //
  108. // if(abs(acc_norm - 4194304) < 262144 && data.acc[2] < -1024)
  109. // station_count =0;
  110. if(data.acc[2] > 1200)
  111. station_count =1;
  112. else
  113. station_count =0;
  114. DEBUG_LOG("acc_norm:%d,station_count:%d,data.acc2:%d\n",abs(acc_norm - 4194304),station_count,data.acc[2]);
  115. if(station_count > 0){
  116. if(0 == LED_LIVE_TIME){
  117. LED_LIVE_TIME = (10000/StandByPower_Interval);
  118. if(GetBatteryPersent()>20){
  119. LED_Start(LED_OVERTURN,COLOR_GREEN);
  120. }else{
  121. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  122. }
  123. Process_SetHoldOn(app_BatDispaly_Process_N,1);
  124. }
  125. else if (2 == LED_LIVE_TIME){
  126. LED_Stop(LED_OVERTURN);
  127. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  128. }
  129. if (LED_LIVE_TIME > 1)LED_LIVE_TIME--;
  130. }
  131. else if (LED_LIVE_TIME > 0 && 0 == station_count){LED_LIVE_TIME=0;
  132. LED_Stop(LED_OVERTURN);
  133. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  134. }
  135. }
  136. }
  137. //穿鞋的情况下
  138. void app_BatDispaly_Process(void)
  139. {
  140. ser_imu_data_t data={0};
  141. static uint16_t time_count = 0;
  142. static uint16_t station_count= 0;
  143. static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
  144. static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
  145. static uint16_t overturn_180_count = 0;
  146. static uint8_t lED_LIFE_TIME = 0;
  147. if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
  148. {
  149. return;//走路状态
  150. }
  151. // DEBUG_LOG("app_BatDispaly_Process;\n");
  152. //获取最新一组前脚加速度, 有fifo
  153. int16_t data_size = 0;
  154. data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
  155. if(data_size > 0){
  156. // DEBUG_LOG("data_size : %d, hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
  157. hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
  158. //耗时较少的计算滑动窗口的最大值、最小值
  159. sort_silde_window(&max_slide_window, &min_slide_window, data.acc[0], time_count);
  160. if(time_count > SLIDE_WINDOW_LEN){
  161. 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
  162. && max_slide_window.slide_window[0].max_temp - min_slide_window.slide_window[0].max_temp < 256 && data.acc[0] < -308){
  163. station_count =6;
  164. }
  165. else if(station_count > 0)station_count--;
  166. }
  167. time_count++;
  168. //在穿鞋状态下,被翻转了
  169. int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
  170. if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
  171. overturn_180_count ++;
  172. else
  173. overturn_180_count = 0;
  174. DEBUG_LOG("acc_norm:%d,station_count:%d,overturn_180_count:%d\n",abs(acc_norm - 4194304),station_count,overturn_180_count);
  175. if(station_count > 0 || overturn_180_count >= 5){
  176. if(0 == lED_LIFE_TIME){
  177. lED_LIFE_TIME = (10000/LowPower_Interval);
  178. if(GetBatteryPersent()>20){
  179. LED_Start(LED_OVERTURN,COLOR_GREEN);
  180. }else{
  181. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  182. }
  183. Process_SetHoldOn(app_BatDispaly_Process,1);
  184. }
  185. else if (2 == lED_LIFE_TIME){
  186. LED_Stop(LED_OVERTURN);
  187. Process_SetHoldOn(app_BatDispaly_Process,0);
  188. }
  189. if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
  190. }
  191. else if (lED_LIFE_TIME > 0 && (0 == station_count && 0 == overturn_180_count)){lED_LIFE_TIME=0;
  192. LED_Stop(LED_OVERTURN);
  193. Process_SetHoldOn(app_BatDispaly_Process,0);
  194. }
  195. }
  196. }
  197. void app_overturn_Init(void)
  198. {
  199. Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
  200. Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
  201. }