Faced a problem. I need to poll the device by serial port using the Modbus protocol.
But polling the device takes a long time - about 2 seconds.
True, my program still additionally constantly polls devices in a separate thread, but I wanted it to be faster.
Maybe someone can help me how to optimize my code. I would be very grateful.
public override RcResult ExecuteModBus(RcModBusDevice device, byte[] request, out byte[] answer)
{
answer = null;
var result = new RcResult();
OnLogMessage?.Invoke(this, "ExecuteModBus LOCK?");
lock (communication)
{
OnLogMessage?.Invoke(this, "ExecuteModBus LOCK!");
var dt = DateTime.Now;
if (device != null)
{
serialPort.WriteTimeout = device.SendTimeout;
serialPort.ReadTimeout = device.ReceiveTimeout;
}
serialPort.DiscardOutBuffer();
serialPort.DiscardInBuffer();
OnLogMessage?.Invoke(this, "REQUEST->:" + Utils.BytesToHex(request));
try
{
serialPort.Write(request, 0, request.Length);
}
catch(Exception ex)
{
result.ErrorCode = 1;
result.ErrorText = ex.Message;
return result;
}
var tmp = new byte[0x2000];
int dataLength = 0;
try
{
for (int i = 0; i < tmp.Length; i++)
tmp[dataLength++] = (byte)serialPort.ReadByte();
}
catch (Exception ex)
{
}
var crc = Utils.GetCRC(tmp, 0, dataLength - 2);
if (crc[0] != tmp[dataLength - 2] || crc[1] != tmp[dataLength - 1])
{
result.ErrorCode = 1;
result.ErrorText = "Bad CRC";
}
answer = new byte[dataLength];
Array.Copy(tmp, 0, answer, 0, dataLength);
OnLogMessage?.Invoke(this, "ANSWER<-:" + Utils.BytesToHex(answer));
if (device != null)
SaveToLog(DbID, device.DbID, dt, Utils.BytesToHex(request), DateTime.Now, Utils.BytesToHex(answer));
if (dataLength == 0)
result.ErrorCode = 1;
}
OnLogMessage?.Invoke(this, "ExecuteModBus UNLOCK");
return result;
}
19200
.This is what my program displays:Request: 07.04.2020 12:51.48.038 01 03 04 00 00 03 04 FB Answer: 07.04.2020 12:51.49.949 (1,911 seconds) 01 03 06 51 47 07 12 20 84 20 29 00
– Aleksey Malashenkovfor (int i = 0; i < tmp.Length; i++)
loop will exit as soon as the data is received. Try setting the buffer size to 11 (3 byte header; the 3rd byte indicating the number of bytes following - 6 in this case + 2 bytes for the CRC) - this will only work for the specific example query in your comment!. Note that this is a guess; at 19200, with an 11 byte payload, I would expect a faster response but some devices are quite slow. – Brits