终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

440 lines
16 KiB

  1. using BPASmartClient.EventBus;
  2. using BPASmartClient.Helper;
  3. using BPASmartClient.Message;
  4. using BPASmartClient.Model;
  5. using BPASmartClient.Model.单片机;
  6. using BPASmartClient.Model.单片机.Enum;
  7. using BPASmartClient.Peripheral;
  8. using BPASmartClient.SerialPort;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Runtime.InteropServices;
  12. using System.Threading;
  13. using static BPASmartClient.EventBus.EventBus;
  14. namespace BPASmartClient.SCChip
  15. {
  16. public class ICChipMachine : BasePeripheral
  17. {
  18. //通讯代理
  19. SerialPortClient commProxy = null;
  20. //数据仓库
  21. private DataStorage<byte> dataStorage = new DataStorage<byte>();
  22. //单片机基础协议
  23. private ICChipPackage package = new ICChipPackage();
  24. //串口COM口
  25. public string PortName { get; set; }
  26. //串口波特率
  27. public string BaudRate { get; set; }
  28. //心跳时间
  29. private DateTime lastRefreshTime = DateTime.MinValue;
  30. /// <summary>
  31. /// 是否在线
  32. /// </summary>
  33. public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }
  34. #region 无需上传的数据
  35. /// <summary>
  36. /// 1号舵机打开完成
  37. /// </summary>
  38. public bool CompletedOpen_SE_1 { get; set; }
  39. /// <summary>
  40. /// 2号舵机打开完成
  41. /// </summary>
  42. public bool CompletedOpen_SE_2 { get; set; }
  43. /// <summary>
  44. /// 3号舵机打开完成
  45. /// </summary>
  46. public bool CompletedOpen_SE_3 { get; set; }
  47. /// <summary>
  48. /// 1号舵机关闭完成
  49. /// </summary>
  50. public bool CompletedClose_SE_1 { get; set; }
  51. /// <summary>
  52. /// 2号舵机关闭完成
  53. /// </summary>
  54. public bool CompletedClose_SE_2 { get; set; }
  55. /// <summary>
  56. /// 3号舵机关闭完成
  57. /// </summary>
  58. public bool CompletedClose_SE_3 { get; set; }
  59. /// <summary>
  60. /// 是否存在物品
  61. /// </summary>
  62. public bool ArticleExits { get; set; }
  63. /// <summary>
  64. /// 物品距离
  65. /// </summary>
  66. public byte ArticleDist { get; set; }
  67. #endregion
  68. public ICChipMachine()
  69. {
  70. }
  71. /// <summary>
  72. /// 主线程开始运行
  73. /// </summary>
  74. public override void Start()
  75. {
  76. try
  77. {
  78. commProxy.Start();
  79. IsConnected = true;
  80. MainLoop();
  81. }
  82. catch (Exception ex)
  83. {
  84. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  85. }
  86. }
  87. /// <summary>
  88. /// 停止运行
  89. /// </summary>
  90. public override void Stop()
  91. {
  92. try
  93. {
  94. commProxy.Stop();
  95. IsConnected = false;
  96. }
  97. catch (Exception ex)
  98. {
  99. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  100. }
  101. }
  102. /// <summary>
  103. /// 主循环,循环询问状态
  104. /// </summary>
  105. private void MainLoop()
  106. {
  107. ThreadManage.GetInstance().StartLong(new Action(() =>
  108. {
  109. ResolveMsg();
  110. }), "单片机解析线程");
  111. }
  112. private void ResolveMsg()
  113. {
  114. List<byte> temp = new List<byte>();
  115. //一系列解包
  116. while (dataStorage.GetSize() > 0)
  117. {
  118. byte item = dataStorage.GetData();
  119. if (item == 0xAA)
  120. {
  121. temp.Add(item);
  122. while (dataStorage.GetSize() < 4) { Thread.Sleep(5); }
  123. while (temp.Count < 5)
  124. {
  125. temp.Add(dataStorage.GetData());
  126. }
  127. if (temp[4] == 0xBB)
  128. {
  129. var package = ByteToStructure(temp.ToArray());
  130. ProcessMsg(package);
  131. }
  132. temp.Clear();
  133. }
  134. continue;
  135. }
  136. Thread.Sleep(5);
  137. }
  138. /// <summary>
  139. /// 由byte数组转换为结构体
  140. /// </summary>
  141. private ICChipPackage ByteToStructure(byte[] dataBuffer)
  142. {
  143. ICChipPackage structure = new ICChipPackage();
  144. int size = Marshal.SizeOf(typeof(ICChipPackage));
  145. IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
  146. try
  147. {
  148. Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
  149. structure = (ICChipPackage)Marshal.PtrToStructure(allocIntPtr, typeof(ICChipPackage));
  150. }
  151. finally
  152. {
  153. Marshal.FreeHGlobal(allocIntPtr);
  154. }
  155. return structure;
  156. }
  157. private byte[] StructureToByte(ICChipPackage structure)
  158. {
  159. structure.Header = 0xAA;
  160. structure.Sender = IC_SENDER.CONSOLE;
  161. structure.End = 0xBB;
  162. int size = Marshal.SizeOf(typeof(ICChipPackage));
  163. byte[] buffer = new byte[size];
  164. IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
  165. try
  166. {
  167. Marshal.StructureToPtr(structure, bufferIntPtr, true);
  168. Marshal.Copy(bufferIntPtr, buffer, 0, size);
  169. }
  170. finally
  171. {
  172. Marshal.FreeHGlobal(bufferIntPtr);
  173. }
  174. return buffer;
  175. }
  176. public void ProcessMsg(ICChipPackage data)
  177. {
  178. try
  179. {
  180. switch (data.Cmd)
  181. {
  182. case IC_CMD.HEART_BEAT:
  183. lastRefreshTime = DateTime.Now;
  184. status["OnLine"] = OnLine;
  185. break;
  186. case IC_CMD.TAKE_CUP:
  187. switch ((IC_CUP)data.Value)
  188. {
  189. case IC_CUP.CUP_COFFEE:
  190. status["CompletedTake_CPU_CUP_COFFEE"] = true;
  191. break;
  192. case IC_CUP.CUP_ICECREAM:
  193. status["CompletedTake_CPU_CUP_ICECREAM"] = true;
  194. break;
  195. }
  196. break;
  197. case IC_CMD.OPEN_SE:
  198. switch ((IC_SE)data.Value)
  199. {
  200. case IC_SE.SE_1:
  201. CompletedOpen_SE_1 = true;
  202. break;
  203. case IC_SE.SE_2:
  204. CompletedOpen_SE_2 = true;
  205. break;
  206. case IC_SE.SE_3:
  207. CompletedOpen_SE_3 = true;
  208. break;
  209. }
  210. break;
  211. case IC_CMD.CLOSE_SE:
  212. switch ((IC_SE)data.Value)
  213. {
  214. case IC_SE.SE_1:
  215. CompletedClose_SE_1 = true;
  216. break;
  217. case IC_SE.SE_2:
  218. CompletedClose_SE_2= true;
  219. break;
  220. case IC_SE.SE_3:
  221. CompletedClose_SE_3 = true;
  222. break;
  223. }
  224. break;
  225. }
  226. if (!OnLine) IsWork = false;
  227. else IsWork = true;
  228. }
  229. catch (Exception ex)
  230. {
  231. }
  232. }
  233. protected override void InitStatus()
  234. {
  235. status["CompletedTake_CPU_CUP_ICECREAM"] = false;
  236. status["CompletedTake_CPU_CUP_COFFEE"] = false;
  237. //status["CompletedOpen_SE_1"] = false;
  238. //status["CompletedOpen_SE_2"] = false;
  239. //status["CompletedOpen_SE_3"] = false;
  240. //status["CompletedClose_SE_1"] = false;
  241. //status["CompletedClose_SE_2"] = false;
  242. //status["CompletedClose_SE_3"] = false;
  243. }
  244. public override void Init()
  245. {
  246. commProxy = new SerialPortClient(communicationPar.SerialPort, (BaudRates)communicationPar.BaudRate);
  247. commProxy.SetDataStorage(dataStorage);
  248. //STM32F103RCT6单片机下杯
  249. EventBus.EventBus.GetInstance().Subscribe<SCChip_TakeCupEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  250. {
  251. try
  252. {
  253. switch ((@event as SCChip_TakeCupEvent).Cup)
  254. {
  255. case IC_CUP.CUP_ICECREAM:
  256. status["CompletedTake_CPU_CUP_ICECREAM"] = false;
  257. break;
  258. case IC_CUP.CUP_COFFEE:
  259. status["CompletedTake_CPU_CUP_COFFEE"] = false;
  260. break;
  261. }
  262. package.Cmd = IC_CMD.TAKE_CUP;
  263. package.Value = (byte)(@event as SCChip_TakeCupEvent).Cup;
  264. commProxy.SendData(StructureToByte(package));
  265. bool wait = true;
  266. var waitTimeout = DateTime.Now.AddSeconds(3);
  267. while (wait)
  268. {
  269. wait = DateTime.Now < waitTimeout;
  270. if (wait)
  271. {
  272. switch ((@event as SCChip_TakeCupEvent).Cup)
  273. {
  274. case IC_CUP.CUP_ICECREAM:
  275. wait = !(bool)status["CompletedTake_CPU_CUP_ICECREAM"];
  276. break;
  277. case IC_CUP.CUP_COFFEE:
  278. wait = !(bool)status["CompletedTake_CPU_CUP_COFFEE"];
  279. break;
  280. }
  281. }
  282. Thread.Sleep(10);
  283. }
  284. }
  285. catch (Exception ex)
  286. {
  287. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  288. }
  289. });
  290. //STM32F103RCT6单片机舵机打料
  291. EventBus.EventBus.GetInstance().Subscribe<SCChip_MakeIceCreamEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
  292. {
  293. try
  294. {
  295. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  296. {
  297. case IC_SE.SE_1:
  298. CompletedOpen_SE_1 = false;
  299. break;
  300. case IC_SE.SE_2:
  301. CompletedOpen_SE_2 = false;
  302. break;
  303. case IC_SE.SE_3:
  304. CompletedOpen_SE_3 = false;
  305. break;
  306. }
  307. package.Cmd = IC_CMD.OPEN_SE;
  308. package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine;
  309. commProxy.SendData(StructureToByte(package));
  310. bool wait = true;
  311. DateTime waitTimeout = DateTime.Now.AddSeconds(3);
  312. while (wait)
  313. {
  314. wait = DateTime.Now < waitTimeout;
  315. if (wait)
  316. {
  317. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  318. {
  319. case IC_SE.SE_1:
  320. wait = !CompletedOpen_SE_1;
  321. break;
  322. case IC_SE.SE_2:
  323. wait = !CompletedOpen_SE_2;
  324. break;
  325. case IC_SE.SE_3:
  326. wait = !CompletedOpen_SE_3;
  327. break;
  328. }
  329. }
  330. Thread.Sleep(10);
  331. }
  332. Thread.Sleep(2000);
  333. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  334. {
  335. case IC_SE.SE_1:
  336. CompletedClose_SE_1 = false;
  337. break;
  338. case IC_SE.SE_2:
  339. CompletedClose_SE_2 = false;
  340. break;
  341. case IC_SE.SE_3:
  342. CompletedClose_SE_3 = false;
  343. break;
  344. }
  345. package.Cmd = IC_CMD.CLOSE_SE;
  346. package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine;
  347. commProxy.SendData(StructureToByte(package));
  348. wait = true;
  349. waitTimeout = DateTime.Now.AddSeconds(3);
  350. while (wait)
  351. {
  352. wait = DateTime.Now < waitTimeout;
  353. if (wait)
  354. {
  355. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  356. {
  357. case IC_SE.SE_1:
  358. wait = !CompletedClose_SE_1;
  359. break;
  360. case IC_SE.SE_2:
  361. wait = !CompletedClose_SE_2;
  362. break;
  363. case IC_SE.SE_3:
  364. wait = !CompletedClose_SE_3;
  365. break;
  366. }
  367. }
  368. Thread.Sleep(10);
  369. }
  370. }
  371. catch (Exception ex)
  372. {
  373. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  374. }
  375. });
  376. //STM32F103RCT6单片机舵机打开或者关闭
  377. EventBus.EventBus.GetInstance().Subscribe<SCChip_SESwitchCreamEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  378. {
  379. try
  380. {
  381. package.Cmd = (@event as SCChip_SESwitchCreamEvent).IsOpen ? IC_CMD.OPEN_SE : IC_CMD.CLOSE_SE;
  382. package.Value = (byte)(@event as SCChip_SESwitchCreamEvent).SteeringEngine;
  383. commProxy.SendData(StructureToByte(package));
  384. }
  385. catch (Exception ex)
  386. {
  387. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  388. }
  389. });
  390. //STM32F103RCT6单片机控制冰淇淋机器转
  391. EventBus.EventBus.GetInstance().Subscribe<SCChip_RotorSwitchEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  392. {
  393. try
  394. {
  395. package.Cmd = IC_CMD.ROTOR;
  396. package.Value = (@event as SCChip_RotorSwitchEvent).TurnOn ? (byte)IC_ROTOR.OPEN_ROTOR : (byte)IC_ROTOR.CLOSE_ROTOR;
  397. commProxy.SendData(StructureToByte(package));
  398. }
  399. catch (Exception ex)
  400. {
  401. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  402. }
  403. });
  404. InitStatus();
  405. //测试
  406. Start();
  407. }
  408. public override void WriteData(string address, object value)
  409. {
  410. }
  411. }
  412. }