QT串口读取

tle*_*ton 3 c++ qt serial-port qt5 qtserialport

我正在尝试读取通过USB通过设备插头发送的数据。首先我通过此命令读取数据

  • 须藤stty -F / dev / ttyUSB0 1200 sane parenb evenp cs7 -crtscts
  • 猫/ dev / ttyUSB0

数据是这样的

TGPHI_s -0,24 =

MESURES2 BT 4 SUP36 A

PTCOUR2 HPH /
Run Code Online (Sandbox Code Playgroud)

现在我想通过Qt5.3程序读取数据

QSerialPort serial;
serial.setPortName("ttyUSB0");
if(!serial.setBaudRate(QSerialPort::Baud1200 , QSerialPort::Input))
    qDebug() << serial.errorString();
if(!serial.setDataBits(QSerialPort::Data7))
    qDebug() << serial.errorString();
if(!serial.setParity(QSerialPort::EvenParity))
    qDebug() << serial.errorString();
if(!serial.setFlowControl(QSerialPort::HardwareControl))
    qDebug() << serial.errorString();
if(!serial.setStopBits(QSerialPort::OneStop))
    qDebug() << serial.errorString();
if(!serial.open(QIODevice::ReadOnly))
    qDebug() << serial.errorString();
qDebug() << serial.bytesAvailable();
while(true)
{
    if (serial.isOpen()) {
        qDebug() << "Serial port is open...";
        QByteArray datas = serial.readAll();
        if (datas.size() == 0) {
            qDebug() << "Arrived data: 0";
        } else {
            for (int i = 0; i < datas.size(); i++){
                if (datas.at(i)) {
                    qDebug() << datas[i];
                }
            }
        }

    } else {
        qDebug() << "OPEN ERROR: " << serial.errorString();
    }
}
return 0;
Run Code Online (Sandbox Code Playgroud)

答案是->

"/dev/ttyUSB0"
0
Serial port is open...
Arrived data: 0
Serial port is open...
Arrived data: 0
Run Code Online (Sandbox Code Playgroud)

所以我的程序没有捕获任何数据...我的问题是:

  • 我在QSerialPort的设置中错过了什么吗?
  • 如果没有,为什么没有通过qDebug()显示数据

编辑

多亏了迈克,我才能最终阅读此USB设备!这是我的最终代码

    QSerialPort serial;
serial.setPortName("ttyUSB0");
if(!serial.setBaudRate(QSerialPort::Baud1200))
    qDebug() << serial.errorString();
if(!serial.setDataBits(QSerialPort::Data7))
    qDebug() << serial.errorString();
if(!serial.setParity(QSerialPort::EvenParity))
    qDebug() << serial.errorString();
if(!serial.setFlowControl(QSerialPort::HardwareControl))
    qDebug() << serial.errorString();
if(!serial.setStopBits(QSerialPort::OneStop))
    qDebug() << serial.errorString();
if(!serial.open(QIODevice::ReadOnly))
    qDebug() << serial.errorString();
QObject::connect(&serial, &QSerialPort::readyRead, [&]
{
    //this is called when readyRead() is emitted
    //qDebug() << "New data available: " << serial.bytesAvailable();
    qDebug() << "New data available: " << serial.bytesAvailable();
    QByteArray datas = serial.readAll();
    qDebug() << datas;
});
QObject::connect(&serial,
                     static_cast<void(QSerialPort::*)(QSerialPort::SerialPortError)>
                     (&QSerialPort::error),
                     [&](QSerialPort::SerialPortError error)
{
    //this is called when a serial communication error occurs
    qDebug() << "An error occured: " << error;
    return qApp->quit();
});


if(!serial.open(QIODevice::ReadOnly))
    qDebug() << serial.errorString();
return qApp->exec();
Run Code Online (Sandbox Code Playgroud)

Mik*_*ike 6

Qt中的大多数IO功能都是异步的。这意味着readAll()不等待数据到达。而是返回当前可用的数据(无需等待即可从设备读取的数据)。当前,您只是readAll在无休止的循环中进行调用(这使线程将所有时间都花在此循环中,无法接收可能已经到达的新数据。

readAll仅在知道新数据到达时才需要呼叫。这可以通过两种方式完成:

  • 非阻塞异步方式:

    readyRead()当设备中有新数据可用时,使用信号来通知,而不是永远循环。这是您应该在Qt中做的大多数事情的方式,以便能够对可能随时到达的多个事件采取行动。您的代码可以这样重写:

    #include <QtSerialPort>
    
    int main(int argc, char* argv[]){
        QCoreApplication a(argc, argv);
        QSerialPort serial;
        serial.setPortName("ttyUSB0");
        if(!serial.setBaudRate(QSerialPort::Baud1200))
            qDebug() << serial.errorString();
        if(!serial.setDataBits(QSerialPort::Data7))
            qDebug() << serial.errorString();
        if(!serial.setParity(QSerialPort::EvenParity))
            qDebug() << serial.errorString();
        if(!serial.setFlowControl(QSerialPort::HardwareControl))
            qDebug() << serial.errorString();
        if(!serial.setStopBits(QSerialPort::OneStop))
            qDebug() << serial.errorString();
        if(!serial.open(QIODevice::ReadOnly))
            qDebug() << serial.errorString();
        QObject::connect(&serial, &QSerialPort::readyRead, [&]
        {
            //this is called when readyRead() is emitted
            qDebug() << "New data available: " << serial.bytesAvailable();
            QByteArray datas = serial.readAll();
            qDebug() << datas;
        });
        QObject::connect(&serial,
                         static_cast<void(QSerialPort::*)(QSerialPort::SerialPortError)>
                         (&QSerialPort::error),
                         [&](QSerialPort::SerialPortError error)
        {
            //this is called when a serial communication error occurs
            qDebug() << "An error occured: " << error;
            a.quit();
        });
    
        return a.exec();
        //     ^^^^^^^^
        //very important: starts the Qt main event loop
        //this makes all asynchronous stuff possible
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 阻塞同步方式:

    使用waitForReadyRead()直到新的数据到达串口阻塞线程。这使得调用线程无法做任何事情,直到新数据到达该串行端口。如果此线程是GUI线程,这将使应用程序在该时间段内无响应。仅在确定要使用此方法时才使用此方法。您的代码可以这样重写:

    #include <QtSerialPort>
    
    int main(int argc, char* argv[]){
        QCoreApplication a(argc, argv);
        QSerialPort serial;
        serial.setPortName("ttyUSB0");
        if(!serial.setBaudRate(QSerialPort::Baud1200))
            qDebug() << serial.errorString();
        if(!serial.setDataBits(QSerialPort::Data7))
            qDebug() << serial.errorString();
        if(!serial.setParity(QSerialPort::EvenParity))
            qDebug() << serial.errorString();
        if(!serial.setFlowControl(QSerialPort::HardwareControl))
            qDebug() << serial.errorString();
        if(!serial.setStopBits(QSerialPort::OneStop))
            qDebug() << serial.errorString();
        if(!serial.open(QIODevice::ReadOnly))
            qDebug() << serial.errorString();
        qDebug() << serial.bytesAvailable();
        while(serial.isOpen())
        {
            if(!serial.waitForReadyRead(-1)) //block until new data arrives
                qDebug() << "error: " << serial.errorString();
            else{
                qDebug() << "New data available: " << serial.bytesAvailable();
                QByteArray datas = serial.readAll();
                qDebug() << datas;
            }
        }
        return 0;
    }
    
    Run Code Online (Sandbox Code Playgroud)