process.c 14 KB

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