Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QtSerialPort terminal example fails for me; how can the sample not work?



  • I am using Qt 5.2 and when my app (which worked using QextSerialPort in v4.8.4) failed to communicate, I tried the example in ...\5.2.0\Src\qtserialport\examples\serialport\terminal. And that fails too.

    I have a simple USB dongle that emulates a COM port. If I use RealTerm, I can send AT commands to it and get back OK just fine.

    But the terminal example that comes with Qt does not communicate with it. I looked at an API snooper, and I am getting an unsuccessful return with error of "997:Overlapped I/O operation is in progress" for WaitCommEvent and WriteFile.

    I am running it on Windows 7, and I copied the exe and DLLs over to a Windows 8 machine, and it failed there as well (though I admittedly didn't do the API snooping there).

    Anyone have any ideas what to try? How can the unmodified example app just plain fail? I am befuddled.


  • Qt Champions 2020

    What is model of your USB dongle? What is not work: data writting or data reading? Maybe it driver does not support overlapped mode, and I/O never completed.

    Upd: you can try use the Free Serial Port Monitor to check a data transactions.



  • Could you please provide some code? And your .pro file contents.



  • I quickly checked out a small program I was working on a while ago. Its very basic. It pretty much assumes I only have one active serial port.

    untitled.pro file
    @
    #-------------------------------------------------

    Project created by QtCreator 2013-11-29T13:22:20

    #-------------------------------------------------

    QT += core serialport
    QT -= gui

    TARGET = untitled
    CONFIG += console
    CONFIG -= app_bundle

    TEMPLATE = app

    SOURCES += main.cpp
    serialcomms.cpp

    HEADERS +=
    serialcomms.h
    @

    main.cpp
    @
    #include <QCoreApplication>
    #include "serialcomms.h"

    using namespace std;

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    serialComms comms;
    
    return a.exec&#40;&#41;;
    

    }
    @

    serialcomms.h
    @
    #ifndef SERIALCOMMS_H
    #define SERIALCOMMS_H

    #include <QObject>
    #include <QtSerialPort/QSerialPort>
    #include <QtSerialPort/QSerialPortInfo>

    class serialComms : public QObject
    {
    Q_OBJECT
    public:
    explicit serialComms(QObject *parent = 0);
    QSerialPort *serial;

    signals:

    public slots:
    void readData();

    };

    #endif // SERIALCOMMS_H
    @

    serialcomms.cpp
    @
    #include "serialcomms.h"
    #include <QDebug>

    serialComms::serialComms(QObject *parent) :
    QObject(parent)
    {
    serial = new QSerialPort(this);

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
            qDebug() << "Name        : " << info.portName();
            qDebug() << "Description : " << info.description();
            qDebug() << "Manufacturer: " << info.manufacturer();
    
    serial->setPort(info);
    serial->setBaudRate(QSerialPort::Baud19200);
    serial->setDataBits(QSerialPort::Data8);
    serial->setFlowControl(QSerialPort::NoFlowControl);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    }
    
    serial->open(QIODevice::ReadWrite);
    serial->flush();
    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
    

    }

    void serialComms::readData() {
    qDebug() << serial->readAll();
    serial->flush();
    }
    @

    I used this to get debugging output from an embedded linux module. So it basically just reads from the COM port. I built it using Qt5.1.1 in Windows 7.

    Hope it helps!



  • btw, check lines 10 to 12. If the application builds and runs, those lines should output the available serial devices you have connected.


  • Qt Champions 2020

    2 PleaseWait,

    please do not provide your code because your code is wrong.

    The author used the Bluetooth dongle & Terminal example so it is enough for the start point..

    2 dabbler,

    please try the "casyncwriter" example (from the git) to check triggering of the bytesWritten() signal after writing data. It is important...



  • I SOLVED the problem. So I'll mention it here in case it helps anyone. The bottom line is that I was trying to read data from the port synchronously... like this:
    @
    testPort.write( "AT\r", 3 );
    Sleep( 200L );
    QByteArray rsp = testPort.readAll();
    @

    But I learned that in order to receive data from the serial port, I need to mix in a call to processEvents()
    or else the data won't arrive for me.
    @
    testPort.write( "AT\r", 3 );
    Sleep( 200L );
    QCoreApplication::processEvents( QEventLoop::AllEvents );
    QByteArray rsp = testPort.readAll();
    @
    I suspect there are some signal/slot stuff that is required, even when I don't want to use signals/slots to receive the data.

    In my case, my app normally uses signal/slots for the serial data. But to find the proper port, I found the code much more readable if I just sent an "AT\r" and looked for a response of "OK\r". But I found that after sending "AT\r" I needed to do a processEvents() call, and then I could do a readAll() to look for the "OK\r".

    Now my app works fine.

    I never went back to see why I had problems with the terminal sample code. Seems like that should have worked; but I guess I was having some different problem with that. Likely it was a problem between my chair and keyboard.


  • Qt Champions 2020

    For your concrete problem is enough (something like it):

    [code]
    testPort.write( "AT\r", 3 );
    if (!testPort.waitForBytesWritten(200L))
    return;
    QByteArray rsp;
    while (testPort.waitForReadyRead(20L)) {
    rsp += testPort.readAll();
    if (rsp.size() == expectedSize)
    break;
    }

    if (rsp.size() != expectedSize)
        return;
    
    // parse rsp ...
    ...
    

    [/code]


Log in to reply