所以,我在c ++ win forms app中有一个串口控制(System :: IO :: Ports :: SerialPort),它从串口连接中读取数据,正如标题所暗示的那样。但是,无论出于何种原因,Microsoft决定读取数据只返回String值,如果您只是在事后解析字符串就可以了。除了,当我尝试解析从ReadExisting()命令返回的字符串时,我得到一个System.FormatException。
我确定它与ReadExisting()返回字符串值的方式有关,因为当我将其更改为ReadLine()时,我可以轻松地在其上调用Double :: Parse(string)并得到一个清洁的回报价值。除了我没有使用ReadLine()的奢侈,因为它对我的应用来说太慢了。我试图以640 Hz的频率读取通过该串行连接的每一段数据,因此当我尝试使用ReadLine()时,等待新的行字符将其减慢大约10倍,这意味着我是相反,读取大约64赫兹。没有数据丢失,但对我的应用来说太慢了。
这是附加DataReceived事件的方法。我正在寻找一种方法,允许我解析从ReadExisting()传回来的字符串。无论是那种,还是一种更有效的阅读方法,让我不会失去任何速度,但仍然允许我最终解析数据,以便我可以使用它。
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {
if (!this->reading) return;
else
{
try
{
//get incoming port and read
SerialPort^ sp = (SerialPort^)sender;
String^ sInData = sp->ReadExisting();
//parse read data
double inData = Double::Parse(sInData);
//write data to debugger for testing
Debug::WriteLine(sInData);
//start populating the "in" array
AppendIn(inData);
}
catch (Exception^ e)
{
Debug::WriteLine(e->Message);
}
}
}
提前感谢您提供的任何想法。
答案 0 :(得分:1)
我猜测FormatException
中的消息说明了一个无效的字符串。 ReadExisting
读取可用的任何字节,将字节解码为字符,并将它们作为字符串返回。由于您没有检查ReadExisting
的结果,因此可能还有多个双打。由于您说ReadLine
有效,因此从ReadExisting
返回的字符串可能是“123 \ n456 \ n”,Double::Parse
正在抛出FormatException
,因为它不是有效的双精度数。
我要做的是将读取串行字节与解析传入数据的问题分开。有一个接收字节的缓冲区,并在DataReceived
事件中附加到它。执行此操作时,请检查缓冲区是否有足够的数据,如果是,请处理完整的传入数据包,并从缓冲区中删除该数据包。就像现在一样,您依靠ReadLine
为您打包,或者您依赖于DataReceived
每个数据包调用一次,而不是。{/ p>
另外,我不明白你的阅读速度是什么意思。
我正在尝试读取每一段数据... 640 Hz ,......我的读数大致是 64 Hz 。 没有数据丢失 ......
如果数据的速度比你读取速度快10倍,那么只有两种可能的选择:要么丢弃数据,要么你的程序越来越落后。