using BPASmartClient.EventBus; using BPASmartClient.Helper; using BPASmartClient.Message; 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 BPASmartClient.EventBus.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; } } 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() { ThreadManage.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(5); } /// /// 由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["OnLine"] = 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: status["CompletedOpen_SE_1"] = true; break; case IC_SE.SE_2: status["CompletedOpen_SE_2"] = true; break; case IC_SE.SE_3: status["CompletedOpen_SE_3"] = true; break; } break; case IC_CMD.CLOSE_SE: switch ((IC_SE)data.Value) { case IC_SE.SE_1: status["CompletedClose_SE_1"] = true; break; case IC_SE.SE_2: status["CompletedClose_SE_2"] = true; break; case IC_SE.SE_3: status["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(PortName,(BaudRates)Enum.Parse(typeof(BaudRates),BaudRate)); commProxy.SetDataStorage(dataStorage); //STM32F103RCT6单片机下杯 EventBus.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)); 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.EventBus.GetInstance().Subscribe(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack) { try { switch ((IC_SE)(@event as SCChip_MakeIceCreamEvent).SteeringEngine) { case IC_SE.SE_1: status["CompletedOpen_SE_1"] = false; break; case IC_SE.SE_2: status["CompletedOpen_SE_2"] = false; break; case IC_SE.SE_3: status["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 = !(bool)status["CompletedOpen_SE_1"]; break; case IC_SE.SE_2: wait = !(bool)status["CompletedOpen_SE_2"]; break; case IC_SE.SE_3: wait = !(bool)status["CompletedOpen_SE_3"]; break; } } Thread.Sleep(10); } Thread.Sleep(2000); 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 = !(bool)status["CompletedClose_SE_1"]; break; case IC_SE.SE_2: wait = !(bool)status["CompletedClose_SE_2"]; break; case IC_SE.SE_3: wait = !(bool)status["CompletedClose_SE_3"]; break; } } Thread.Sleep(10); } } catch (Exception ex) { MessageLog.GetInstance.ShowEx($"BPASmartClient.SCChip 中引发错误,ICChipMachine 类,描述:[{ex.Message}]"); } }); //STM32F103RCT6单片机舵机打开或者关闭 EventBus.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.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(); } } }