当前位置: 首页 > 知识库问答 >
问题:

串口读取

潘衡
2023-03-14

我试图读取3温度设备使用WinForm和Modbus 485协议。基本上,我必须定期向每个设备写入命令,等待响应,当我得到响应时,处理它。每个设备都有一个唯一的通信地址。为了定期发送命令,我使用了计时器。Timer1.interval=100;这就是我发送命令的方式和处理响应的地方:

private void ProcessTimer_Tick(object sender, EventArgs e)
    {

                switch (tempState)
                {
                    case TempTimerState.sendCommDevice1:
                        if (!tempSerial.IsOpen)
                        {
                            tempSerial.Open();
                        }
                        tempSerial.DiscardInBuffer();
                        communication.tempCommand[0] = 0x01;  //device adress
                        communication.tempCommand[6] = 0xA5;  //CRC
                        communication.tempCommand[7] = 0xC2;  //CRC
                        tempSerial.Write(communication.tempCommand, 0, 8);
                        tempState = TempTimerState.recievedDevice1;
                        communication.waitTime = 0;  //time to wait before throw a timeout exception
                        communication.dataRecievedTemp = false;  //flag for response recieved
                        break;
                    case TempTimerState.recievedDevice1:
                        communication.waitTime++;
                        if (communication.dataRecievedTemp)
                        {
                            communication.waitTime = 0;
                            if(CheckCRC(communication.tempResponse))  //CRC checking
                            {
                                //process response
                            }
                            else
                            {
                                //handle CRC Failure error
                            }
                        }
                        if(commcommunication.waitTime>=maxWaitTime)
                        {
                               //handle Timeout exception
                        }
                        tempState=TempTimerState.sendCommDevice2;
                        break;
                 }
        }

对于每个设备,等等。这是我的serialport数据接收事件:

    private void tempSerial_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            sp.Read(communication.tempResponse, 0, sp.BytesToRead);
            communication.dataRecievedTemp = true;  //flag for data recieved           
        }

所以我的沟通应该是:

send command device1
recieve response device1
send command device2
recieve command device2
send command device3
recieve command device3

然后再次发送命令device1。问题是,我有时得到通信超时错误,我知道肯定所有的设备都响应非常快,每次。因为我已经预设了sp。ReceivedBytesThreshold=8我也开始得到CRC错误。我的响应应该总是8字节长。

我认为问题出在串口数据接收事件中,但我看不出有什么问题。

P. S.我也尝试设置计时器间隔为1000毫秒但这并没有解决我的问题

共有1个答案

宗政金鹏
2023-03-14

依靠ReceivedBytesThreshold是非常脆弱的,当你一次不同步时,表演就结束了。您的代码也很容易受到其他原因的影响,数据接收可能会触发,您没有检查e。EventType属性。这当然可以是序列数据。二进制协议的Eof。

只需编写不依赖于EventType或可用字节数的健壮代码。这样地:

    private byte[] rcveBuf = new byte[8];
    private int rcveLen;

    private void tempSerial_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        rcveLen += sp.Read(rcvebuf, rcveLen, rcveBuf.Length - rcveLen);
        if (rcveLen == rcveBuf.Length) {
           Array.Copy(rcveBuf, communication.tempResponse, rcveBuf.Length);
           communication.dataRecievedTemp = true;
           rcveLen = 0;
        }        
    }

并在超时时将rcveLen重置回零。并且要确保超时时间不要太低,如果你的程序被调出,你可能会损失很多秒,使用10秒是安全的。

 类似资料:
  • 这是http://www.gravitech.us/7segmentshield.html给出的代码。 那么怎样才能逐行阅读呢?

  • 本文向大家介绍Android串口通信之串口读写实例,包括了Android串口通信之串口读写实例的使用技巧和注意事项,需要的朋友参考一下 在Android串口通信:基本知识梳理的基础上,我结合我项目中使用串口的实例,进行总结; Android使用jni直接进行串口设备的读写网上已经有开源项目了,本文是基于网上的开源项目在实际项目中的使用做的调整和优化; Google串口开源项目 下面是我项目中的相关

  • 我做了一个python程序,从串行端口读取gps数据。GPS冰球流NMEA数据语句连续插入USB时。我的程序打开端口,然后尝试读取数据,解析它,然后将其与从Arduino提取的其他数据一起写入文本文件。 我遇到的问题是,当我第一次运行程序时,有时它无法读取数据。我放入了一些Try/Exception捕获,发现以某种方式无法从GPS串行端口读取数据 如果我点击Cntrl-C几次,这似乎可以解决它遇到

  • 问题内容: 我以下列方式从打开的串行端口读取某些数据时遇到麻烦。我已经多次使用此代码实例,并且一切正常,但是现在,由于某种原因,我无法弄清楚,我完全无法从串行端口读取任何内容。 我能够写,并且在另一端正确接收了所有消息,但是从未收到答复(正确发送)(不,电缆都还好;)) 我用来打开串行端口的代码如下: 端口初始化后,我通过简单的write命令向其中写入一些内容。 hCom是文件描述符(没关系),并

  • 问题内容: 我正在尝试 使用FTDI通过USB端口发送/接收数据 ,因此我需要使用C / C ++处理串行通信。我正在使用 Linux (Ubuntu)。 基本上,我已连接到正在侦听传入命令的设备。我需要发送这些命令并阅读设备的响应。命令和响应都是 ASCII字符 。 使用GtkTerm一切正常,但是,当我切换到C编程时,遇到了问题。 这是我的代码: 发生的结果是返回0(根本不读取任何字节)或阻塞

  • 问题内容: 我有一个Java程序,必须读取Arduino发送的信息。我从这里获取了Java代码。现在,我不太了解它是如何工作的,但是我尝试对其进行修改,并且得到了以下信息: 我创建一个对象串行COM口,我需要在主程序,然后我使用和当我需要它。 效果很好,Arduino获取数据并将其显示在LCD显示屏中。问题是。程序运行时,它会不断从串行端口读取数据(大约每40毫秒一次),但这并不意味着Arduin