process.c 14 KB

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