soft_engine.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. #include "soft_engine.h"
  2. #include "soft_crc.h"
  3. #include "crc.h"
  4. #include "string.h"
  5. #include "usart_data_handle.h"
  6. struct ENGINE_DATA engine_data;
  7. //串口接收奥安发动机数据
  8. AOAN_TYPE aoan_data = {0, .engin_warn = 0xffff};
  9. Connect_check aoan_engine_Link;
  10. //解析奥安油电混传感器数据
  11. short decode_aoan_engine(uint8_t *pdata, uint16_t length)
  12. {
  13. short rst = 0;
  14. if (pdata[0] == 0x5A && pdata[1] == 0xA5 && pdata[2] == 0x1A && pdata[3] == 0x02)
  15. {
  16. unsigned char dNum = pdata[2];
  17. //校验通过。
  18. if (Get_Crc16(pdata, dNum + 5) == 0)
  19. {
  20. rst = 1;
  21. aoan_engine_Link.connect_status = COMP_NORMAL;
  22. //赋值数据
  23. memcpy(&aoan_data, &pdata[3], dNum);
  24. aoan_engine_Link.recv_time = HAL_GetTick();
  25. }
  26. }
  27. return rst;
  28. }
  29. //串口接收VKV3发动机数据
  30. VKV3_TYPE vkv3_data = {0, .engin_warn = 0xffff};
  31. Connect_check vkv3_engine_link;
  32. //解析V3协议油电混传感器数据
  33. short decode_vkv3_engine(uint8_t *pdata, uint16_t length)
  34. {
  35. short rst = 0;
  36. if (pdata[0] == 0x5A && pdata[1] == 0xA5 && pdata[2] == 0X27 && pdata[4] == 0X03)
  37. {
  38. unsigned char dLEN = pdata[2];
  39. unsigned char comID = pdata[3];
  40. //校验通过。
  41. if (Get_Crc16(pdata, dLEN + 6) == 0)
  42. {
  43. rst = 1;
  44. switch (comID)
  45. {
  46. case 0X01:
  47. vkv3_engine_link.connect_status = COMP_NORMAL;
  48. //赋值数据
  49. memcpy(&vkv3_data, &pdata[4], dLEN);
  50. break;
  51. default:
  52. break;
  53. }
  54. vkv3_engine_link.recv_time = HAL_GetTick();
  55. }
  56. }
  57. return rst;
  58. }
  59. bool geely_set_tcd = false,geely_set_tcd_re = false,
  60. geely_set_tlock = false, geely_set_tlock_re = false, geely_set_protect = false,
  61. geely_send_time = false, geely_get_sys = false,geely_get_version = false,geely_get_time = false;
  62. GEELY2 geely_data2;
  63. //解析吉利发动机
  64. GEELY geely_data = {0};
  65. GEELY_MONI geely_moni = {0};
  66. Connect_check geely_engin_link;
  67. void EngGeelyCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len)
  68. {
  69. if (cellCanID == 0x1c0)
  70. {
  71. memcpy(&geely_data.engine_ver, &data[0], len);
  72. }
  73. else if (cellCanID == 0x1c1)
  74. {
  75. //木牛防地雷达会异常进入发动机识别
  76. geely_engin_link.connect_status = COMP_NORMAL;
  77. memcpy(&geely_data.engine_rev, &data[0], len);
  78. }
  79. else if (cellCanID == 0x1c2)
  80. {
  81. memcpy(&geely_data.engine_vol, &data[0], len);
  82. }
  83. else if (cellCanID == 0x1c3)
  84. {
  85. uint8_t checkSum = 0;
  86. for (uint8_t i = 0; i < 8; i++)
  87. {
  88. checkSum += data[i];
  89. }
  90. geely_moni.recv_1c3++;
  91. if (checkSum == 0)
  92. {
  93. memcpy(&geely_data.engine_control, &data[0], len);
  94. if (geely_moni.msg1c3_last + 1 != geely_data.engine_counts)
  95. {
  96. geely_moni.msg1c3_indexerr++;
  97. }
  98. geely_moni.msg1c3_last = geely_data.engine_counts;
  99. if(geely_data.engine_set == 0x11)
  100. {
  101. //接收保养时间反馈
  102. if(geely_set_tcd == true)
  103. {
  104. geely_set_tcd = false;
  105. geely_set_counts = 0;
  106. geely_set_tcd_re = true;
  107. }
  108. }
  109. if(geely_data.engine_set == 0x12)
  110. {
  111. //接收保养时间复位反馈
  112. if(geely_set_tcd_re == true)
  113. {
  114. geely_set_tcd_re = false;
  115. geely_set_counts = 0;
  116. }
  117. }
  118. if(geely_data.engine_set == 0x14)
  119. {
  120. //接收锁机时间反馈
  121. if(geely_set_tlock == true)
  122. {
  123. geely_set_tlock = false;
  124. geely_set_counts = 0;
  125. geely_set_tlock_re = true;
  126. }
  127. }
  128. if(geely_data.engine_set == 0x15)
  129. {
  130. //接收锁机时间复位反馈
  131. if(geely_set_tlock_re == true)
  132. {
  133. geely_set_tlock_re = false;
  134. geely_set_counts = 0;
  135. }
  136. }
  137. if(geely_data.engine_set == 0x17)
  138. {
  139. }
  140. }
  141. else
  142. {
  143. geely_moni.msg1c3_sumerr++;
  144. }
  145. }
  146. else if (cellCanID == 0x1c4)
  147. {
  148. memcpy(&geely_data.engine_runtime, &data[0], len);
  149. }
  150. else
  151. {
  152. if(cellCanID >= 0x1E1 && cellCanID <= 0x1EF)
  153. {
  154. geely_engin_link.connect_status = COMP_NORMAL;
  155. if(geely_data2.version2_flag != true)
  156. {
  157. geely_data2.version2_flag = true;
  158. } //作为第二版协议标志
  159. }
  160. //第二版协议
  161. switch (cellCanID)
  162. {
  163. case 0x1E1:
  164. break;
  165. case 0x1E2:
  166. geely_get_version = true;
  167. geely_count = 10;
  168. memcpy(&geely_data2.engine_ver,&data[0],8);
  169. break;
  170. case 0x1E3:
  171. geely_get_time = true;
  172. //geely_count = 10;
  173. memcpy(&geely_data2.engine_runtime,&data[0],8);
  174. break;
  175. case 0x1E4:
  176. memcpy(&geely_data2.Bit1E4,&data[0],6);
  177. break;
  178. case 0x1E8:
  179. memcpy(&geely_data2.engine_time,&data[0],8);
  180. break;
  181. case 0x1E9:
  182. memcpy(&geely_data2.engine_rev,&data[0],8);
  183. break;
  184. case 0x1EA:
  185. memcpy(&geely_data2.Bit1EA,&data[0],8);
  186. break;
  187. case 0x1EB:
  188. memcpy(&geely_data2.FuelConsumption,&data[0],8);
  189. break;
  190. case 0x1ED:
  191. memcpy(&geely_data2.AlmST0,&data[0],8);
  192. break;
  193. case 0x1EE:
  194. memcpy(&geely_data2.Gear1Position,&data[0],7);
  195. break;
  196. default:
  197. break;
  198. }
  199. }
  200. geely_engin_link.recv_time = HAL_GetTick();
  201. }
  202. short geely_set_counts = 0;
  203. #pragma pack(1)
  204. typedef struct
  205. {
  206. uint32_t time;
  207. uint8_t nodecode:4;
  208. uint8_t message_conut0:4;
  209. int8_t check_sum0;
  210. uint8_t client_cmd;
  211. uint8_t syscontrol;
  212. uint8_t reserve0;
  213. uint8_t reserve1;
  214. uint32_t reserve2:20;
  215. uint8_t message_conut1:4;
  216. int8_t check_sum1;
  217. }geely_info2;
  218. geely_info2 geely_sendinfo2;
  219. #pragma pack()
  220. uint8_t geely_count = 15;
  221. uint8_t start_engine = 1; // 0x80启动 0停止
  222. #define SENDTO_GEELY_STATUS_ID (0X1A0)
  223. STO_GEELY sendto_geely = {.ExtenderControl = 0,
  224. .ExtenderSetting = 0x10,
  225. .SettingParameter = 0,
  226. .ExtenderBak = 0,
  227. .MessageCount = 0
  228. };
  229. uint32_t sendto_geely_lasttime = 0;
  230. void send_msg_to_geely(void)
  231. {
  232. if (geely_engin_link.connect_status == COMP_NORMAL && HAL_GetTick() - sendto_geely_lasttime > 100)
  233. {
  234. uint8_t geely[8] = {0};
  235. sendto_geely_lasttime = HAL_GetTick();
  236. //Geely_version2_init();
  237. if(geely_data2.version2_flag == true)
  238. {
  239. //Geely_version2_send_info();
  240. }
  241. else
  242. {
  243. sendto_geely.ExtenderBak = planep.thr_pwm;
  244. sendto_geely.DroneStatus = (uint8_t)planep.lock_status; //(thr_lock_status == LOCKED ? 0 : 1);
  245. sendto_geely.MessageCount++;
  246. if(geely_set_tcd == true)
  247. {
  248. geely_set_counts++;
  249. if(geely_set_counts > 5){
  250. geely_set_tcd = false;
  251. geely_set_counts = 0;
  252. }
  253. sendto_geely.ExtenderSetting = 0x11;
  254. //sendto_geely.SettingParameter = 0;
  255. }
  256. else if(geely_set_tcd_re == true)
  257. {
  258. geely_set_counts++;
  259. if(geely_set_counts > 5){
  260. geely_set_tcd_re = false;
  261. geely_set_counts = 0;
  262. }
  263. sendto_geely.ExtenderSetting = 0x12;
  264. sendto_geely.SettingParameter = 0;
  265. }
  266. else if(geely_set_tlock == true)
  267. {
  268. geely_set_counts++;
  269. if(geely_set_counts > 5){
  270. geely_set_tlock = false;
  271. geely_set_counts = 0;
  272. }
  273. sendto_geely.ExtenderSetting = 0x14;
  274. //sendto_geely.SettingParameter = 0;
  275. }
  276. else if(geely_set_tlock_re == true)
  277. {
  278. geely_set_counts++;
  279. if(geely_set_counts > 5){
  280. geely_set_tlock_re = false;
  281. geely_set_counts = 0;
  282. }
  283. sendto_geely.ExtenderSetting = 0x15;
  284. sendto_geely.SettingParameter = 0;
  285. }
  286. else if(geely_set_protect == true)
  287. {
  288. geely_set_counts++;
  289. if(geely_set_counts > 5){
  290. geely_set_protect = false;
  291. geely_set_counts = 0;
  292. }
  293. sendto_geely.ExtenderSetting = 0x17;
  294. sendto_geely.SettingParameter = 0;
  295. }
  296. else
  297. {
  298. sendto_geely.ExtenderSetting = 0x10;
  299. sendto_geely.SettingParameter = 0;
  300. geely_set_counts = 0;
  301. }
  302. memcpy(geely, (uint8_t *)&sendto_geely.ExtenderControl, 7);
  303. sendto_geely.CheckSum = 0;
  304. for (uint8_t i = 0; i < 7; i++)
  305. {
  306. sendto_geely.CheckSum += geely[i];
  307. }
  308. sendto_geely.CheckSum = -sendto_geely.CheckSum;
  309. //can_send_msg_normalstd(&sendto_geely.ExtenderControl, sizeof(sendto_geely), SENDTO_GEELY_STATUS_ID);
  310. geely_moni.send_1a0++;
  311. }
  312. }
  313. }
  314. comp_status engine_link_status = COMP_NOEXIST;
  315. struct ENGINE_DATA engine_data = {0, 0};
  316. /*
  317. 发动机类型 uint8 1-瑞深 2-中飞
  318. 发动机转速 uint16_t RPM
  319. 发动机油门 uint16_t
  320. 发动机电压 uint16_t 0.1v
  321. 充电电流 uint16_t 0.1A
  322. 发动机运行时间 uint32_t Min 总运行时间不清零
  323. 剩余保养时间 uint16_t Min 保养后清零
  324. 剩余锁机时间 uint16_t Min 锁机倒计时
  325. 运行状态 uint8_t 0:停止,1:等待,2:运行, 3:锁机
  326. 报警信息 uint16_t 按位来表示可同时容纳16种警报
  327. 剩余油量 uint8_t % 0%-100%
  328. 气缸1温度 uint16_t ℃ 0℃~300℃
  329. 气缸2温度 uint16_t ℃ 0℃~300℃
  330. PCB温度 uint8_t ℃ 0℃~255℃
  331. */
  332. /*
  333. 检查智能电池的连接及数据获取,主要解决兼容多厂家设备接入时的选用优先级问题。
  334. 更新速度至少要 5hz
  335. 缺少放电电流数据
  336. */
  337. void update_engine_data(void)
  338. {
  339. //监测中飞发动机
  340. Check_dev_link(&aoan_engine_Link,5000,(char *)&aoan_data,sizeof(AOAN_TYPE));
  341. //监测VKV3的发动机
  342. Check_dev_link(&vkv3_engine_link,5000,(char *)&vkv3_data,sizeof(VKV3_TYPE));
  343. //检测GEELY发动机
  344. Check_dev_link(&geely_engin_link,5000,(char *)&geely_data,sizeof(GEELY));
  345. if (aoan_engine_Link.connect_status == COMP_NORMAL)
  346. {
  347. engine_link_status = COMP_NORMAL;
  348. //数字显示,显示9位数
  349. engine_data.engine_type = 2;
  350. engine_data.engine_rev = aoan_data.engin_rev;
  351. engine_data.engine_thr = aoan_data.engin_thr;
  352. engine_data.engine_vol = aoan_data.engin_vol;
  353. engine_data.engine_elect = aoan_data.engin_elect;
  354. engine_data.engine_rtime = aoan_data.engin_rtime;
  355. engine_data.engine_tcd = aoan_data.engin_tcd;
  356. engine_data.engine_lcd = aoan_data.engin_lcd;
  357. engine_data.engine_rsta = aoan_data.engin_rsta;
  358. engine_data.engine_warn = aoan_data.engin_warn;
  359. engine_data.engine_roil = aoan_data.engin_roil;
  360. engine_data.engine_cyl1temp = aoan_data.engin_cyl1temp;
  361. engine_data.engine_cyl2temp = aoan_data.engin_cyl2temp;
  362. engine_data.engine_pcbtemp = aoan_data.engin_pcbtemp;
  363. memcpy(engine_data.engine_brand, "AOAN", 4);
  364. }
  365. else if (vkv3_engine_link.connect_status == COMP_NORMAL)
  366. {
  367. engine_link_status = COMP_NORMAL;
  368. //数字显示,显示9位数
  369. engine_data.engine_type = 3;
  370. engine_data.engine_rev = vkv3_data.engin_rev;
  371. engine_data.engine_thr = vkv3_data.engin_thr;
  372. engine_data.engine_vol = vkv3_data.engin_vol;
  373. engine_data.engine_elect = vkv3_data.engin_elect;
  374. engine_data.engine_rtime = vkv3_data.engin_rtime;
  375. engine_data.engine_tcd = vkv3_data.engin_tcd;
  376. engine_data.engine_lcd = vkv3_data.engin_lcd;
  377. engine_data.engine_rsta = vkv3_data.engin_rsta;
  378. engine_data.engine_warn = vkv3_data.engin_warn;
  379. engine_data.engine_roil = vkv3_data.engin_roil;
  380. engine_data.engine_cyl1temp = vkv3_data.engin_cyl1temp;
  381. engine_data.engine_cyl2temp = vkv3_data.engin_cyl2temp;
  382. engine_data.engine_pcbtemp = vkv3_data.engin_pcbtemp;
  383. engine_data.engine_sn = vkv3_data.engin_sn;
  384. memcpy(engine_data.engine_brand, vkv3_data.engin_brand, 8);
  385. }
  386. else if (geely_engin_link.connect_status == COMP_NORMAL)
  387. {
  388. engine_link_status = COMP_NORMAL;
  389. engine_data.engine_type = 4;
  390. //数字显示,显示9位数
  391. if(geely_data2.version2_flag != true)
  392. {
  393. engine_data.engine_rev = geely_data.engine_rev;
  394. engine_data.engine_thr = geely_data.engine_thrposition * 0.1f;
  395. engine_data.engine_vol = geely_data.engine_vol * 2;
  396. engine_data.engine_elect = (short)(geely_data.engine_elect - 1000) * 2;
  397. engine_data.engine_rtime = geely_data.engine_runtime;
  398. engine_data.engine_tcd = geely_data.engine_tcd;
  399. engine_data.engine_lcd = geely_data.engine_tlock;
  400. engine_data.engine_rsta = geely_data.engine_status;
  401. engine_data.engine_warn = geely_data.engine_warn & 0xffef;//屏蔽总线系统异常
  402. engine_data.engine_roil = geely_data.engine_fuelposition * 0.5f;
  403. engine_data.engine_cyl1temp = geely_data.engine_cyltemp - 40;
  404. engine_data.engine_cyl2temp = 0;
  405. engine_data.engine_pcbtemp = geely_data.engine_cooltemp - 40;
  406. memcpy(engine_data.engine_brand, geely_data.engine_brand, 3);
  407. memcpy(&engine_data.engine_brand[3],"-", 1);
  408. snprintf((char *)&engine_data.engine_brand[4],4,"%d",(int)geely_data.engine_ver);
  409. engine_data.engine_sn = geely_data.engine_sn[0] * 10000000 + geely_data.engine_sn[1] * 100000 +
  410. geely_data.engine_sn[2] * 1000 + geely_data.engine_sn[3];
  411. engine_data.engine_lockstatus = geely_data.engine_control;
  412. }
  413. else
  414. {
  415. engine_data.engine_rev = geely_data2.engine_rev;
  416. engine_data.engine_thr = geely_data2.Bit1EA.engine_ATP1 * 0.05f;
  417. engine_data.engine_vol = geely_data2.engine_vol * 0.1f;
  418. engine_data.engine_elect = (short)(geely_data2.engine_elect * 0.05f - 400) * 10;
  419. engine_data.engine_rtime = geely_data2.engine_runtime;
  420. engine_data.engine_tcd = geely_data2.engine_tcd;
  421. engine_data.engine_lcd = geely_data2.engine_tlock;
  422. engine_data.engine_rsta = geely_data2.engine_state;
  423. engine_data.engine_warn = geely_data2.ErrST0 + geely_data2.EmgST1;
  424. engine_data.engine_roil = geely_data2.GPS * 0.5f;
  425. engine_data.engine_cyl1temp = geely_data2.engine_cooltemp - 40;
  426. engine_data.engine_cyl2temp = geely_data2. engine_cooltemp1 - 40;
  427. engine_data.engine_pcbtemp = geely_data2.engine_GWT - 40;
  428. memcpy(engine_data.engine_brand, geely_data2.engine_brand, 3);
  429. memcpy(&engine_data.engine_brand[3],"-", 1);
  430. snprintf((char *)&engine_data.engine_brand[4],4,"%d",(int)geely_data2.engine_ver);
  431. engine_data.engine_sn = geely_data2.engine_sn[0] * 10000000 + geely_data2.engine_sn[1] * 100000 +
  432. geely_data2.engine_sn[2] * 1000 + geely_data2.engine_sn[3];
  433. engine_data.engine_lockstatus = geely_data2.engine_Mcontrol;
  434. }
  435. }
  436. else
  437. {
  438. if (engine_link_status == COMP_NORMAL)
  439. {
  440. engine_link_status = COMP_LOST;
  441. memset(&engine_data, 0, sizeof(engine_data));
  442. //状态未置异常
  443. engine_data.engine_type = 0xFF;
  444. }
  445. }
  446. }
  447. /******************void engine_function(void)********************
  448. * ****************发动机检测函数*********************************
  449. * **************************************************************/
  450. void engine_function(void)
  451. {
  452. static uint32_t engine_time = 0;
  453. if(Check_Timer_Ready(&engine_time,_10_HZ_))
  454. {
  455. update_engine_data();
  456. }
  457. //给吉利发动机发送信息
  458. send_msg_to_geely();
  459. }