终端一体化运控平台
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(10);
  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["SCChipIsConnect"] = 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. MessageLog.GetInstance.Show($"发送落杯指令--{(@event as SCChip_TakeCupEvent).Cup}");
  266. bool wait = true;
  267. var waitTimeout = DateTime.Now.AddSeconds(3);
  268. while (wait)
  269. {
  270. wait = DateTime.Now < waitTimeout;
  271. if (wait)
  272. {
  273. switch ((@event as SCChip_TakeCupEvent).Cup)
  274. {
  275. case IC_CUP.CUP_ICECREAM:
  276. wait = !(bool)status["CompletedTake_CPU_CUP_ICECREAM"];
  277. break;
  278. case IC_CUP.CUP_COFFEE:
  279. wait = !(bool)status["CompletedTake_CPU_CUP_COFFEE"];
  280. break;
  281. }
  282. }
  283. Thread.Sleep(10);
  284. }
  285. }
  286. catch (Exception ex)
  287. {
  288. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  289. }
  290. });
  291. //STM32F103RCT6单片机舵机打料
  292. EventBus.EventBus.GetInstance().Subscribe<SCChip_MakeIceCreamEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
  293. {
  294. try
  295. {
  296. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  297. {
  298. case IC_SE.SE_1:
  299. CompletedOpen_SE_1 = false;
  300. break;
  301. case IC_SE.SE_2:
  302. CompletedOpen_SE_2 = false;
  303. break;
  304. case IC_SE.SE_3:
  305. CompletedOpen_SE_3 = false;
  306. break;
  307. }
  308. package.Cmd = IC_CMD.OPEN_SE;
  309. package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine;
  310. commProxy.SendData(StructureToByte(package));
  311. bool wait = true;
  312. DateTime waitTimeout = DateTime.Now.AddSeconds(3);
  313. while (wait)
  314. {
  315. wait = DateTime.Now < waitTimeout;
  316. if (wait)
  317. {
  318. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  319. {
  320. case IC_SE.SE_1:
  321. wait = !CompletedOpen_SE_1;
  322. break;
  323. case IC_SE.SE_2:
  324. wait = !CompletedOpen_SE_2;
  325. break;
  326. case IC_SE.SE_3:
  327. wait = !CompletedOpen_SE_3;
  328. break;
  329. }
  330. }
  331. Thread.Sleep(10);
  332. }
  333. Thread.Sleep(1800);
  334. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  335. {
  336. case IC_SE.SE_1:
  337. CompletedClose_SE_1 = false;
  338. break;
  339. case IC_SE.SE_2:
  340. CompletedClose_SE_2 = false;
  341. break;
  342. case IC_SE.SE_3:
  343. CompletedClose_SE_3 = false;
  344. break;
  345. }
  346. package.Cmd = IC_CMD.CLOSE_SE;
  347. package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine;
  348. commProxy.SendData(StructureToByte(package));
  349. wait = true;
  350. waitTimeout = DateTime.Now.AddSeconds(3);
  351. while (wait)
  352. {
  353. wait = DateTime.Now < waitTimeout;
  354. if (wait)
  355. {
  356. switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine)
  357. {
  358. case IC_SE.SE_1:
  359. wait = !CompletedClose_SE_1;
  360. break;
  361. case IC_SE.SE_2:
  362. wait = !CompletedClose_SE_2;
  363. break;
  364. case IC_SE.SE_3:
  365. wait = !CompletedClose_SE_3;
  366. break;
  367. }
  368. }
  369. Thread.Sleep(10);
  370. }
  371. }
  372. catch (Exception ex)
  373. {
  374. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  375. }
  376. });
  377. //STM32F103RCT6单片机舵机打开或者关闭
  378. EventBus.EventBus.GetInstance().Subscribe<SCChip_SESwitchCreamEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  379. {
  380. try
  381. {
  382. package.Cmd = (@event as SCChip_SESwitchCreamEvent).IsOpen ? IC_CMD.OPEN_SE : IC_CMD.CLOSE_SE;
  383. package.Value = (byte)(@event as SCChip_SESwitchCreamEvent).SteeringEngine;
  384. commProxy.SendData(StructureToByte(package));
  385. }
  386. catch (Exception ex)
  387. {
  388. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  389. }
  390. });
  391. //STM32F103RCT6单片机控制冰淇淋机器转
  392. EventBus.EventBus.GetInstance().Subscribe<SCChip_RotorSwitchEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
  393. {
  394. try
  395. {
  396. package.Cmd = IC_CMD.ROTOR;
  397. package.Value = (@event as SCChip_RotorSwitchEvent).TurnOn ? (byte)IC_ROTOR.OPEN_ROTOR : (byte)IC_ROTOR.CLOSE_ROTOR;
  398. commProxy.SendData(StructureToByte(package));
  399. }
  400. catch (Exception ex)
  401. {
  402. MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]");
  403. }
  404. });
  405. InitStatus();
  406. //测试
  407. Start();
  408. }
  409. public override void WriteData(string address, object value)
  410. {
  411. }
  412. }
  413. }