using BPA.Helper; using BPASmartClient.Model; using BPASmartClient.Model.单片机; using BPASmartClient.Model.单片机.Enum; using BPASmartClient.Peripheral; using BPASmartClient.SerialPort; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; using static BPA.Helper.EventBus; namespace BPASmartClient.SCChip { public class ICChipMachine : BasePeripheral { //通讯代理 SerialPortClient commProxy = null; //数据仓库 private DataStorage dataStorage = new DataStorage(); //单片机基础协议 private ICChipPackage package = new ICChipPackage(); //串口COM口 public string PortName { get; set; } //串口波特率 public string BaudRate { get; set; } //心跳时间 private DateTime lastRefreshTime = DateTime.MinValue; /// /// 是否在线 /// public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } #region 无需上传的数据 /// /// 1号舵机打开完成 /// public bool CompletedOpen_SE_1 { get; set; } /// /// 2号舵机打开完成 /// public bool CompletedOpen_SE_2 { get; set; } /// /// 3号舵机打开完成 /// public bool CompletedOpen_SE_3 { get; set; } /// /// 1号舵机关闭完成 /// public bool CompletedClose_SE_1 { get; set; } /// /// 2号舵机关闭完成 /// public bool CompletedClose_SE_2 { get; set; } /// /// 3号舵机关闭完成 /// public bool CompletedClose_SE_3 { get; set; } /// /// 是否存在物品 /// public bool ArticleExits { get; set; } /// /// 物品距离 /// public byte ArticleDist { get; set; } #endregion public ICChipMachine() { } /// /// 主线程开始运行 /// public override void Start() { try { commProxy.Start(); IsConnected = true; MainLoop(); } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } } /// /// 停止运行 /// public override void Stop() { try { commProxy.Stop(); IsConnected = false; } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } } /// /// 主循环,循环询问状态 /// private void MainLoop() { TaskManage.GetInstance.StartLong(new Action(() => { ResolveMsg(); }), "单片机解析线程"); } private void ResolveMsg() { List temp = new List(); //一系列解包 while (dataStorage.GetSize() > 0) { byte item = dataStorage.GetData(); if (item == 0xAA) { temp.Add(item); while (dataStorage.GetSize() < 4) { Thread.Sleep(5); } while (temp.Count < 5) { temp.Add(dataStorage.GetData()); } if (temp[4] == 0xBB) { var package = ByteToStructure(temp.ToArray()); ProcessMsg(package); } temp.Clear(); } continue; } Thread.Sleep(10); } /// /// 由byte数组转换为结构体 /// private ICChipPackage ByteToStructure(byte[] dataBuffer) { ICChipPackage structure = new ICChipPackage(); int size = Marshal.SizeOf(typeof(ICChipPackage)); IntPtr allocIntPtr = Marshal.AllocHGlobal(size); try { Marshal.Copy(dataBuffer, 0, allocIntPtr, size); structure = (ICChipPackage)Marshal.PtrToStructure(allocIntPtr, typeof(ICChipPackage)); } finally { Marshal.FreeHGlobal(allocIntPtr); } return structure; } private byte[] StructureToByte(ICChipPackage structure) { structure.Header = 0xAA; structure.Sender = IC_SENDER.CONSOLE; structure.End = 0xBB; int size = Marshal.SizeOf(typeof(ICChipPackage)); byte[] buffer = new byte[size]; IntPtr bufferIntPtr = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr(structure, bufferIntPtr, true); Marshal.Copy(bufferIntPtr, buffer, 0, size); } finally { Marshal.FreeHGlobal(bufferIntPtr); } return buffer; } public void ProcessMsg(ICChipPackage data) { try { switch (data.Cmd) { case IC_CMD.HEART_BEAT: lastRefreshTime = DateTime.Now; status["SCChipIsConnect"] = OnLine; break; case IC_CMD.TAKE_CUP: switch ((IC_CUP)data.Value) { case IC_CUP.CUP_COFFEE: status["CompletedTake_CPU_CUP_COFFEE"] = true; break; case IC_CUP.CUP_ICECREAM: status["CompletedTake_CPU_CUP_ICECREAM"] = true; break; } break; case IC_CMD.OPEN_SE: switch ((IC_SE)data.Value) { case IC_SE.SE_1: CompletedOpen_SE_1 = true; break; case IC_SE.SE_2: CompletedOpen_SE_2 = true; break; case IC_SE.SE_3: CompletedOpen_SE_3 = true; break; } break; case IC_CMD.CLOSE_SE: switch ((IC_SE)data.Value) { case IC_SE.SE_1: CompletedClose_SE_1 = true; break; case IC_SE.SE_2: CompletedClose_SE_2 = true; break; case IC_SE.SE_3: CompletedClose_SE_3 = true; break; } break; } if (!OnLine) IsWork = false; else IsWork = true; } catch (Exception ex) { } } protected override void InitStatus() { status["CompletedTake_CPU_CUP_ICECREAM"] = false; status["CompletedTake_CPU_CUP_COFFEE"] = false; //status["CompletedOpen_SE_1"] = false; //status["CompletedOpen_SE_2"] = false; //status["CompletedOpen_SE_3"] = false; //status["CompletedClose_SE_1"] = false; //status["CompletedClose_SE_2"] = false; //status["CompletedClose_SE_3"] = false; } public override void Init() { commProxy = new SerialPortClient(communicationPar.SerialPort, (BaudRates)communicationPar.BaudRate); commProxy.SetDataStorage(dataStorage); //STM32F103RCT6单片机下杯 EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { try { switch ((@event as SCChip_TakeCupEvent).Cup) { case IC_CUP.CUP_ICECREAM: status["CompletedTake_CPU_CUP_ICECREAM"] = false; break; case IC_CUP.CUP_COFFEE: status["CompletedTake_CPU_CUP_COFFEE"] = false; break; } package.Cmd = IC_CMD.TAKE_CUP; package.Value = (byte)(@event as SCChip_TakeCupEvent).Cup; commProxy.SendData(StructureToByte(package)); MessageLog.GetInstance.Show($"发送落杯指令--{(@event as SCChip_TakeCupEvent).Cup}"); bool wait = true; var waitTimeout = DateTime.Now.AddSeconds(3); while (wait) { wait = DateTime.Now < waitTimeout; if (wait) { switch ((@event as SCChip_TakeCupEvent).Cup) { case IC_CUP.CUP_ICECREAM: wait = !(bool)status["CompletedTake_CPU_CUP_ICECREAM"]; break; case IC_CUP.CUP_COFFEE: wait = !(bool)status["CompletedTake_CPU_CUP_COFFEE"]; break; } } Thread.Sleep(10); } } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } }); //STM32F103RCT6单片机舵机打料 EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { try { switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine) { case IC_SE.SE_1: CompletedOpen_SE_1 = false; break; case IC_SE.SE_2: CompletedOpen_SE_2 = false; break; case IC_SE.SE_3: CompletedOpen_SE_3 = false; break; } package.Cmd = IC_CMD.OPEN_SE; package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine; commProxy.SendData(StructureToByte(package)); bool wait = true; DateTime waitTimeout = DateTime.Now.AddSeconds(3); while (wait) { wait = DateTime.Now < waitTimeout; if (wait) { switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine) { case IC_SE.SE_1: wait = !CompletedOpen_SE_1; break; case IC_SE.SE_2: wait = !CompletedOpen_SE_2; break; case IC_SE.SE_3: wait = !CompletedOpen_SE_3; break; } } Thread.Sleep(10); } Thread.Sleep(1800); switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine) { case IC_SE.SE_1: CompletedClose_SE_1 = false; break; case IC_SE.SE_2: CompletedClose_SE_2 = false; break; case IC_SE.SE_3: CompletedClose_SE_3 = false; break; } package.Cmd = IC_CMD.CLOSE_SE; package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine; commProxy.SendData(StructureToByte(package)); wait = true; waitTimeout = DateTime.Now.AddSeconds(3); while (wait) { wait = DateTime.Now < waitTimeout; if (wait) { switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine) { case IC_SE.SE_1: wait = !CompletedClose_SE_1; break; case IC_SE.SE_2: wait = !CompletedClose_SE_2; break; case IC_SE.SE_3: wait = !CompletedClose_SE_3; break; } } Thread.Sleep(10); } } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } }); //STM32F103RCT6单片机舵机打开或者关闭 EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { try { package.Cmd = (@event as SCChip_SESwitchCreamEvent).IsOpen ? IC_CMD.OPEN_SE : IC_CMD.CLOSE_SE; package.Value = (byte)(@event as SCChip_SESwitchCreamEvent).SteeringEngine; commProxy.SendData(StructureToByte(package)); } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } }); //STM32F103RCT6单片机控制冰淇淋机器转 EventBus.GetInstance.Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { try { package.Cmd = IC_CMD.ROTOR; package.Value = (@event as SCChip_RotorSwitchEvent).TurnOn ? (byte)IC_ROTOR.OPEN_ROTOR : (byte)IC_ROTOR.CLOSE_ROTOR; commProxy.SendData(StructureToByte(package)); } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } }); InitStatus(); //测试 Start(); } public override void WriteData(string address, object value) { } } }