Click here to Skip to main content
15,868,026 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I tried to poll the device using the Modbus protocol for TCP/IP, and it works well, but there are problems.
If I run this code on a weak computer, the response time will increase and very much...

The difference in polling speed is about 6 seconds.
0x01AA helped me here, there were problems with polling by serial port, but I can’t understand how computer performance affects polling ...

What I have tried:

C#
public override void Run()
{
    IsRunning = true;
    OnJobStarted?.Invoke(this);
    OnLogMessage?.Invoke(this, "JOB START");
    try
    {
        while (Job.ThreadState == ThreadState.Running && !isJobTerminated)
        {
            var ts = DateTime.Now;
            if (!Ping())
            {

            }
            var es = DateTime.Now;
            var ms = (es - ts).TotalMilliseconds;
            while (!isJobTerminated && (DateTime.Now - ts).TotalMilliseconds <= this.PingInterval * 1000)
                Thread.Sleep(10);
        }
    }
    catch (Exception ex)
    {
        OnLogMessage?.Invoke(this, " RUN: " + ex.Message);
    }
    OnLogMessage?.Invoke(this, "JOB END");
    OnJobEnded?.Invoke(this);
    IsRunning = false;
}

public override bool Ping()
{
    var result = false;
    try
    {
        PingStat.LastPingDateTime = DateTime.Now;
        PingStat.PingInterval = this.PingInterval;

        result = true;
        PingStat.TotalPingCount++;
        if (!result)
            PingStat.ErrorCount++;

        if (result)
        {
            foreach (var md in Children.Where(m => !m.IsSuspended && m.IsEnabled))
            {
                var pingResult = ReadConfiguration(md).ErrorCode == 0;
                Thread.Sleep(10);

                if (pingResult)
                    ReadState(md);
                if (pingResult && md.IsMaskChanged)
                {
                    var maskResult = WriteSingleRegister(md, 0x05FC, md.Mask);
                    md.IsMaskChanged = !(maskResult.ErrorCode == 0);
                }

                md.PingStat.IsLastPingOk = pingResult;
                md.OnPing?.Invoke(md, pingResult);

            }
        }
    }
    catch (Exception ex)
    {
        OnLogMessage?.Invoke(this, ex.Message + Environment.NewLine + ex.StackTrace);
        result = false;
    }
    finally
    {
        PingStat.IsLastPingOk = result;
        OnPing?.Invoke(this, result);
    }
    return result;
}

public override RcResult ExecuteModBus(RcModBusDevice device, byte[] request, out byte[] answer)
{
    answer = null;
    var result = new RcResult();
    var dt = DateTime.Now;
    Random rnd = new Random();
    try
    {
        OnLogMessage?.Invoke(this, "ExecuteModBus Lock?");
        lock (communication)
        {

            OnLogMessage?.Invoke(this, "ExecuteModBus Lock!");

            using (var tcpClient = new TcpClient())
            {
                tcpClient.Connect(IP, Port);
                tcpClient.SendTimeout = SendTimeout;
                tcpClient.ReceiveTimeout = Math.Max(100, ReceiveTimeout);
                using (var stream = tcpClient.GetStream())
                {
                    dt = DateTime.Now;
                    OnLogMessage?.Invoke(this, "REQUEST->:" + Utils.BytesToHex(request));
                    stream.Write(request, 0, request.Length);

                    var tmp = new byte[0xA0];
                    int dataLength = 0;

                    try
                    {

                        for (dataLength = 0; dataLength < tmp.Length; dataLength++)
                        {
                            tmp[dataLength] = (byte)(stream.ReadByte());
                            tcpClient.ReceiveTimeout = 100 - Properties.Settings.Default.coefIP;
                            Thread.Sleep(0);
                        }

                    }
                    catch (Exception ex)
                    {
                    }

                    if (dataLength < 2)
                        result.ErrorCode = 1;
                    else
                    {
                        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.AddMilliseconds(rnd.Next(-35, -30)), Utils.BytesToHex(answer));
            }
        }
        OnLogMessage?.Invoke(this, "ExecuteModBus UnLock");
    }
    catch (Exception ex)
    {
        SaveToLog(DbID, device.DbID, dt, Utils.BytesToHex(request), DateTime.Now.AddMilliseconds(rnd.Next(-35, -30)), "ERROR", ex.Message);
        OnLogMessage?.Invoke(this, ex.Message + Environment.NewLine + ex.StackTrace);
        result = new RcResult() { ErrorCode = 1, ErrorText = ex.Message };
    }
    return result;
}
Posted
Updated 27-May-20 7:22am
v2
Comments
Richard MacCutchan 27-May-20 7:57am    
I suspect all those calls to Thread.Sleep are not helping.
Demuter 27-May-20 9:52am    
I also thought about these ... I cleaned them, but still got the same result
Richard MacCutchan 27-May-20 11:41am    
I am afraid that without more information it is difficult to guess what the problem may be.
Demuter 27-May-20 13:14pm    
What additional information is better to provide?

1 solution

You keep opening a new connection every time you make a request; that's where all your "lag" is. You create a connection to a device, and keep it open while you are "sending and receiving." You close the connection when you're "done".
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900