我的 arduino(这不是 Arduino 问题,而是一般的 C++ 问题)已连接到 PC,并每 2 秒发送一个计数的 3 位数字:
for (long i=100; i <= 999; i++){
Serial.println(i);
delay(2000);
}
通过终端程序连接到 com 端口表明代码执行了预期的操作。
在我的 C++ 应用程序(我们称之为客户端)中,我使用以下代码(在自己的线程中运行)来从串行连接中获取数据:
void *MyThread::Entry() {
SerialPort arduino(port_name); // Init serial port
if (arduino.isConnected()){
wxLogMessage("Message: %s", "Connection Established");
}
else {
wxLogMessage("Message: %s", "ERROR, check port name");
}
while (arduino.isConnected()){
int read_result = arduino.readSerialPort(incomingData, MAX_DATA_LENGTH); // Read data
if (read_result > 2){ // Length of read data
wxLogMessage("incomingData: %s", incomingData);
}
}
}
但是,这会产生如下输出:
09:02:14: Message: Connection Established
09:02:14: incomingData: 100
09:02:15: incomingData:
1
09:02:17: incomingData: 01
09:02:18: incomingData:
10
09:02:20: incomingData: 2
09:02:21: incomingData: 103
09:02:23: incomingData:
1
09:02:24: incomingData: 04
09:02:26: incomingData:
10
09:02:27: incomingData: 5
09:02:29: incomingData: 106
09:02:30: incomingData:
1
09:02:32: incomingData: 07
09:02:33: incomingData:
10
09:02:35: incomingData: 8
09:02:36: incomingData: 109
09:02:38: incomingData:
1
所以我总是有 4 行在两条正确的行之间有错误的值。我认为这是一个赛车问题。 C++代码正在轮询高于arduino发送数据的串行连接方式(每2秒)。
由于传入数据是
char incomingData[255];
我不能只清空传入数据并测试 3 位数字。
那么我怎样才能让客户端以正确的方式获取arduino发送的每个完整的3位数字值呢?我是否需要实现一个自己的消息传递系统,例如用开始和停止标志封装 arduino 发送的值?或者还有另一种我看不到的便宜方法吗?
最佳答案
作为一般规则,在使用串行通信时,您无法“准确读取所需的长度”(包括换行符等)。字符可能会丢失,或者添加“噪音”。
这是一种更好的方法来验证来自串行输入的数据,并使用更大的缓冲区读入单独的缓冲区,并在完成时返回行(或您想要返回的任何“数据包”),到调用代码。这当然会变得更加复杂,因为您需要第二个缓冲区来跟踪您“尚未提供给调用者”的内容。
尽管如此,正如我的评论所暗示的,我认为这里的问题是您正在读取 3 个字节,而您收到了 5 个字节。您的实际消息如下所示:
100<CR><LF>
101<CR><LF>
102<CR><LF>
103<CR><LF>
所以第一次,你读到 100
,然后第二次读取得到 <CR><LF>1
,然后 01<CR>
,接下来得到<LF>10
,然后2<CR><LF>
,我们又与 103
保持同步再次。
哪里<CR>
是字符 13 (Control-M) 和 <LF>
是字符 10 (Control-J)
关于C++串行连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49045419/