Browse Source

fixed Serial port

master
Z 5 months ago
parent
commit
c24ef29a9b
  1. 18
      Example/Gateway/Script/View/ViewModbusGateway.cs
  2. 73
      addons/EGFramework/Module/ProtocolTools/EGModbus.cs
  3. 32
      addons/EGFramework/Module/ProtocolTools/EGSerialPort.cs

18
Example/Gateway/Script/View/ViewModbusGateway.cs

@ -17,8 +17,9 @@ namespace EGFramework.Examples.Gateway{
ReadTest2(); ReadTest2();
ReadTest3(); ReadTest3();
ReadTest3(); ReadTest3();
ReadTest2(); // ReadTest2();
ReadTest(); // ReadTest();
WriteTest1();
} }
// Called every frame. 'delta' is the elapsed time since the previous frame. // Called every frame. 'delta' is the elapsed time since the previous frame.
@ -76,6 +77,19 @@ namespace EGFramework.Examples.Gateway{
GD.Print("Timeout!"); 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!");
}
}
} }
} }

73
addons/EGFramework/Module/ProtocolTools/EGModbus.cs

@ -35,15 +35,15 @@ namespace EGFramework{
this.EGOnMessage<ModbusTCP_Response>(); this.EGOnMessage<ModbusTCP_Response>();
} }
public bool IsReadingRTU { set; get; } private bool IsRequestRTU { set; get; }
public async Task<ModbusRTU_Response?> ReadRTUAsync(ModbusRegisterType registerType,string serialPort,byte deviceAddress,ushort start,ushort count){ public async Task<ModbusRTU_Response?> ReadRTUAsync(ModbusRegisterType registerType,string serialPort,byte deviceAddress,ushort start,ushort count){
if(IsReadingRTU){ if(IsRequestRTU){
SendPointerRTU++; SendPointerRTU++;
int messageId = SendPointerRTU; int messageId = SendPointerRTU;
WaitForSendRTU.Enqueue(messageId); WaitForSendRTU.Enqueue(messageId);
await Task.Run(async () => await Task.Run(async () =>
{ {
while (IsReadingRTU || NextSendRTU != messageId) while (IsRequestRTU || NextSendRTU != messageId)
{ {
await Task.Delay(10); await Task.Delay(10);
//break; //break;
@ -53,7 +53,7 @@ namespace EGFramework{
//return null; //return null;
} }
RTUCache.Clear(); RTUCache.Clear();
IsReadingRTU = true; IsRequestRTU = true;
IRequest ReadRequest; IRequest ReadRequest;
ModbusRTU_Response? res = null; ModbusRTU_Response? res = null;
switch(registerType){ switch(registerType){
@ -76,22 +76,73 @@ namespace EGFramework{
}else{ }else{
//Print Error Timeout //Print Error Timeout
OnReadTimeOut.Invoke(); OnReadTimeOut.Invoke();
this.EGSerialPort().ClearBuffer(serialPort);
} }
}); });
IsReadingRTU = false; this.EGSerialPort().ClearReceivedCache(serialPort);
IsRequestRTU = false;
if(this.WaitForSendRTU.Count>0){ if(this.WaitForSendRTU.Count>0){
NextSendRTU = this.WaitForSendRTU.Dequeue(); NextSendRTU = this.WaitForSendRTU.Dequeue();
} }
return res; return res;
} }
public bool IsReadingTCP { set; get; } public async Task<ModbusRTU_Response?> 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<ModbusTCP_Response?> ReadTCPAsync(ModbusRegisterType registerType,string ipPort,byte deviceAddress,ushort start,ushort count){ public async Task<ModbusTCP_Response?> ReadTCPAsync(ModbusRegisterType registerType,string ipPort,byte deviceAddress,ushort start,ushort count){
if(IsReadingTCP){ if(IsRequestTCP){
await Task.Run(async () => await Task.Run(async () =>
{ {
while (IsReadingTCP) while (IsRequestTCP)
{ {
await Task.Delay(10); await Task.Delay(10);
//break; //break;
@ -100,7 +151,7 @@ namespace EGFramework{
//return null; //return null;
} }
TCPCache.Clear(); TCPCache.Clear();
IsReadingTCP = true; IsRequestTCP = true;
IRequest ReadRequest; IRequest ReadRequest;
ModbusTCP_Response? res = null; ModbusTCP_Response? res = null;
switch(registerType){ switch(registerType){
@ -123,7 +174,7 @@ namespace EGFramework{
OnReadTimeOut.Invoke(); OnReadTimeOut.Invoke();
} }
}); });
IsReadingTCP = false; IsRequestTCP = false;
return res; return res;
} }

32
addons/EGFramework/Module/ProtocolTools/EGSerialPort.cs

@ -23,7 +23,7 @@ namespace EGFramework{
public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>(); public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>();
public byte[] ReceivedCache { set; get; } = new byte[0]; public Dictionary<string,byte[]> ReceivedCache { set; get; } = new Dictionary<string,byte[]>();
public void Init() public void Init()
{ {
@ -77,6 +77,7 @@ namespace EGFramework{
if(!SerialPortDevices.ContainsKey(serialPort)){ if(!SerialPortDevices.ContainsKey(serialPort)){
SerialPort newPort = new SerialPort(serialPort, DefaultBaudRate, Parity.None, 8, StopBits.One); SerialPort newPort = new SerialPort(serialPort, DefaultBaudRate, Parity.None, 8, StopBits.One);
SerialPortDevices.Add(serialPort,newPort); SerialPortDevices.Add(serialPort,newPort);
ReceivedCache.Add(serialPort,new byte[0]);
if (!SerialPortDevices[serialPort].IsOpen) if (!SerialPortDevices[serialPort].IsOpen)
{ {
SerialPortDevices[serialPort].Open(); SerialPortDevices[serialPort].Open();
@ -176,19 +177,19 @@ namespace EGFramework{
int bufferSize = serialPort.BytesToRead; int bufferSize = serialPort.BytesToRead;
byte[] buffer = new byte[bufferSize]; byte[] buffer = new byte[bufferSize];
serialPort.Read(buffer,0,serialPort.BytesToRead); serialPort.Read(buffer,0,serialPort.BytesToRead);
ReceivedCache = ReceivedCache.Concat(buffer).ToArray(); ReceivedCache[serialPort.PortName] = ReceivedCache[serialPort.PortName].Concat(buffer).ToArray();
} }
if(ReceivedCache.Length >= MinDataPackLength){ if(ReceivedCache[serialPort.PortName].Length >= MinDataPackLength){
string str = StringEncoding.GetString(ReceivedCache); string str = StringEncoding.GetString(ReceivedCache[serialPort.PortName]);
Godot.GD.Print("[Receive]"+ReceivedCache.ToStringByHex()); Godot.GD.Print("[Receive]"+ReceivedCache[serialPort.PortName].ToStringByHex());
ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache,serialPort.PortName,ProtocolType.SerialPort)); ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache[serialPort.PortName],serialPort.PortName,ProtocolType.SerialPort));
ReceivedCache = new byte[0]; ReceivedCache[serialPort.PortName] = new byte[0];
MinDataPackLength = 0; MinDataPackLength = 0;
//this.EGOnReceivedData(new ResponseMsg(str,buffer,serialPort.PortName,ProtocolType.SerialPort)); //this.EGOnReceivedData(new ResponseMsg(str,buffer,serialPort.PortName,ProtocolType.SerialPort));
}else{ }else{
Godot.GD.Print("[Data Get]" + ReceivedCache.Length); Godot.GD.Print("[Data Get]" + ReceivedCache[serialPort.PortName].Length);
string str = StringEncoding.GetString(ReceivedCache); string str = StringEncoding.GetString(ReceivedCache[serialPort.PortName]);
ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache,serialPort.PortName,ProtocolType.SerialPort)); ResponseMsgs.Enqueue(new ResponseMsg(str,ReceivedCache[serialPort.PortName],serialPort.PortName,ProtocolType.SerialPort));
} }
} }
@ -196,15 +197,8 @@ namespace EGFramework{
this.MinDataPackLength = leastLength; this.MinDataPackLength = leastLength;
} }
public void ClearBuffer(string serialPort){ public void ClearReceivedCache(string serialPort){
if(SerialPortDevices.ContainsKey(serialPort)){ ReceivedCache[serialPort] = new byte[0];
if (SerialPortDevices[serialPort].IsOpen)
{
SerialPortDevices[serialPort].DiscardInBuffer();
}
}else{
//Not found in SerialPortDevices,need add?
}
} }
public IArchitecture GetArchitecture() public IArchitecture GetArchitecture()

Loading…
Cancel
Save