app_overturn.c 7.6 KB

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