diff --git a/Example/Gateway/Script/View/ViewModbusGateway.cs b/Example/Gateway/Script/View/ViewModbusGateway.cs index 8bab602..c6d5600 100644 --- a/Example/Gateway/Script/View/ViewModbusGateway.cs +++ b/Example/Gateway/Script/View/ViewModbusGateway.cs @@ -17,8 +17,9 @@ namespace EGFramework.Examples.Gateway{ ReadTest2(); ReadTest3(); ReadTest3(); - ReadTest2(); - ReadTest(); + // ReadTest2(); + // ReadTest(); + WriteTest1(); } // Called every frame. 'delta' is the elapsed time since the previous frame. @@ -76,6 +77,19 @@ namespace EGFramework.Examples.Gateway{ GD.Print("Timeout!"); } } + + public async void WriteTest1(){ + ModbusRTU_Response? result = await this.EGModbus().WriteOnceRTUAsync(ModbusRegisterType.HoldingRegister,"COM4",0x01,0x2000,0x50); + if(result != null){ + if(!((ModbusRTU_Response)result).IsError){ + GD.Print("Write[0]"+((ModbusRTU_Response)result).FunctionType); + }else{ + GD.Print("Error:"+((ModbusRTU_Response)result).ErrorCode); + } + }else{ + GD.Print("Timeout!"); + } + } } } diff --git a/addons/EGFramework/Module/ProtocolTools/EGModbus.cs b/addons/EGFramework/Module/ProtocolTools/EGModbus.cs index abf7d98..c9c4fc7 100644 --- a/addons/EGFramework/Module/ProtocolTools/EGModbus.cs +++ b/addons/EGFramework/Module/ProtocolTools/EGModbus.cs @@ -35,15 +35,15 @@ namespace EGFramework{ this.EGOnMessage(); } - public bool IsReadingRTU { set; get; } + private bool IsRequestRTU { set; get; } public async Task ReadRTUAsync(ModbusRegisterType registerType,string serialPort,byte deviceAddress,ushort start,ushort count){ - if(IsReadingRTU){ + if(IsRequestRTU){ SendPointerRTU++; int messageId = SendPointerRTU; WaitForSendRTU.Enqueue(messageId); await Task.Run(async () => { - while (IsReadingRTU || NextSendRTU != messageId) + while (IsRequestRTU || NextSendRTU != messageId) { await Task.Delay(10); //break; @@ -53,7 +53,7 @@ namespace EGFramework{ //return null; } RTUCache.Clear(); - IsReadingRTU = true; + IsRequestRTU = true; IRequest ReadRequest; ModbusRTU_Response? res = null; switch(registerType){ @@ -76,22 +76,73 @@ namespace EGFramework{ }else{ //Print Error Timeout OnReadTimeOut.Invoke(); - this.EGSerialPort().ClearBuffer(serialPort); } }); - IsReadingRTU = false; + this.EGSerialPort().ClearReceivedCache(serialPort); + IsRequestRTU = false; if(this.WaitForSendRTU.Count>0){ NextSendRTU = this.WaitForSendRTU.Dequeue(); } return res; } - public bool IsReadingTCP { set; get; } + public async Task WriteOnceRTUAsync(ModbusRegisterType registerType,string serialPort,byte deviceAddress,ushort registerAddress,ushort value){ + if(IsRequestRTU){ + SendPointerRTU++; + int messageId = SendPointerRTU; + WaitForSendRTU.Enqueue(messageId); + await Task.Run(async () => + { + while (IsRequestRTU || NextSendRTU != messageId) + { + await Task.Delay(10); + //break; + } + }); + GD.Print("-----Write"+messageId+" ----"); + //return null; + } + RTUCache.Clear(); + IsRequestRTU = true; + IRequest ReadRequest; + ModbusRTU_Response? res = null; + switch(registerType){ + case ModbusRegisterType.HoldingRegister: + ReadRequest = new ModbusRTU_WriteSingleHoldingRegister(deviceAddress,registerAddress,value); + // this.AppendMessage("【发送-"+DataModbusItem.SerialPort+"】 "+ReadRequest.ToProtocolByteData().ToStringByHex()); + this.EGSendMessage(ReadRequest,serialPort,ProtocolType.SerialPort); + // this.EGSerialPort().SetExpectReceivedDataLength(5+count*2); + this.EGSerialPort().SetExpectReceivedDataLength(ReadRequest.ToProtocolByteData().Length); + break; + } + await Task.Run(async ()=>{ + int timeout = 0; + while(RTUCache.Count==0 && timeout < Delay){ + await Task.Delay(10); + timeout+=10; + } + if(RTUCache.Count>0){ + res = RTUCache.Dequeue(); + }else{ + //Print Error Timeout + OnReadTimeOut.Invoke(); + } + }); + this.EGSerialPort().ClearReceivedCache(serialPort); + IsRequestRTU = false; + if(this.WaitForSendRTU.Count>0){ + NextSendRTU = this.WaitForSendRTU.Dequeue(); + } + return res; + } + + + private bool IsRequestTCP { set; get; } public async Task ReadTCPAsync(ModbusRegisterType registerType,string ipPort,byte deviceAddress,ushort start,ushort count){ - if(IsReadingTCP){ + if(IsRequestTCP){ await Task.Run(async () => { - while (IsReadingTCP) + while (IsRequestTCP) { await Task.Delay(10); //break; @@ -100,7 +151,7 @@ namespace EGFramework{ //return null; } TCPCache.Clear(); - IsReadingTCP = true; + IsRequestTCP = true; IRequest ReadRequest; ModbusTCP_Response? res = null; switch(registerType){ @@ -123,7 +174,7 @@ namespace EGFramework{ OnReadTimeOut.Invoke(); } }); - IsReadingTCP = false; + IsRequestTCP = false; return res; } diff --git a/addons/EGFramework/Module/ProtocolTools/EGSerialPort.cs b/addons/EGFramework/Module/ProtocolTools/EGSerialPort.cs index 21db30a..0a9e8d1 100644 --- a/addons/EGFramework/Module/ProtocolTools/EGSerialPort.cs +++ b/addons/EGFramework/Module/ProtocolTools/EGSerialPort.cs @@ -23,7 +23,7 @@ namespace EGFramework{ public Queue ResponseMsgs { set; get; } = new Queue(); - public byte[] ReceivedCache { set; get; } = new byte[0]; + public Dictionary ReceivedCache { set; get; } = new Dictionary(); public void Init() { @@ -77,6 +77,7 @@ namespace EGFramework{ if(!SerialPortDevices.ContainsKey(serialPort)){ SerialPort newPort = new SerialPort(serialPort, DefaultBaudRate, Parity.None, 8, StopBits.One); SerialPortDevices.Add(serialPort,newPort); + ReceivedCache.Add(serialPort,new byte[0]); if (!SerialPortDevices[serialPort].IsOpen) { SerialPortDevices[serialPort].Open(); @@ -176,19 +177,19 @@ namespace EGFramework{ int bufferSize = serialPort.BytesToRead; byte[] buffer = new byte[bufferSize]; serialPort.Read(buffer,0,serialPort.BytesToRead); - ReceivedCache = ReceivedCache.Concat(buffer).ToArray(); + ReceivedCache[serialPort.PortName] = ReceivedCache[serialPort.PortName].Concat(buffer).ToArray(); } - if(ReceivedCache.Length >= MinDataPackLength){ - string str = StringEncoding.GetString(ReceivedCache); - Godot.GD.Print("[Receive]"+ReceivedCache.ToStringByHex()); - ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache,serialPort.PortName,ProtocolType.SerialPort)); - ReceivedCache = new byte[0]; + if(ReceivedCache[serialPort.PortName].Length >= MinDataPackLength){ + string str = StringEncoding.GetString(ReceivedCache[serialPort.PortName]); + Godot.GD.Print("[Receive]"+ReceivedCache[serialPort.PortName].ToStringByHex()); + ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache[serialPort.PortName],serialPort.PortName,ProtocolType.SerialPort)); + ReceivedCache[serialPort.PortName] = new byte[0]; MinDataPackLength = 0; //this.EGOnReceivedData(new ResponseMsg(str,buffer,serialPort.PortName,ProtocolType.SerialPort)); }else{ - Godot.GD.Print("[Data Get]" + ReceivedCache.Length); - string str = StringEncoding.GetString(ReceivedCache); - ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache,serialPort.PortName,ProtocolType.SerialPort)); + Godot.GD.Print("[Data Get]" + ReceivedCache[serialPort.PortName].Length); + string str = StringEncoding.GetString(ReceivedCache[serialPort.PortName]); + ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache[serialPort.PortName],serialPort.PortName,ProtocolType.SerialPort)); } } @@ -196,15 +197,8 @@ namespace EGFramework{ this.MinDataPackLength = leastLength; } - public void ClearBuffer(string serialPort){ - if(SerialPortDevices.ContainsKey(serialPort)){ - if (SerialPortDevices[serialPort].IsOpen) - { - SerialPortDevices[serialPort].DiscardInBuffer(); - } - }else{ - //Not found in SerialPortDevices,need add? - } + public void ClearReceivedCache(string serialPort){ + ReceivedCache[serialPort] = new byte[0]; } public IArchitecture GetArchitecture()