Qt QSerialPort 读写
Posted
技术标签:
【中文标题】Qt QSerialPort 读写【英文标题】:Qt QSerialPort Read Write 【发布时间】:2019-04-01 06:42:07 【问题描述】:我在读写 QSerialPort 时遇到问题。我读了我写的东西。这是一些证明这一点的示例代码。也许我需要从不同的渠道写作和阅读。代码提前在下面提供。提供带有图像的程序日志。
这里是程序日志
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QTimer>
#include <QDebug>
class MainWindow : public QMainWindow
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QSerialPort *serialPort;
QTimer* sendTimer;
QByteArray receiveDataBuffer;
private slots:
void onReadyRead();
void onSendDataTimeout();
;
#endif // MAINWINDOW_H
MainWindows.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
serialPort(new QSerialPort),
sendTimer(new QTimer)
sendTimer->setInterval(1000);
serialPort->setPortName("COM5");
serialPort->setBaudRate(QSerialPort::Baud115200);
serialPort->setParity(QSerialPort::Parity::NoParity);
serialPort->setDataBits(QSerialPort::DataBits::Data8);
serialPort->setStopBits(QSerialPort::StopBits::TwoStop);
serialPort->open(QSerialPort::OpenModeFlag::ReadWrite);
connect(serialPort,&QSerialPort::readyRead,this,&MainWindow::onReadyRead);
connect(sendTimer,&QTimer::timeout,this,&MainWindow::onSendDataTimeout);
sendTimer->start();
MainWindow::~MainWindow()
void MainWindow::onReadyRead()
receiveDataBuffer.append(serialPort->readAll());
if (receiveDataBuffer.contains('^') && receiveDataBuffer.contains('$') && receiveDataBuffer.lastIndexOf('$') < receiveDataBuffer.lastIndexOf('^'))
QByteArray extractedByteArray;
for(int i = receiveDataBuffer.lastIndexOf("$") ; i < receiveDataBuffer.lastIndexOf("^") + 1 ; i++)
extractedByteArray.append(receiveDataBuffer[i]);
qDebug()<<"Received:"<<extractedByteArray<<endl;
receiveDataBuffer.clear();
void MainWindow::onSendDataTimeout()
qint64 result = serialPort->write("$10,0,123,123^");
bool flush = serialPort->flush();
result != -1 && flush ? qDebug()<<"Data sent"<<endl:qDebug()<<"Failed to send data"<<endl;
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
【问题讨论】:
您的客户端是否处于回显模式或者您是否连接了 RX 和 TX? 我已经连接了 RX 和 TX @user6556709 @user6556709 我也试过用另一个软件写数据,它工作得很好,没有收到我写的东西。我在 serialPort 上做错了吗? 您很可能不需要调用flush,但这应该没有什么区别。连接我的意思是你把RX和TX连接起来了吗? (这将导致回声。)。 QSerialPort 本身不支持回显模式(您没有激活或停用它的标志),但您可以在操作系统中设置回显模式。也许它就在那里。 No rx is not connected to tx) ,我使用的是Windows 10,回显模式设置可以在哪里?? @user6556709 【参考方案1】:首先,尝试连接从端口读取/写入时发出的不同信号。
例如检查数据是否已正确发送,根据文档您可以使用信号QIODevice::bytesWritten
:
每次将数据负载写入设备的当前写入通道时,都会发出该信号。 bytes 参数设置为写入此有效负载的字节数。
connect(serialPort,&QSerialPort::bytesWritte, this, [](const qint64 bytes)
qDebug() << "Sent data: " << bytes << " bytes.";
);
要读取数据,就像您已经做的那样,您需要检查QIODevice::readyRead
信号:
每次有新数据可用于从设备的当前读取通道读取时,都会发出一次此信号。只有在有新数据可用时才会再次发出它,例如当新的网络数据负载到达您的网络套接字时,或者当新的数据块已附加到您的设备时。
关于您描述的问题,第一步是确保您的设备没有配置为在回显模式下工作。要关闭它,您需要检查您的设备接口。
如果这不是问题,请使用`QSerialPort::availablePorts 检查可用端口,并确保您连接到正确的端口。例如,要连接到第一个端口,您可以执行以下操作并检查配置是否与您的设备兼容:
auto serialInfo = QSerialPortInfo::availablePorts();
serialPort->setPort(serialInfo[0])
auto ret = serialPort.open(QSerialPort::ReadWrite)
&& serialPort.setBaudRate(QSerialPort::Baud38400)
&& serialPort.setDataBits(QSerialPort::Data8)
&& serialPort.setStopBits(QSerialPort::OneStop)
&& serialPort.setParity(QSerialPort::NoParity);
qDebug() << "Port has been configured properly?: " << ret;
如果问题仍然存在,您可以通过调用QSerailPort::handle()
获取本机处理程序并修改其属性。
如果平台支持且串口打开,则返回本机串口句柄;否则返回 -1。
最后一个选项,它不适用于所有平台。更糟糕的情况,查看termios 的官方文档。它提供了一个低级接口,允许您启用/禁用回显模式。
struct termios options;
tcgetattr(file, &options);
cfmakeraw(&options);
options.c_lflag &= ~(ECHO | ECHOE); // Add or disable the flags
tcsetattr(file, TCSANOW, &options);
【讨论】:
感谢您的回答。你给了我实现一些功能的好主意,但我发现问题出在另一个愚蠢的事情上。另一个设备通过“OneStop”停止位连接到串行端口,而我用“TwoStop”连接,我纠正了它并且回声已经停止。 @mohabouje 太棒了!设置该属性时 Qt 是否返回 false? @HrantNurijanyan【参考方案2】:问题出在
serialPort->setStopBits(QSerialPort::StopBits::TwoStop);
另一台设备使用QSerialPort::StopBits::OneStop
连接到串行端口。
所以改变停止位serialPort->setStopBits(QSerialPort::StopBits::OneStop);
解决了问题,没有回声了。谢谢。
【讨论】:
以上是关于Qt QSerialPort 读写的主要内容,如果未能解决你的问题,请参考以下文章