Qt QSerialPort读写

时间:2019-04-01 06:42:08

标签: c++ qt buffer qtserialport

我对QSerialPort进行读写有问题。我读了我写的东西。这是一些示例代码证明了这一点。也许我需要从不同的渠道进行读写。预先在thx下面提供了代码。提供了带有图像的程序日志。

此处记录程序

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();
}

2 个答案:

答案 0 :(得分:0)

首先,尝试连接从端口读取/写入信号时发出的不同信号。

例如,要检查数据是否已正确发送,根据文档,您可以使用信号QIODevice::bytesWritten

  

每次将有效载荷数据写入设备的当前写入通道时,都会发出信号。 bytes参数设置为在此有效负载中写入的字节数。

connect(serialPort,&QSerialPort::bytesWritte, this, [](const qint64 bytes) {
    qDebug() << "Sent data: " << bytes << " bytes.";
});

要像以前一样读取数据,需要检查QIODevice::readyRead信号:

  

每当有新数据可用于从设备的当前读取通道读取时,都会发出此信号。仅当有新数据可用时(例如,当网络套接字上有新的网络数据有效负载,或将新的数据块附加到设备上时),才会再次发出该信号。

关于您描述的问题,要做的第一步是确保未将您的Decive配置为在回显模式下工作。要关闭它,您需要检查设备界面。

如果这不是问题,请使用`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);

答案 1 :(得分:0)

问题出在

    serialPort->setStopBits(QSerialPort::StopBits::TwoStop);

另一台设备已通过QSerialPort::StopBits::OneStop连接到串行端口。 因此,更改停止位serialPort->setStopBits(QSerialPort::StopBits::OneStop); 解决了这个问题,再也没有回音了。