我是C#的新手,并试图开发RS-485水压传感器的窗体项目。 从我的代码中,当我只写一个传感器命令并读取时,它工作正常。但是当我编写所有命令并尝试执行它时,它无法正常工作。 在我的代码中DatafromCOM是带字符串值的全局变量,在Timer中我写了一个写传感器命令的代码。能否请你给我一些解决方案我试图这样做一周,我找不到解决方案。我的代码在
之下 private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
while (serialPort1.BytesToRead != 0)
{
DatafromCOM = serialPort1.ReadLine();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
string cmdCurrent = "D0107012A0C";
string cmdCrntTW = "D0107022B4C";
string cmdVer = "D010703EB8D";
string cmdConf = "D01070429CC";
string cmdAdd = "D010705E90D";
string cmdCorr = "D020B10";
string cmdAvg = "D011011";
string cmdLvlCor = "D010B12";
string cmdGrvty = "D010B14";
serialPort1.Write(cmdCrntTW + NewLine);
serialPort1.Write(cmdVer + NewLine);
serialPort1.Write(cmdConf + NewLine);
serialPort1.Write(cmdAdd + NewLine);
serialPort1.Write(cmdCorr + NewLine);
serialPort1.Write(cmdCorr + NewLine);
serialPort1.Write(cmdAvg + NewLine);
serialPort1.Write(cmdAvg + NewLine);
serialPort1.Write(cmdLvlCor + NewLine);
serialPort1.Write(cmdGrvty + NewLine);
txtKQ.Text += DatafromCOM + Environment.NewLine;
}
答案 0 :(得分:1)
一般来说,我发现有两个独立的线程来处理串口通信要容易得多。一个是从BlockingCollection
读取的写入循环,另一个是使用ReadByte()
的读取器循环,一次同步读取一个字节的数据,并立即循环返回以获取下一个数据。读者线程与其他线程通信,包括使用Subject<T>
的UI线程,即可观察序列。
您的主UI(或其他控制线程或计时器)可以在传出的BlockingCollection中放置要发送的字节,并且当在observable上异步接收输入时,可以对其进行处理。
当我尝试它时,SerialDataReceivedEvent
似乎永远不够可靠,这就是为什么我有一个专门的读者线程。 ReadAsync
也不可靠。
我的home automation system中有10多个串口设备,包括许多RS485设备,这就是我使用的方法。我的读者线程还会检查TimeoutException
和IOException
以及InvalidOperationException
,当您在串行端口发生短暂或致命错误时调用ReadByte
时,所有这些都会发生。实现指数退避然后重新打开串口,取消发送方线程,并重新启动新的发送方线程可以可靠地处理所有这些情况。
但无论如何,第一步,尝试实现一个单独的线程,一次一个字节地从串口读取,并确保工作正常。缓冲一行,然后使用IObservable
将该行发送到您的UI,主题将是一个良好的开端。