终端一体化运控平台
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

440 linhas
16 KiB

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