process.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. #include "process.h"
  2. #include "osif.h"
  3. #include "gpio.h"
  4. #include "adxl312.h"
  5. #include "uart.h"
  6. #include "crc16.h"
  7. #include "string.h"
  8. #include "math.h"
  9. uint16_t g_blinkLedTime; /*RUN LED闪烁频率控制时间*/
  10. uint16_t g_blinkLedTgtTime; /*RUN LED目标闪烁频率*/
  11. //uint32_t g_alg_run_count;
  12. //uint8_t g_bvopen_delay;
  13. uint8_t g_bvopen; // 0: close , 1: open
  14. uint8_t g_trigger_vo;
  15. #define DEFAULT_VO_PERIOD (500) /* 5秒*/
  16. uint16_t g_VoiceOutTime; /*语音播报频率控制时间*/
  17. #define BV_OPEN (1)
  18. #define BV_CLOSE (0)
  19. #define STATUS_DETECTINTERVAL (60) /*60ms * 8 == 500ms */
  20. #define BV_DELAY_COUNT (50) /*50次, 500ms */
  21. static uint8_t g_bvopen_delay;
  22. static circle_buffer cbuffer;
  23. static filter_avg_t filter_avg;
  24. static axis_info_t axis_info;
  25. static detect_info_t detect_info;
  26. static int16_t accx = 0;
  27. static int16_t accy = 0;
  28. static int16_t accz = 0;
  29. static int16_t acc_x = 0;
  30. static int16_t acc_y = 0;
  31. static int16_t acc_z = 0;
  32. //static float acc_fx = 0;
  33. //static float acc_fy = 0;
  34. //static float acc_fz = 0;
  35. //static float fx_sum = 0;
  36. //static float fy_sum = 0;
  37. //static float fz_sum = 0;
  38. uint8_t g_send_raw = 0;
  39. uint8_t g_send_filtered = 0;
  40. uint32_t g_send_sequence = 0;
  41. uint8_t g_vo_alarm = 0; /* 是否触发语音输出*/
  42. ALG_CONTEXT g_alg_context;
  43. void cbuffer_pushdata(int16_t acc_x, int16_t acc_y, int16_t acc_z);
  44. //每10ms 调用一次
  45. void timer_callback(void)
  46. {
  47. if (g_blinkLedTime < 0xFFFF)
  48. {
  49. g_blinkLedTime++;
  50. }
  51. if(g_VoiceOutTime < 0xFFFF){
  52. g_VoiceOutTime++;
  53. }
  54. //底阀打开状态
  55. if(LOW == GET_K3_STS()){
  56. if(g_bvopen_delay <= BV_DELAY_COUNT){
  57. g_bvopen_delay++;
  58. }else{
  59. //g_alg_run_count = 10*60*100; //10 min
  60. if(BV_CLOSE == g_bvopen){
  61. //g_alg_context.state = ALG_Start;
  62. g_bvopen =BV_OPEN;
  63. //g_VoiceOutTime = DEFAULT_VO_PERIOD-100;
  64. }
  65. //g_alg_context.rundelay_count = RUNDELAY_COUNT;
  66. }
  67. }else{
  68. if(g_bvopen_delay > 0){
  69. g_bvopen_delay--;
  70. }else{
  71. g_bvopen = BV_CLOSE;
  72. //if(g_alg_context.rundelay_count > 0){
  73. // g_alg_context.rundelay_count--;
  74. //}
  75. }
  76. }
  77. //433 语音输出
  78. if(g_trigger_vo > 0){
  79. g_trigger_vo--;
  80. }
  81. // 算法触发开阀延时
  82. if(g_alg_context.valveclose_delay > 0){
  83. g_alg_context.valveclose_delay--;
  84. }
  85. //read acc data
  86. ADXL312_ReadAcc(&accx, &accy, &accz);
  87. cbuffer_pushdata(accx, accy, accz);
  88. }
  89. void Process_Init(void)
  90. {
  91. g_blinkLedTime = 0;
  92. g_blinkLedTgtTime = BLINK_LED_DFTT;
  93. //g_alg_run_count = 0;
  94. g_bvopen_delay = 0;
  95. g_bvopen = BV_CLOSE;
  96. g_trigger_vo = 0;
  97. g_vo_alarm = 0;
  98. /* acc data */
  99. g_send_raw = 0;
  100. g_send_filtered = 0;
  101. g_alg_context.state = ALG_None;
  102. //g_alg_context.rundelay_count = 0;
  103. g_alg_context.valveclose_delay = 0;
  104. cbuffer.read_index = 0;
  105. cbuffer.write_index = 0;
  106. filter_avg.count = 0;
  107. }
  108. void Process_RunLedPrd(void)
  109. {
  110. /*周期性地检查LED闪烁,运行指示灯闪烁.*/
  111. if (g_blinkLedTime >= g_blinkLedTgtTime)
  112. {
  113. g_blinkLedTime = 0;
  114. LED3_TOGGLE;
  115. }
  116. /*语音输出*/
  117. if(g_VoiceOutTime >= DEFAULT_VO_PERIOD){
  118. g_VoiceOutTime = 0;
  119. if((g_vo_alarm == 1) && (g_trigger_vo == 0)){
  120. g_trigger_vo = VO_COUNT_DFTT;
  121. }
  122. }
  123. if(g_bvopen == BV_OPEN){
  124. LED4_ON;
  125. }else{
  126. LED4_OFF;
  127. }
  128. //433 语音输出
  129. if(g_trigger_vo > 0){
  130. if(GPIO_DRV_GetPinsOutput(LED2_GPIO)& (1<<LED2_PIN))
  131. {
  132. }else{
  133. LED2_ON;
  134. }
  135. }else{
  136. if(GPIO_DRV_GetPinsOutput(LED2_GPIO)&(1<<LED2_PIN))
  137. {
  138. LED2_OFF;
  139. }
  140. }
  141. }
  142. void sv_open(void)
  143. {
  144. LED1_ON;
  145. }
  146. void sv_close(void)
  147. {
  148. LED1_OFF;
  149. }
  150. void cbuffer_pushdata(int16_t acc_x, int16_t acc_y, int16_t acc_z)
  151. {
  152. cbuffer.data[0][cbuffer.write_index] = acc_x;
  153. cbuffer.data[1][cbuffer.write_index] = acc_y;
  154. cbuffer.data[2][cbuffer.write_index] = acc_z;
  155. cbuffer.write_index++;
  156. if(cbuffer.write_index == ACC_DATASIZE){
  157. cbuffer.write_index = 0;
  158. }
  159. }
  160. int cbuffer_popdata(int16_t* acc_x, int16_t* acc_y, int16_t* acc_z)
  161. {
  162. if(cbuffer.write_index == cbuffer.read_index){
  163. return 1;
  164. }
  165. *acc_x = cbuffer.data[0][cbuffer.read_index];
  166. *acc_y = cbuffer.data[1][cbuffer.read_index];
  167. *acc_z = cbuffer.data[2][cbuffer.read_index];
  168. cbuffer.read_index++;
  169. if(cbuffer.read_index == ACC_DATASIZE){
  170. cbuffer.read_index = 0;
  171. }
  172. return 0;
  173. }
  174. void alg_PreProcess(void)
  175. {
  176. static uint8_t _bvopen = BV_CLOSE;
  177. //状态切换
  178. if(_bvopen != g_bvopen){
  179. _bvopen = g_bvopen;
  180. if(BV_OPEN == g_bvopen){
  181. if(ALG_None == g_alg_context.state){
  182. g_alg_context.state = ALG_Start;
  183. }
  184. //g_VoiceOutTime = DEFAULT_VO_PERIOD-200;
  185. }else{
  186. if(ALG_Triggering != g_alg_context.state){
  187. g_alg_context.state = ALG_None;
  188. }
  189. g_vo_alarm = 0;
  190. }
  191. }
  192. }
  193. void alg_start(void)
  194. {
  195. g_alg_context.state = ALG_Calibrate;
  196. g_alg_context.axis_offset.x = 0.0;
  197. g_alg_context.axis_offset.y = 0.0;
  198. g_alg_context.axis_offset.z = 0.0;
  199. g_alg_context.calibrate_count = 0;
  200. g_alg_context.valveclose_delay = 0;
  201. g_alg_context.valveclose_times = 0;
  202. detect_info.count = 0;
  203. memset(detect_info.info, 0x00, sizeof(axis_info_t)*DETECT_CNT);
  204. //filter_avg.count = 0;
  205. //printf("alg_start \r");
  206. }
  207. void alg_calibrate(axis_info_t* pAxis_info){
  208. g_alg_context.axis_offset.x += pAxis_info->x;
  209. g_alg_context.axis_offset.y += pAxis_info->y;
  210. g_alg_context.axis_offset.z += pAxis_info->z;
  211. g_alg_context.calibrate_count++;
  212. if(g_alg_context.calibrate_count == CALIBRATE_COUNT){
  213. g_alg_context.axis_offset.x /= CALIBRATE_COUNT;
  214. g_alg_context.axis_offset.y /= CALIBRATE_COUNT;
  215. g_alg_context.axis_offset.z /= CALIBRATE_COUNT;
  216. g_alg_context.state = ALG_Detecting;
  217. g_alg_context.calibrate_count = 0;
  218. //printf("X=%4.3f g Y=%4.3f g Z=%4.3f g \r", g_alg_context.axis_offset.x, g_alg_context.axis_offset.y, g_alg_context.axis_offset.z);
  219. }
  220. }
  221. void alg_detect(axis_info_t* paxis_info)
  222. {
  223. uint16_t i=0;
  224. uint16_t _trigger=0;
  225. static uint16_t x_keepcount =0;
  226. static uint16_t y_keepcount =0;
  227. static uint16_t z_keepcount =0;
  228. float accx_sum = 0.0;
  229. float accy_sum = 0.0;
  230. float accz_sum = 0.0;
  231. //消除零偏
  232. paxis_info->x -= g_alg_context.axis_offset.x;
  233. paxis_info->y -= g_alg_context.axis_offset.y;
  234. paxis_info->z -= g_alg_context.axis_offset.z;
  235. //机械滤波
  236. if(fabs(paxis_info->x) <= MECHANICAL_NOISE_THRESHOLD){
  237. paxis_info->x = 0.0;
  238. }
  239. if(fabs(paxis_info->y) <= MECHANICAL_NOISE_THRESHOLD){
  240. paxis_info->y = 0.0;
  241. }
  242. if(fabs(paxis_info->z) <= MECHANICAL_NOISE_THRESHOLD){
  243. paxis_info->z = 0.0;
  244. }
  245. detect_info.info[detect_info.count].x = paxis_info->x;
  246. detect_info.info[detect_info.count].y = paxis_info->y;
  247. detect_info.info[detect_info.count].z = paxis_info->z;
  248. for(i=0; i < DETECT_CNT; i++){
  249. accx_sum += detect_info.info[i].x*0.01;
  250. accy_sum += detect_info.info[i].y*0.01;
  251. accz_sum += detect_info.info[i].z*0.01;
  252. }
  253. accx_sum *= 9.8;
  254. accy_sum *= 9.8;
  255. accz_sum *= 9.8;
  256. //printf("X=%4.3f g Y=%4.3f g Z=%4.3f g \r", accx_sum, accy_sum, accz_sum);
  257. //加速度累加值大于了 5Km/h, 需要持续 2s 去震动
  258. if(fabs(accx_sum) >= DETECT_THRESHOLD){
  259. x_keepcount++;
  260. if(KEEP_CNT == x_keepcount){
  261. _trigger = 1;
  262. }
  263. }else if(fabs(accx_sum) >= DETECT_THRESHOLD_DOWN){
  264. if(x_keepcount>0){
  265. x_keepcount++;
  266. }
  267. if(KEEP_CNT == x_keepcount){
  268. _trigger = 1;
  269. }
  270. }else{
  271. x_keepcount=0;
  272. }
  273. if(fabs(accy_sum) >= DETECT_THRESHOLD){
  274. y_keepcount++;
  275. if(KEEP_CNT == y_keepcount){
  276. _trigger = 1;
  277. }
  278. }else if(fabs(accy_sum) >= DETECT_THRESHOLD_DOWN){
  279. if(y_keepcount>0){
  280. y_keepcount++;
  281. }
  282. if(KEEP_CNT == y_keepcount){
  283. _trigger = 1;
  284. }
  285. }else{
  286. y_keepcount = 0;
  287. }
  288. if(fabs(accz_sum) >= DETECT_THRESHOLD){
  289. z_keepcount++;
  290. if(KEEP_CNT == z_keepcount){
  291. _trigger = 1;
  292. }
  293. }else if(fabs(accz_sum) >= DETECT_THRESHOLD_DOWN){
  294. if(z_keepcount>0){
  295. z_keepcount++;
  296. }
  297. if(KEEP_CNT == z_keepcount){
  298. _trigger = 1;
  299. }
  300. }else{
  301. z_keepcount = 0;
  302. }
  303. if(1 == _trigger){
  304. g_alg_context.state = ALG_Triggering;
  305. g_alg_context.valveclose_delay = CLOSEVALVE_DELAY;
  306. sv_open(); //打开电磁阀,泄气
  307. g_alg_context.valveclose_times =0;
  308. g_alg_context.valveclose_interval = CLOSEVALVE_INTERVAL;
  309. g_vo_alarm = 0;
  310. x_keepcount = 0;
  311. y_keepcount = 0;
  312. z_keepcount = 0;
  313. }
  314. detect_info.count++;
  315. if(detect_info.count == DETECT_CNT)
  316. {
  317. detect_info.count = 0;
  318. }
  319. }
  320. void alg_Triggering(void)
  321. {
  322. //时间到强制关阀
  323. //底阀关闭时,就可以关阀了
  324. //if(BV_CLOSE == g_bvopen){
  325. // sv_close();
  326. // g_alg_context.state = ALG_Finished;
  327. // g_vo_alarm = 0;
  328. //}else{
  329. if(0 == g_alg_context.valveclose_delay)
  330. {
  331. /*
  332. if(1 != g_vo_alarm){
  333. g_VoiceOutTime = DEFAULT_VO_PERIOD-50;
  334. g_vo_alarm = 1;
  335. }
  336. */
  337. sv_close();
  338. if(g_alg_context.valveclose_interval > 0){
  339. g_alg_context.valveclose_interval--;
  340. }else{
  341. if(BV_CLOSE == g_bvopen){
  342. //sv_close();
  343. g_alg_context.state = ALG_Finished;
  344. g_vo_alarm = 0;
  345. return ;
  346. }
  347. g_alg_context.valveclose_delay = CLOSEVALVE_DELAY;
  348. sv_open(); //打开电磁阀,泄气
  349. g_alg_context.valveclose_times++;
  350. g_alg_context.valveclose_interval = CLOSEVALVE_INTERVAL;
  351. }
  352. }
  353. if(g_alg_context.valveclose_times >= 3){
  354. sv_close();
  355. g_alg_context.state = ALG_Finished;
  356. if(1 != g_vo_alarm){
  357. g_VoiceOutTime = DEFAULT_VO_PERIOD-10;
  358. g_vo_alarm = 1;
  359. }
  360. }
  361. //}
  362. }
  363. void alg_Finished(void)
  364. {
  365. //if(g_alg_context.rundelay_count == 0){
  366. g_alg_context.state = ALG_None;
  367. //}
  368. }
  369. void alg_filter(axis_info_t* paxis_info)
  370. {
  371. uint16_t i=0;
  372. float x_sum = 0.0;
  373. float y_sum = 0.0;
  374. float z_sum = 0.0;
  375. filter_avg.info[filter_avg.count].x = paxis_info->x;
  376. filter_avg.info[filter_avg.count].y = paxis_info->y;
  377. filter_avg.info[filter_avg.count].z = paxis_info->z;
  378. for(i=0; i < FILTER_CNT; i++){
  379. x_sum += filter_avg.info[i].x;
  380. y_sum += filter_avg.info[i].y;
  381. z_sum += filter_avg.info[i].z;
  382. }
  383. paxis_info->x = x_sum/FILTER_CNT;
  384. paxis_info->y = y_sum/FILTER_CNT;
  385. paxis_info->z = z_sum/FILTER_CNT;
  386. filter_avg.count++;
  387. if(filter_avg.count == FILTER_CNT){
  388. filter_avg.count = 0;
  389. }
  390. }
  391. static uint16_t d_crc;
  392. static uint8_t d_buffer[20] = {0};
  393. void Process_Alg(void)
  394. {
  395. alg_PreProcess();
  396. if(0 == cbuffer_popdata(&acc_x, &acc_y, &acc_z)){
  397. axis_info.x = acc_x*2.9/1000;
  398. axis_info.y = acc_y*2.9/1000;
  399. axis_info.z = acc_z*2.9/1000;
  400. alg_filter(&axis_info);
  401. uint32_t start = OSIF_GetMilliseconds();
  402. //printf("alg:%d ms st: %d \r", start, g_alg_context.state);
  403. switch(g_alg_context.state){
  404. case ALG_Start:
  405. alg_start();
  406. break;
  407. case ALG_Calibrate:
  408. alg_calibrate(&axis_info);
  409. break;
  410. case ALG_Detecting:
  411. alg_detect(&axis_info);
  412. break;
  413. case ALG_Triggering:
  414. alg_Triggering();
  415. break;
  416. case ALG_Finished:
  417. alg_Finished();
  418. break;
  419. default:
  420. break;
  421. }
  422. #if 1
  423. if(g_send_raw){
  424. d_buffer[0] = 0xAA;
  425. d_buffer[1] = 0xAA;
  426. g_send_sequence++;
  427. d_buffer[2] = (g_send_sequence >> 24)&0xff;
  428. d_buffer[3] = (g_send_sequence >> 16)&0xff;
  429. d_buffer[4] = (g_send_sequence >> 8)&0xff;
  430. d_buffer[5] = (g_send_sequence >> 0)&0xff;
  431. d_buffer[6] = (acc_x>>8)&0xFF;
  432. d_buffer[7] = (acc_x)&0xFF;
  433. d_buffer[8] = (acc_y>>8)&0xFF;
  434. d_buffer[9] = (acc_y)&0xFF;
  435. d_buffer[10] = (acc_z>>8)&0xFF;
  436. d_buffer[11] = (acc_z)&0xFF;
  437. d_crc = crc16(d_buffer, 12);
  438. d_buffer[12] = (uint8_t)((d_crc>>8) & 0xff);
  439. d_buffer[13] = (uint8_t)(d_crc & 0xff);
  440. Uart1_TransmitData(d_buffer, 14);
  441. }
  442. #endif
  443. }
  444. }