app_overturn - 副本 (3).c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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. //全功率
  13. static const fml_imu_param_t game_front_param={
  14. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  15. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  16. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  17. .timestamp_switch = FML_IMU_TIMESTAMP_ON, //前脚 - 时间戳开启
  18. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  19. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  20. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  21. .acc_odr = FML_IMU_ACC_ODR_104HZ, //前脚 - 加速度采样频率 - 104HZ
  22. .gry_odr = FML_IMU_GRY_ODR_104HZ, //前脚 - 陀螺仪采样频率 - 104HZ
  23. .mag_odr = FML_IMU_MAG_ODR_200HZ, //前脚 - 地磁计采样频率 - 200HZ
  24. .fifo_odr = FML_IMU_FIFO_ODR_104HZ,
  25. };
  26. static const fml_imu_param_t game_back_param={
  27. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  28. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  29. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  30. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  31. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  32. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  33. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  34. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  35. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  36. .mag_odr = FML_IMU_MAG_ODR_200HZ, //后脚 - 地磁计采样频率 - 200HZ
  37. .fifo_odr = FML_IMU_FIFO_ODR_OFF,
  38. };
  39. //低功耗
  40. static const fml_imu_param_t shoes_front_param={
  41. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  42. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  43. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  44. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //前脚 - 时间戳关闭
  45. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  46. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  47. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  48. .acc_odr = FML_IMU_ACC_ODR_104HZ, //前脚 - 加速度采样频率 - 104HZ
  49. .gry_odr = FML_IMU_GRY_ODR_OFF, //前脚 - 陀螺仪采样频率 关闭
  50. .mag_odr = FML_IMU_MAG_ODR_100HZ, //前脚 - 地磁计采样频率 - 100HZ
  51. .fifo_odr = FML_IMU_FIFO_ODR_104HZ,
  52. };
  53. static const fml_imu_param_t shoes_back_param={
  54. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  55. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  56. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  57. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  58. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  59. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  60. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  61. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  62. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  63. .mag_odr = FML_IMU_MAG_ODR_OFF, //后脚 - 地磁计采样频率 - 200HZ
  64. .fifo_odr = FML_IMU_FIFO_ODR_OFF,
  65. };
  66. //待机模式
  67. static const fml_imu_param_t standby_front_param={
  68. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  69. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  70. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  71. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //前脚 - 时间戳关闭
  72. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  73. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  74. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  75. .acc_odr = FML_IMU_ACC_ODR_12HZ5, //前脚 - 加速度采样频率 - 12.5HZ
  76. .gry_odr = FML_IMU_GRY_ODR_OFF, //前脚 - 陀螺仪采样频率 - 关闭
  77. .mag_odr = FML_IMU_MAG_ODR_OFF, //前脚 - 地磁计采样频率 - 关闭
  78. .fifo_odr = FML_IMU_FIFO_ODR_OFF, //前脚 - FIFO采样频率 - 104HZ
  79. };
  80. static const fml_imu_param_t standby_param={
  81. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  82. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  83. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  84. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  85. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  86. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  87. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  88. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  89. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  90. .mag_odr = FML_IMU_MAG_ODR_10HZ, //后脚 - 地磁计采样频率 - 10HZ
  91. .fifo_odr = FML_IMU_FIFO_ODR_OFF, //后脚 - FIFO采样频率 - 关闭
  92. };
  93. typedef struct
  94. {
  95. int16_t max_temp;
  96. uint16_t time_count;
  97. }ACC_TIME_TYPE;
  98. typedef struct
  99. {
  100. ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
  101. int window_length;
  102. }SLIDE_WINDOW;
  103. int cal_unsigned_D_value(uint16_t left_value, uint16_t right_value)
  104. {
  105. if(left_value <= right_value)
  106. {
  107. return right_value - left_value;
  108. }
  109. else
  110. {
  111. return 65535-left_value + 1 + right_value;
  112. }
  113. }
  114. static uint8_t flag_move =0;
  115. void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t time_count)
  116. {
  117. ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
  118. //检测当前的值是是否是最大值
  119. if(max_slide_window->window_length == 0)
  120. {
  121. max_slide_window->slide_window[0] = acc_time_type_temp;
  122. max_slide_window->window_length = 1;
  123. }
  124. else
  125. {
  126. //先判断长度是否溢出来了
  127. while(cal_unsigned_D_value(max_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
  128. {
  129. memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
  130. max_slide_window->window_length --;
  131. }
  132. //再检测新的元素需要前面的元素小
  133. while(max_slide_window->window_length > 0)
  134. {
  135. if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
  136. {
  137. max_slide_window->window_length --;
  138. }
  139. else
  140. {
  141. break;
  142. }
  143. }
  144. max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
  145. max_slide_window->window_length ++;
  146. }
  147. //检测当前的值是是否是最大值
  148. if(min_slide_window->window_length == 0)
  149. {
  150. min_slide_window->slide_window[0] = acc_time_type_temp;
  151. min_slide_window->window_length = 1;
  152. }
  153. else
  154. {
  155. //先判断长度是否溢出来了
  156. while(cal_unsigned_D_value(min_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
  157. {
  158. memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
  159. min_slide_window->window_length --;
  160. }
  161. //再检测新的元素需要前面的元素小
  162. while(min_slide_window->window_length > 0)
  163. {
  164. if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
  165. {
  166. min_slide_window->window_length --;
  167. }
  168. else
  169. {
  170. break;
  171. }
  172. }
  173. min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
  174. min_slide_window->window_length ++;
  175. }
  176. }
  177. /************************ 踮脚显示电量 ***********************************/
  178. //没穿鞋的情况下
  179. void app_BatDispaly_Process_N(void)
  180. {
  181. ser_imu_data_t data= {0};
  182. static uint8_t lED_LIFE_SIGNAL = 0;
  183. static uint8_t lED_LIFE_TIME = 0;
  184. // DEBUG_LOG("app_BatDispaly_Process_N;\n");
  185. if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_STANDBY))
  186. {
  187. return;//停止状态
  188. }
  189. //获取最新一组前脚加速度
  190. int16_t data_size = 0;
  191. data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
  192. if(data_size > 0){
  193. hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size -1 , &data);
  194. int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
  195. if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
  196. {
  197. lED_LIFE_SIGNAL = 3;
  198. }
  199. else if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
  200. if(abs(acc_norm - 4194304) < 362144 && data.acc[2] < -1024)
  201. {
  202. lED_LIFE_SIGNAL = 0;
  203. }
  204. // 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);
  205. if(lED_LIFE_SIGNAL > 0)
  206. {
  207. // DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
  208. if(lED_LIFE_TIME == 0){
  209. lED_LIFE_TIME = (10000/StandByPower_Interval);
  210. if(GetBatteryPersent()>20){
  211. LED_Start(LED_OVERTURN,COLOR_GREEN);
  212. }else{
  213. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  214. }
  215. Process_SetHoldOn(app_BatDispaly_Process_N,1);
  216. }
  217. else if (2 == lED_LIFE_TIME){
  218. LED_Stop(LED_OVERTURN);
  219. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  220. }
  221. if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
  222. }
  223. else
  224. {
  225. // DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
  226. if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
  227. LED_Stop(LED_OVERTURN);
  228. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  229. }
  230. if(1 == flag_move){flag_move =0;
  231. LED_Stop(LED_OVERTURN);
  232. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  233. }
  234. }
  235. }
  236. }
  237. //穿鞋的情况下
  238. void app_BatDispaly_Process(void)
  239. {
  240. ser_imu_data_t data={0};
  241. static uint16_t time_count = 0;
  242. static uint16_t station_count =0;
  243. static uint16_t overturn_180_count = 0;
  244. static uint8_t lED_LIFE_SIGNAL = 0;
  245. static uint8_t lED_LIFE_TIME = 0;
  246. static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
  247. static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
  248. if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
  249. {
  250. return;//走路状态
  251. }
  252. // DEBUG_LOG("app_BatDispaly_Process;\n");
  253. //获取最新一组前脚加速度, 有fifo
  254. int16_t data_size = 0;
  255. data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
  256. if(data_size > 0){
  257. // DEBUG_LOG("data_size : %d, hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
  258. hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
  259. //耗时较少的计算滑动窗口的最大值、最小值
  260. sort_silde_window(&max_slide_window, &min_slide_window, data.acc[0], time_count);
  261. if(time_count > SLIDE_WINDOW_LEN)
  262. {
  263. 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
  264. && max_slide_window.slide_window[0].max_temp - min_slide_window.slide_window[0].max_temp < 256 && data.acc[0] < -1400)
  265. {
  266. station_count++;
  267. }
  268. else station_count =0;
  269. }
  270. time_count++;
  271. //在穿鞋状态下,被翻转了
  272. int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
  273. if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
  274. {
  275. //DEBUG_LOG(" wear shoes if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536);\n");
  276. overturn_180_count ++;
  277. }
  278. else
  279. {
  280. overturn_180_count = 0;
  281. }
  282. if(overturn_180_count >= 5 || station_count > 4)
  283. {
  284. // DEBUG_LOG(" overturn_180_count > 5;\n");
  285. lED_LIFE_SIGNAL = 6;
  286. }
  287. if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
  288. if(lED_LIFE_SIGNAL > 0)
  289. {
  290. // DEBUG_LOG("wearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
  291. if(lED_LIFE_TIME == 0){
  292. lED_LIFE_TIME = (10000/LowPower_Interval);
  293. if(GetBatteryPersent()>20){
  294. LED_Start(LED_OVERTURN,COLOR_GREEN);
  295. }else{
  296. LED_Start(LED_OVERTURN,COLOR_ORANGE);
  297. }
  298. Process_SetHoldOn(app_BatDispaly_Process,1);
  299. }
  300. else if (2 == lED_LIFE_TIME){
  301. LED_Stop(LED_OVERTURN);
  302. Process_SetHoldOn(app_BatDispaly_Process,0);
  303. }
  304. if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
  305. }
  306. else
  307. {
  308. // DEBUG_LOG("wearshoes LED_Stop(LED_OVERTURN);\n");
  309. if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
  310. LED_Stop(LED_OVERTURN);
  311. Process_SetHoldOn(app_BatDispaly_Process,0);
  312. }
  313. if(0 == flag_move){flag_move =1;
  314. LED_Stop(LED_OVERTURN);
  315. Process_SetHoldOn(app_BatDispaly_Process_N,0);
  316. }
  317. }
  318. }
  319. }
  320. void app_overturn_Init(void)
  321. {
  322. Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
  323. Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
  324. fml_imu_mode_manage_imu_full_power_init(&app1_config_param.config_param[BLL_IMU_DIR_FRONT], &app1_config_param.config_param[BLL_IMU_DIR_BACK]);
  325. }