diff --git a/HBLConsole.MORKIC/Control_MORKIC.cs b/HBLConsole.MORKIC/Control_MORKIC.cs index 34d6d7c..1cb7e21 100644 --- a/HBLConsole.MORKIC/Control_MORKIC.cs +++ b/HBLConsole.MORKIC/Control_MORKIC.cs @@ -17,6 +17,8 @@ using Robotc; using System.Collections.Concurrent; using System.Diagnostics; using BPA.Message.IOT; +using HBLDevice.ICChip; + namespace HBLConsole.MORKIC { /* @@ -33,6 +35,7 @@ namespace HBLConsole.MORKIC GVL_MORIC mORKD = new GVL_MORIC(); //咖啡机主控程序 private CoffeeMachine coffeeMachine; + private ICChipMachine icchipMachine; //冰淇淋主控程序 private IceCreamMachine iceCreamMachine; //物料存放位置 @@ -60,7 +63,6 @@ namespace HBLConsole.MORKIC //构建所有商品物料信息 batchings = PolymerBatching.BuildAll(); - EventBus.GetInstance().Subscribe(IceCreamEndCookHandle); EventBus.GetInstance().Subscribe(CoffeEndCookHandle); System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None); @@ -70,6 +72,11 @@ namespace HBLConsole.MORKIC var com_IceCream = config.AppSettings.Settings["COM_IceCream"].Value; var baud_IceCream = config.AppSettings.Settings["BAUD_IceCream"].Value; var iceCreamCXBThreshold = int.Parse(config.AppSettings.Settings["IceCream_CXB_Threshold"].Value); + + var com_ICChip = config.AppSettings.Settings["COM_ICChip"].Value; + var baud_ICChip = config.AppSettings.Settings["BAUD_IChip"].Value; + + if (iceCreamCXBThreshold > 0) { //设置冰淇淋成型比 @@ -79,6 +86,7 @@ namespace HBLConsole.MORKIC coffeeMachine = new CoffeeMachine(com_Coffee, (BaudRates)Enum.Parse(typeof(BaudRates), baud_Coffee)); //冰淇淋机创建 iceCreamMachine = new IceCreamMachine(com_IceCream, (BaudRates)Enum.Parse(typeof(BaudRates), baud_IceCream)); + icchipMachine = new ICChipMachine(com_ICChip, (BaudRates)Enum.Parse(typeof(BaudRates), baud_ICChip)); Main(); ReadData(); @@ -167,7 +175,7 @@ namespace HBLConsole.MORKIC //订单状态改变:开始制作 SimpleFactory.GetInstance.OrderChanged(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); //todo:先调用机器人 - + ThreadOperate.GetInstance.Start(new Action(() => { LebaiHelper.GetInstance.Scene(10002); }), "调用乐百机器人做咖啡场景"); while (!(lebai.Ok && lebai.Value == 1)) @@ -211,10 +219,9 @@ namespace HBLConsole.MORKIC { Thread.Sleep(5); } - new DischargeEvent().Publish(); - - //冰淇淋没有模式切换,强制等待10s - Thread.Sleep(10000); + new TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish(); + while (!ChipStatus.GetInstance().CompletedTake_CPU_CUP_ICECREAM) { Thread.Sleep(5); } + new MakeIceCreamEvent() { SteeringEngine = IC_SE.SE_1 }.Publish(); LebaiHelper.GetInstance.SetValue(100); //are.WaitOne(100 * 90); //订单状态改变:完成 @@ -226,12 +233,6 @@ namespace HBLConsole.MORKIC are.Set(); } - private void IceCreamEndCookHandle(IEvent @event, EventBus.EventCallBackHandle callBack) - { - //are.Set(); - } - - public void Main() { //咖啡机开启主线程 @@ -250,7 +251,7 @@ namespace HBLConsole.MORKIC // MorkIStatus.GetInstance().CanDo && // MorkCStatus.GetInstance().CanDo; GeneralConfig.Healthy = - LebaiHelper.GetInstance.IsConnected && + LebaiHelper.GetInstance.IsConnected && MorkCStatus.GetInstance().CanDo; Thread.Sleep(100); }), "MORK-IC心跳刷新"); diff --git a/HBLConsole.MORKIC/HBLConsole.MORKIC.csproj b/HBLConsole.MORKIC/HBLConsole.MORKIC.csproj index 3cf5084..a5b0a6c 100644 --- a/HBLConsole.MORKIC/HBLConsole.MORKIC.csproj +++ b/HBLConsole.MORKIC/HBLConsole.MORKIC.csproj @@ -13,6 +13,7 @@ + diff --git a/HBLConsole.sln b/HBLConsole.sln index a641290..9169631 100644 --- a/HBLConsole.sln +++ b/HBLConsole.sln @@ -41,7 +41,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLDevice.Coffee", "HBLDevi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLDevice.IceCream", "HBLDevice.IceCream\HBLDevice.IceCream.csproj", "{6F9FD1DA-D17A-4243-83F3-E24ADC0B8CF7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HBLConsole.Debug", "HBLConsole.Debug\HBLConsole.Debug.csproj", "{8F75DF03-50F7-4ECF-8535-E59E6486B652}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLConsole.Debug", "HBLConsole.Debug\HBLConsole.Debug.csproj", "{8F75DF03-50F7-4ECF-8535-E59E6486B652}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLDevice.ICChip", "HBLDevice.ICChip\HBLDevice.ICChip.csproj", "{4A451647-FB80-4D19-85CF-C04A9548A17E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -125,6 +127,10 @@ Global {8F75DF03-50F7-4ECF-8535-E59E6486B652}.Debug|Any CPU.Build.0 = Debug|Any CPU {8F75DF03-50F7-4ECF-8535-E59E6486B652}.Release|Any CPU.ActiveCfg = Release|Any CPU {8F75DF03-50F7-4ECF-8535-E59E6486B652}.Release|Any CPU.Build.0 = Release|Any CPU + {4A451647-FB80-4D19-85CF-C04A9548A17E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A451647-FB80-4D19-85CF-C04A9548A17E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A451647-FB80-4D19-85CF-C04A9548A17E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A451647-FB80-4D19-85CF-C04A9548A17E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -132,6 +138,7 @@ Global GlobalSection(NestedProjects) = preSolution {1E33FFE0-3B82-47F9-9E48-6FC870F36FF0} = {CFF94828-163A-4907-B951-081B18F3CBBD} {6F9FD1DA-D17A-4243-83F3-E24ADC0B8CF7} = {CFF94828-163A-4907-B951-081B18F3CBBD} + {4A451647-FB80-4D19-85CF-C04A9548A17E} = {CFF94828-163A-4907-B951-081B18F3CBBD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1968105D-1913-4F0B-A03E-7C18AFA58912} diff --git a/HBLConsole/App.config b/HBLConsole/App.config index ff71d3e..0738d6e 100644 --- a/HBLConsole/App.config +++ b/HBLConsole/App.config @@ -24,6 +24,8 @@ + + \ No newline at end of file diff --git a/HBLDevice.ICChip/ChipStatus.cs b/HBLDevice.ICChip/ChipStatus.cs new file mode 100644 index 0000000..2c9c07a --- /dev/null +++ b/HBLDevice.ICChip/ChipStatus.cs @@ -0,0 +1,116 @@ +using BPA.Utility; +using HBLConsole.Service; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + public class ChipStatus : Singleton + { + private DateTime lastRefreshTime = DateTime.MinValue; + /// + /// 是否在线 + /// + public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } + /// + /// 取冰淇淋杯完成 + /// + public bool CompletedTake_CPU_CUP_ICECREAM { get; set; } + /// + /// 取咖啡杯完成 + /// + public bool CompletedTake_CPU_CUP_COFFEE { get; set; } + /// + /// 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 CanDo + { + get + { + if (!OnLine) + return false; + return true; + } + } + + public void ProcessMsg(ICChipPackage data) + { + try + { + switch (data.Cmd) + { + case IC_CMD.HEART_BEAT: + lastRefreshTime = DateTime.Now; + break; + case IC_CMD.TAKE_CUP: + switch ((IC_CUP)data.Value) { + case IC_CUP.CUP_COFFEE: + CompletedTake_CPU_CUP_COFFEE = true; + break; + case IC_CUP.CUP_ICECREAM: + 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; + } + } + catch (Exception ex) + { + + } + } + } +} diff --git a/HBLDevice.ICChip/CommandEvent.cs b/HBLDevice.ICChip/CommandEvent.cs new file mode 100644 index 0000000..12243b3 --- /dev/null +++ b/HBLDevice.ICChip/CommandEvent.cs @@ -0,0 +1,22 @@ +using BPA.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + public class TakeCupEvent : IEvent + { + /// + /// 杯 + /// + public IC_CUP Cup { get; set; } + } + + public class MakeIceCreamEvent : IEvent + { + public IC_SE SteeringEngine { get; set; } + } +} diff --git a/HBLDevice.ICChip/CommandHandler.cs b/HBLDevice.ICChip/CommandHandler.cs new file mode 100644 index 0000000..3b2ad99 --- /dev/null +++ b/HBLDevice.ICChip/CommandHandler.cs @@ -0,0 +1,149 @@ +using BPA.Utility; +using HBLConsole.Communication; +using HBLConsole.Service; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using static BPA.Utility.EventBus; + +namespace HBLDevice.ICChip +{ + /// + /// 指令封装 + /// + internal class CommandHandler + { + private SerialPortClient commProxy; + private ICChipPackage package = new ICChipPackage(); + + /// + /// 初始化 + /// + internal void Init(SerialPortClient commProxy) + { + this.commProxy = commProxy; + EventBus.GetInstance().Subscribe(TakeCupEventHandle); + EventBus.GetInstance().Subscribe(MakeIceCreamEventHandle); + } + + private void MakeIceCreamEventHandle(IEvent @event, EventCallBackHandle callBack) + { + switch ((@event as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + ChipStatus.GetInstance().CompletedOpen_SE_1 = false; + break; + case IC_SE.SE_2: + ChipStatus.GetInstance().CompletedOpen_SE_2 = false; + break; + case IC_SE.SE_3: + ChipStatus.GetInstance().CompletedOpen_SE_3 = false; + break; + } + package.Cmd = IC_CMD.OPEN_SE; + package.Value = (byte)(@event as MakeIceCreamEvent).SteeringEngine; + commProxy.SendData(StructureToByte(package)); + + Thread.Sleep(500); + + DateTime timeOut = DateTime.Now.AddSeconds(3); + bool loop = true; + while (loop) + { + loop = DateTime.Now < timeOut; + switch ((@event as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + loop = !ChipStatus.GetInstance().CompletedOpen_SE_1; + break; + case IC_SE.SE_2: + loop = !ChipStatus.GetInstance().CompletedOpen_SE_2; + break; + case IC_SE.SE_3: + loop = !ChipStatus.GetInstance().CompletedOpen_SE_3; + break; + } + } + + switch ((@event as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + ChipStatus.GetInstance().CompletedClose_SE_1 = false; + break; + case IC_SE.SE_2: + ChipStatus.GetInstance().CompletedClose_SE_2 = false; + break; + case IC_SE.SE_3: + ChipStatus.GetInstance().CompletedClose_SE_3 = false; + break; + } + package.Cmd = IC_CMD.CLOSE_SE; + package.Value = (byte)(@event as MakeIceCreamEvent).SteeringEngine; + commProxy.SendData(StructureToByte(package)); + + Thread.Sleep(500); + + timeOut = DateTime.Now.AddSeconds(3); + loop = true; + while (loop) + { + loop = DateTime.Now < timeOut; + switch ((@event as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + loop = !ChipStatus.GetInstance().CompletedClose_SE_1; + break; + case IC_SE.SE_2: + loop = !ChipStatus.GetInstance().CompletedClose_SE_2; + break; + case IC_SE.SE_3: + loop = !ChipStatus.GetInstance().CompletedClose_SE_3; + break; + } + } + } + + private void TakeCupEventHandle(IEvent @event, EventCallBackHandle callBack) + { + switch ((@event as TakeCupEvent).Cup) + { + case IC_CUP.CUP_ICECREAM: + ChipStatus.GetInstance().CompletedTake_CPU_CUP_ICECREAM = false; + break; + case IC_CUP.CUP_COFFEE: + ChipStatus.GetInstance().CompletedTake_CPU_CUP_COFFEE = false; + break; + } + package.Cmd = IC_CMD.TAKE_CUP; + package.Value = (byte)(@event as TakeCupEvent).Cup; + commProxy.SendData(StructureToByte(package)); + } + + + private byte[] StructureToByte(ICChipPackage structure) + { + structure.Header = 0xAA; + 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; + } + + + } +} diff --git a/HBLDevice.ICChip/HBLDevice.ICChip.csproj b/HBLDevice.ICChip/HBLDevice.ICChip.csproj new file mode 100644 index 0000000..d0fb844 --- /dev/null +++ b/HBLDevice.ICChip/HBLDevice.ICChip.csproj @@ -0,0 +1,17 @@ + + + + net5.0 + + + + + + + + + ..\..\..\BPACommon_output\net5.0\BPA.Utility.dll + + + + diff --git a/HBLDevice.ICChip/ICChipMachine.cs b/HBLDevice.ICChip/ICChipMachine.cs new file mode 100644 index 0000000..db620d9 --- /dev/null +++ b/HBLDevice.ICChip/ICChipMachine.cs @@ -0,0 +1,102 @@ +using HBLConsole.Communication; +using HBLConsole.Model; +using HBLConsole.Service; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; + +namespace HBLDevice.ICChip +{ + public class ICChipMachine + { + //指令组装 + private CommandHandler commandHandler = new CommandHandler(); + //通讯代理 + SerialPortClient commProxy = null; + //数据仓库 + private DataStorage dataStorage = new DataStorage(); + //主线程运行标识 + private bool running = false; + //是否下发指令,主线程等待 + public Action SendCallback; + public Action ReciveCallback; + + + + public ICChipMachine(string portName, BaudRates baud) + { + commProxy = new SerialPortClient(portName, baud); + commProxy.SetDataStorage(dataStorage); + commandHandler.Init(commProxy); + } + + public void Start() + { + commProxy.Start(); + running = true; + MainLoop(); + } + + public void Stop() + { + } + + private void MainLoop() + { + ThreadOperate.GetInstance.StartLong(new Action(() => + { + ResolveMsg(); + //Thread.Sleep(2000); + }), "冰淇淋解析线程"); + } + int contentLength = 0; + int currentContentOffset = 0; + private void ResolveMsg() + { + List temp = new List(); + //一系列解包 + while (dataStorage.GetSize() > 0) + { + byte item = dataStorage.GetData(); + if (item == 0xAA) + { + while (dataStorage.GetSize() < 4) { Thread.Sleep(5); } + while (temp.Count < 5) + { + temp.Add(dataStorage.GetData()); + } + if (temp[4] == 0xBB) + { + var package = ByteToStructure(temp.ToArray()); + ChipStatus.GetInstance().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; + } + } + +} diff --git a/HBLDevice.ICChip/Protocal/ICChipPackage.cs b/HBLDevice.ICChip/Protocal/ICChipPackage.cs new file mode 100644 index 0000000..3b23094 --- /dev/null +++ b/HBLDevice.ICChip/Protocal/ICChipPackage.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + /// + /// Dr咖啡机基础协议 + /// + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public struct ICChipPackage + { + /// + /// 包头(固定0xAA) + /// + public byte Header; + /// + /// 发送方 + /// + public IC_SENDER Sender; + /// + /// 命令 + /// + public IC_CMD Cmd; + /// + /// 故障(咖啡机负责写,工控机负责读) + /// + public byte Value; + /// + /// 包尾(固定为0xBB) + /// + public byte End; + } +} diff --git a/HBLDevice.ICChip/Protocal/IC_CMD.cs b/HBLDevice.ICChip/Protocal/IC_CMD.cs new file mode 100644 index 0000000..776ed96 --- /dev/null +++ b/HBLDevice.ICChip/Protocal/IC_CMD.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + /// + /// 命令 + /// + public enum IC_CMD:byte + { + /// + /// 心跳 + /// + HEART_BEAT=0x00, + /// + /// 下杯(带上碗参数) + /// + TAKE_CUP=0x01, + /// + /// 打开舵机(带上舵机参数) + /// + OPEN_SE=0x02, + /// + /// 关闭舵机(带上舵机参数) + /// + CLOSE_SE = 0x03, + /// + /// 使能冰淇淋转子(带上开关参数) + /// + ROTOR=0x04, + } +} diff --git a/HBLDevice.ICChip/Protocal/IC_CUP.cs b/HBLDevice.ICChip/Protocal/IC_CUP.cs new file mode 100644 index 0000000..0ecd012 --- /dev/null +++ b/HBLDevice.ICChip/Protocal/IC_CUP.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + /// + /// 杯子 + /// + public enum IC_CUP : byte + { + /// + /// 冰淇淋杯 + /// + CUP_ICECREAM = 0x01, + /// + /// 咖啡杯 + /// + CUP_COFFEE = 0x02 + } +} diff --git a/HBLDevice.ICChip/Protocal/IC_SE.cs b/HBLDevice.ICChip/Protocal/IC_SE.cs new file mode 100644 index 0000000..efbdc94 --- /dev/null +++ b/HBLDevice.ICChip/Protocal/IC_SE.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + /// + /// 冰淇淋舵机 + /// + public enum IC_SE:byte + { + /// + /// 舵机1 + /// + SE_1=0x01, + /// + /// 舵机2 + /// + SE_2=0x02, + /// + /// 舵机3 + /// + SE_3=0x03, + } +} diff --git a/HBLDevice.ICChip/Protocal/IC_SENDER.cs b/HBLDevice.ICChip/Protocal/IC_SENDER.cs new file mode 100644 index 0000000..6919a5e --- /dev/null +++ b/HBLDevice.ICChip/Protocal/IC_SENDER.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.ICChip +{ + /// + /// 命令发送方 + /// + public enum IC_SENDER:byte + { + /// + /// 上位机 + /// + CONSOLE=0x01, + /// + /// 单片机 + /// + DEVICE=0x02, + } +} diff --git a/HBLDevice.IceCreamV1/HBLDevice.ICChip.csproj b/HBLDevice.IceCreamV1/HBLDevice.ICChip.csproj new file mode 100644 index 0000000..d0fb844 --- /dev/null +++ b/HBLDevice.IceCreamV1/HBLDevice.ICChip.csproj @@ -0,0 +1,17 @@ + + + + net5.0 + + + + + + + + + ..\..\..\BPACommon_output\net5.0\BPA.Utility.dll + + + +