写入多个传感器命令并同时读取
Write multiple command of senser and read simontenously
我是 C# 的新手,正在尝试开发 windows 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;
}
总的来说,我发现用两个单独的线程来处理串行端口通信要容易得多。一种是从BlockingCollection
读取数据的writer循环,另一种是reader循环,使用ReadByte()
同步读取一个字节的数据,然后立即循环返回获取下一个数据。 reader 线程与其他线程通信,包括使用 Subject<T>
的 UI 线程,即可观察序列。
您的主 UI(或其他控制线程或计时器)可以将要发送的字节放入传出的 BlockingCollection 中,当在可观察对象上异步接收到输入时,可以处理它。
SerialDataReceivedEvent
在我尝试时似乎从来都不够可靠,这就是为什么我有一个专用的 reader 线程。 ReadAsync
也不可靠。
我的 home automation system 中有 10 多个串行设备,包括许多 RS485 设备,这就是我使用的方法。我的 reader 线程还检查 TimeoutException
和 IOException
以及 InvalidOperationException
,所有这些都可能在您调用 ReadByte
时发生串行端口。实现指数 back-off 然后重新打开串口,取消发送线程,并重新启动一个新的发送线程可以可靠地处理所有这些情况。
但无论如何,第一步,尝试实现一个单独的线程,一次从串行端口读取一个字节,并确保它能正常工作。缓冲一行,然后使用 IObservable
将该行发送到您的 UI,主题将是一个好的开始。
我是 C# 的新手,正在尝试开发 windows 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;
}
总的来说,我发现用两个单独的线程来处理串行端口通信要容易得多。一种是从BlockingCollection
读取数据的writer循环,另一种是reader循环,使用ReadByte()
同步读取一个字节的数据,然后立即循环返回获取下一个数据。 reader 线程与其他线程通信,包括使用 Subject<T>
的 UI 线程,即可观察序列。
您的主 UI(或其他控制线程或计时器)可以将要发送的字节放入传出的 BlockingCollection 中,当在可观察对象上异步接收到输入时,可以处理它。
SerialDataReceivedEvent
在我尝试时似乎从来都不够可靠,这就是为什么我有一个专用的 reader 线程。 ReadAsync
也不可靠。
我的 home automation system 中有 10 多个串行设备,包括许多 RS485 设备,这就是我使用的方法。我的 reader 线程还检查 TimeoutException
和 IOException
以及 InvalidOperationException
,所有这些都可能在您调用 ReadByte
时发生串行端口。实现指数 back-off 然后重新打开串口,取消发送线程,并重新启动一个新的发送线程可以可靠地处理所有这些情况。
但无论如何,第一步,尝试实现一个单独的线程,一次从串行端口读取一个字节,并确保它能正常工作。缓冲一行,然后使用 IObservable
将该行发送到您的 UI,主题将是一个好的开始。