我正在使用Qt的QSerialPort库与RS232通信。我将ReadyRead信号连接到readData()插槽;
connect(comms,SIGNAL(readyRead()),this,SLOT(readData()));
当我发送像“Hello World!”这样的字符串时我可以使用comms.readAll()和comms.bytesAvailable()返回12来读取所有数据。
但是当我发送“Hello World!\ n \ r”时,它会显示“Hello World!”和“\ n \ r”部分完全相同,comms.bytesAvailable()首先返回12,然后是2。
当我发送十六进制字节(没有空格)
时,情况会越来越严重0x0F 0x00 0x43 0x11 0x00 0x04 0x11 0x00 0x02 0x70
它正确读取值,但一次读取1或2个字节。我试过waitForRead(),但这没有帮助。
我怎样才能一次读取所有传入的字节,即使它不是标准字母?
答案 0 :(得分:1)
在字节可用时尝试从端口读取:
if (f_port->bytesAvailable()) { // If there are bytes available
QByteArray f_data; // data container
f_data.clear();
if (f_port->open(QIODevice::ReadWrite)) { // Try to open the port
while(f_port->bytesAvailable()) { // Reading loop
f_data.append(f_port->readAll());
}
f_port->flush();
f_port->close();
}
qDebug() << f_data; // Check the result
}
答案 1 :(得分:0)
很遗憾,您无法确定已阅读所有数据。
您必须在某个中间缓冲区中收集传入数据,并对其进行分析以查找符合您的协议定义的命令。也就是说,必须满足某些要求,如固定长度或特定的起始字节(例如0x02)或结束字节(\ r \ n想到的)或它们的组合。
答案 2 :(得分:0)
一种方法是使用您获得的字节累积缓冲区。 然后验证它是否是正确的命令(由您决定什么是正确的)并触发您想要执行的命令。 你还应该有一个计时器来从缓冲区中删除垃圾。
让我们看一下小伪码
static QByteArrray s_vBuffer;
readData()
{
s_vBuffer.append(....);
bool bValidCommand=VerifyCommand(s_vBuffer);
if(bValidCommand)
{
QByteArray vCommand=ExtractCommand(s_vBuffer);//also removing the part of the command
ExecuteCommand(vCommand);
}
else
{
//if timeout clear s_vBuffer
}
}
其他技术涉及command.etc
末尾的校验和,CRC等