首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >长电缆超时下的串行通信超时

长电缆超时下的串行通信超时
EN

Stack Overflow用户
提问于 2016-01-15 12:05:12
回答 5查看 4.3K关注 0票数 14

我有一个通过rs232读取不同硬件的应用程序。它已经过测试,而且运行得很好。在最后的应用程序中,我需要介绍几个hunder长的电缆,这意味着我有rs485转换器。

当我运行我的应用程序来读取硬件时,我会得到System.IO.Ports.SerialStream.Read的一个超时错误。我已经将超时时间增加到20秒,不幸的是它并没有解决这个问题。

我尝试过不同的应用程序来读取硬件,它们甚至可以在1秒的读取频率下工作。

通信使用modbus协议,在当前阶段,我认为这是不相关的,因为我没有到达接收任何东西的阶段。

我的代码如下所示:首先,串口打开和初始化:

代码语言:javascript
运行
复制
//get the right modbus data structure element
ModBus MB = (ModBus)s[0].sensorData;

//set up the serial port regarding the data structure's data
SerialPort sp = new SerialPort();
sp.PortName = MB.portName;
sp.BaudRate = Convert.ToInt32(MB.baudRate);
sp.DataBits = MB.dataBits;
sp.Parity = MB.parity;
sp.StopBits = MB.stopBits;
//Set time outs 20 sec for now
sp.ReadTimeout = 20000;
sp.WriteTimeout = 20000;

//将端口添加到读取器portList.Add(sp);sp.Open()可以访问的列表中;

阅读硬件:

代码语言:javascript
运行
复制
//get the right port for com
SerialPort sp = getRightPort();
ModBus MB = getRightModBusStructureelement();
try
   {
     //Clear in/out buffers:
     sp.DiscardOutBuffer();
     sp.DiscardInBuffer();

     //create modbus read message
     byte[] message = createReadModBusMessage();

     try
        {
         sp.Write(message, 0, message.Length);

         // FM.writeErrorLog output included for easier debug
         FM.writeErrorLog(DateTime.Now + ": ModBus Message Sent");
         FM.writeErrorLog(DateTime.Now + ": Read TimeOut = " + sp.ReadTimeout + " Write TimeOut = " + sp.WriteTimeout);

         int offset = 0, bytesRead;
         int bytesExpected = response.Length;

         FM.writeErrorLog(DateTime.Now + ": start read");

         while (bytesExpected > 0 && (bytesRead = sp.Read(response, offset, bytesExpected)) > 0)
            {
              FM.writeErrorLog(DateTime.Now + ": read - " + offset);
              offset += bytesRead;
              bytesExpected -= bytesRead;
            }
        }
        catch (Exception err)
        {
           Console.WriteLine("ERROR Modbus Message to serial port ModBus: " + err);
           FM.writeErrorLog(DateTime.Now + " - " + "ERROR Modbus Message to serial port ModBus: " + err);
         }

  }

在尝试应用程序之后,我从ErroLog.txt获得了以下输出:

代码语言:javascript
运行
复制
14/01/2016 17:18:17: ModBus Message Sent
14/01/2016 17:18:17: Read TimeOut = 20000 Write TimeOut = 20000
14/01/2016 17:18:18: start read
14/01/2016 17:18:38 - ERROR Modbus Message to serial port ModBus: System.TimeoutException: The operation has timed out.
   at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
   at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
   at System.IO.Ports.SerialPort.Read(Byte[] buffer, Int32 offset, Int32 count)
   at ProbReader.SensorReader.modbusReading(List`1 mm, Int32 spCounter)
14/01/2016 17:18:38: 0
14/01/2016 17:18:38: 0

为了防止出现同样的错误,我将超时时间增加到60秒:

代码语言:javascript
运行
复制
15/01/2016 11:11:51: ModBus Message Sent
15/01/2016 11:11:51: Read TimeOut = 60000 Write TimeOut = 60000
15/01/2016 11:11:51: start read
15/01/2016 11:12:51 - ERROR Modbus Message to serial port ModBus: System.TimeoutException: The operation has timed out.
   at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
   at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
   at System.IO.Ports.SerialPort.Read(Byte[] buffer, Int32 offset, Int32 count)
   at ProbReader.SensorReader.modbusReading(List`1 mm, Int32 spCounter)
15/01/2016 11:12:51: 0
15/01/2016 11:12:51: 0

我尝试过几种不同的读取串口的方法,我认为当前的方法看起来最好,这是我的读取代码中的while循环。

我没有包括我的代码的其余部分,因为它以前是超时的,我认为这是不相关的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-03-09 14:25:47

正如我在我的问题中提到的,我能够与其他软件一起阅读硬件,所以它必须是一个软件错误。在调查了所有可能的变量,我可以操纵在串口设置,我已经提出了一个想法,扭转握手,并让它始终被接受。

仔细研究一下,给我下面的代码,增加写和读的时间。它解决了我的问题:

代码语言:javascript
运行
复制
                            sp.ReadTimeout = 60000;
                            sp.WriteTimeout = 60000;

                            sp.DtrEnable = true;
                            sp.RtsEnable = true;
                            sp.Handshake = Handshake.None;

我希望这将有助于其他人在未来,并感谢大家的帮助和努力。

票数 1
EN

Stack Overflow用户

发布于 2016-01-29 09:31:12

如果您正在使用数百米的串行电缆(这本身就是一个硬件工程问题),那么我强烈建议在电缆两端都有一个适当的收发器。电缆本身应该是电磁兼容屏蔽和高质量.无屏蔽电缆的长时间运行可能是诱发电压波动的受害者,这种波动可能会损坏非设计用于处理长电缆运行的设备。

即使有好的电缆,你仍然会有相当大的电压下降和电感/电容效应,这可能会阻止通信在较高波特率。以最低的波特率运行,你可以逃脱。

票数 6
EN

Stack Overflow用户

发布于 2016-02-03 10:05:25

假设这是一个硬件问题(我想是的,我也必须解决类似的问题),我建议用串行设备旁边的设备服务器(通过以太网)替换数百米的串行电缆。设备服务器可以在您的PC上模拟COM端口,从而保持串行电缆短。

不幸的是,这些服务器比几米长的电缆稍贵一些。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34810718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档