process.c 14 KB

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