process.c 13 KB

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