QSerialPort 单独读取十六进制值
QSerialPort reads hex values sepereatly
我正在使用 Qt 的 QSerialPort 库与 RS232 通信。我将 ReadyRead 信号连接到我的 readData() 插槽;
connect(comms,SIGNAL(readyRead()),this,SLOT(readData()));
当我发送像 "Hello World!" 这样的字符串时,我可以使用 comms.readAll() 和 comms.bytesAvailable() 读取所有数据 returns 12.
但是当我发送 "Hello World!\n\r" 时,它会分别读取 "Hello World!" 和“\n\r”部分,并且 comms.bytesAvailable() returns 首先读取 12,然后读取 2。
当我发送像(没有空格)这样的十六进制字节时情况变得更糟
0x0F 0x00 0x43 0x11 0x00 0x04 0x11 0x00 0x02 0x70
它正确读取值,但一次读取 1 或 2 个字节。我尝试了 waitForRead() 但这没有帮助。
即使不是标准字母,我如何一次读取所有传入字节?
很遗憾,您无法确定是否已读取所有数据。
您必须在某个中间缓冲区中收集传入数据并分析它以查找符合您的协议定义的命令。也就是说,它必须满足某些要求,例如固定长度或特定的起始字节(例如 0x02)或结束字节(想到 \r)或它们的组合。
一种方法是用您获得的字节积累一个缓冲区。
然后验证它是否是正确的命令(由您决定什么是正确的)并触发您想要执行的命令。
你也应该有一个计时器来从缓冲区中删除垃圾。
让我们用一个小的伪代码来看看
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 等
尝试在字节可用时从端口读取:
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
}
我正在使用 Qt 的 QSerialPort 库与 RS232 通信。我将 ReadyRead 信号连接到我的 readData() 插槽;
connect(comms,SIGNAL(readyRead()),this,SLOT(readData()));
当我发送像 "Hello World!" 这样的字符串时,我可以使用 comms.readAll() 和 comms.bytesAvailable() 读取所有数据 returns 12.
但是当我发送 "Hello World!\n\r" 时,它会分别读取 "Hello World!" 和“\n\r”部分,并且 comms.bytesAvailable() returns 首先读取 12,然后读取 2。
当我发送像(没有空格)这样的十六进制字节时情况变得更糟
0x0F 0x00 0x43 0x11 0x00 0x04 0x11 0x00 0x02 0x70
它正确读取值,但一次读取 1 或 2 个字节。我尝试了 waitForRead() 但这没有帮助。
即使不是标准字母,我如何一次读取所有传入字节?
很遗憾,您无法确定是否已读取所有数据。
您必须在某个中间缓冲区中收集传入数据并分析它以查找符合您的协议定义的命令。也就是说,它必须满足某些要求,例如固定长度或特定的起始字节(例如 0x02)或结束字节(想到 \r)或它们的组合。
一种方法是用您获得的字节积累一个缓冲区。 然后验证它是否是正确的命令(由您决定什么是正确的)并触发您想要执行的命令。 你也应该有一个计时器来从缓冲区中删除垃圾。
让我们用一个小的伪代码来看看
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 等尝试在字节可用时从端口读取:
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
}