app_overturn.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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 "app_overturn.h"
  8. #include "hal_wearshoes.h"
  9. #include "bll_imu.h"
  10. #include "ble_comm.h"
  11. #include "hal_qma.h"
  12. #define SLIDE_WINDOW_LEN 5
  13. typedef struct
  14. {
  15. int16_t max_temp;
  16. uint16_t time_count;
  17. }ACC_TIME_TYPE;
  18. typedef struct
  19. {
  20. ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
  21. int window_length;
  22. }SLIDE_WINDOW;
  23. int cal_unsigned_D_value(uint16_t left_value, uint16_t right_value)
  24. {
  25. if(left_value <= right_value)
  26. {
  27. return right_value - left_value;
  28. }
  29. else
  30. {
  31. return 65535-left_value + 1 + right_value;
  32. }
  33. }
  34. static uint8_t flag_move =0;
  35. void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t time_count)
  36. {
  37. ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
  38. //检测当前的值是是否是最大值
  39. if(max_slide_window->window_length == 0)
  40. {
  41. max_slide_window->slide_window[0] = acc_time_type_temp;
  42. max_slide_window->window_length = 1;
  43. }
  44. else
  45. {
  46. //先判断长度是否溢出来了
  47. while(cal_unsigned_D_value(max_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
  48. {
  49. memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
  50. max_slide_window->window_length --;
  51. }
  52. //再检测新的元素需要前面的元素小
  53. while(max_slide_window->window_length > 0)
  54. {
  55. if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
  56. {
  57. max_slide_window->window_length --;
  58. }
  59. else
  60. {
  61. break;
  62. }
  63. }
  64. max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
  65. max_slide_window->window_length ++;
  66. }
  67. //检测当前的值是是否是最大值
  68. if(min_slide_window->window_length == 0)
  69. {
  70. min_slide_window->slide_window[0] = acc_time_type_temp;
  71. min_slide_window->window_length = 1;
  72. }
  73. else
  74. {
  75. //先判断长度是否溢出来了
  76. while(cal_unsigned_D_value(min_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
  77. {
  78. memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
  79. min_slide_window->window_length --;
  80. }
  81. //再检测新的元素需要前面的元素小
  82. while(min_slide_window->window_length > 0)
  83. {
  84. if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
  85. {
  86. min_slide_window->window_length --;
  87. }
  88. else
  89. {
  90. break;
  91. }
  92. }
  93. min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
  94. min_slide_window->window_length ++;
  95. }
  96. }
  97. /************************ 踮脚显示电量 ***********************************/
  98. //没穿鞋的情况下
  99. void app_BatDispaly_Process_N(void)
  100. {
  101. bll_imu_data_t data= {0};
  102. static uint8_t lED_LIFE_SIGNAL = 0;
  103. static uint8_t lED_LIFE_TIME = 0;
  104. // DEBUG_LOG("app_BatDispaly_Process_N;\n");
  105. if(hal_wearshoes_is_wearshoes())return;
  106. //获取最新一组前脚加速度
  107. int16_t data_size = 0;
  108. data_size = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
  109. if(data_size > 0){
  110. bll_imu_get_data(BLL_IMU_DIR_FRONT, data_size -1 , &data);
  111. int32_t acc_norm = ((int32_t)data.acc[0] * (int32_t)data.acc[0] +(int32_t)data.acc[1] * (int32_t)data.acc[1] + (int32_t)data.acc[2] * (int32_t)data.acc[2]);
  112. if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
  113. {
  114. lED_LIFE_SIGNAL = 3;
  115. }
  116. else if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
  117. if(abs(acc_norm - 4194304) < 362144 && data.acc[2] < -1024)
  118. {
  119. lED_LIFE_SIGNAL = 0;
  120. }
  121. // DEBUG_LOG("acc_norm:%d,lED_LIFE_SIGNAL:%d,data.acc2:%d,lED_LIFE_TIME:%d\n",abs(acc_norm - 4194304),lED_LIFE_SIGNAL,data.acc[2],lED_LIFE_TIME);
  122. if(lED_LIFE_SIGNAL > 0)
  123. {
  124. // DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
  125. if(lED_LIFE_TIME == 0){
  126. lED_LIFE_TIME = (10000/StandByPower_Interval);
  127. if(GetBatteryPersent()>20){
  128. LED_Start(LED_OVERTURN,COLOR_GREEN);
  129. }else{
  130. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  131. }
  132. Process_SetHoldOn(app_BatDispaly_Process_N,1);
  133. }
  134. else if (2 == lED_LIFE_TIME){
  135. LED_Stop(LED_OVERTURN);
  136. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  137. }
  138. if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
  139. }
  140. else
  141. {
  142. // DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
  143. if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
  144. LED_Stop(LED_OVERTURN);
  145. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  146. }
  147. if(1 == flag_move){flag_move =0;
  148. LED_Stop(LED_OVERTURN);
  149. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  150. }
  151. }
  152. }
  153. }
  154. //穿鞋的情况下
  155. void app_BatDispaly_Process(void)
  156. {
  157. bll_imu_data_t data={0};
  158. qma_data_t qma_data={0};
  159. static uint16_t time_count = 0;
  160. static uint16_t station_count =0;
  161. static uint16_t overturn_180_count = 0;
  162. static uint8_t lED_LIFE_SIGNAL = 0;
  163. static uint8_t lED_LIFE_TIME = 0;
  164. static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
  165. static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
  166. if(!hal_wearshoes_is_wearshoes())return;
  167. // DEBUG_LOG("app_BatDispaly_Process;\n");
  168. //获取最新一组前脚加速度, 有fifo
  169. int16_t data_size = 0;
  170. // data_size = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
  171. int ret = drv_qma_get_acc_data(&qma_data);
  172. if(ret != -1 && !(qma_data.acc[0] == 0 && qma_data.acc[1] == 0 && qma_data.acc[2] == 0))
  173. {
  174. data_size = 1;
  175. }
  176. if(data_size > 0){
  177. // DEBUG_LOG("data_size : %d, hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
  178. //bll_imu_get_data(BLL_IMU_DIR_FRONT, data_size-1 , &data);
  179. //耗时较少的计算滑动窗口的最大值、最小值
  180. //sort_silde_window(&max_slide_window, &min_slide_window, data.acc[0], time_count);
  181. sort_silde_window(&max_slide_window, &min_slide_window, qma_data.acc[1], time_count);
  182. if(time_count > SLIDE_WINDOW_LEN)
  183. {
  184. // 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
  185. // && max_slide_window.slide_window[0].max_temp - min_slide_window.slide_window[0].max_temp < 256 && data.acc[0] < -1400)
  186. if(qma_data.acc[1] - min_slide_window.slide_window[0].max_temp < 512 && max_slide_window.slide_window[0].max_temp - qma_data.acc[1] < 512
  187. && max_slide_window.slide_window[0].max_temp - min_slide_window.slide_window[0].max_temp < 512 && qma_data.acc[1] < -1500)
  188. {
  189. station_count++;
  190. }
  191. else station_count =0;
  192. }
  193. time_count++;
  194. //在穿鞋状态下,被翻转了
  195. int32_t acc_norm = ((int32_t)data.acc[0] * (int32_t)data.acc[0] +(int32_t)data.acc[1] * (int32_t)data.acc[1] + (int32_t)data.acc[2] * (int32_t)data.acc[2]);
  196. //if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
  197. if(abs(acc_norm - 16777216) < 1448576 && data.acc[2] > 3072)
  198. {
  199. //DEBUG_LOG(" wear shoes if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536);\n");
  200. overturn_180_count ++;
  201. }
  202. else
  203. {
  204. overturn_180_count = 0;
  205. }
  206. if(overturn_180_count >= 5 || station_count > 4)
  207. {
  208. // DEBUG_LOG(" overturn_180_count > 5;\n");
  209. lED_LIFE_SIGNAL = 6;
  210. }
  211. if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
  212. if(lED_LIFE_SIGNAL > 0)
  213. {
  214. // DEBUG_LOG("wearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
  215. if(lED_LIFE_TIME == 0){
  216. lED_LIFE_TIME = (10000/LowPower_Interval);
  217. if(GetBatteryPersent()>20){
  218. LED_Start(LED_OVERTURN,COLOR_GREEN);
  219. }else{
  220. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  221. }
  222. Process_SetHoldOn(app_BatDispaly_Process,1);
  223. }
  224. else if (2 == lED_LIFE_TIME){
  225. LED_Stop(LED_OVERTURN);
  226. Process_SetHoldOn(app_BatDispaly_Process,0);
  227. }
  228. if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
  229. }
  230. else
  231. {
  232. // DEBUG_LOG("wearshoes LED_Stop(LED_OVERTURN);\n");
  233. if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
  234. LED_Stop(LED_OVERTURN);
  235. Process_SetHoldOn(app_BatDispaly_Process,0);
  236. }
  237. if(0 == flag_move){flag_move =1;
  238. LED_Stop(LED_OVERTURN);
  239. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  240. }
  241. }
  242. }
  243. }
  244. void app_overturn_Init(void)
  245. {
  246. Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
  247. Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
  248. }