Reading UART (RS485) with Qt



  • Hello everyone,
    I'm trying to read a byte stream with Qt, later I want to send packets with integers. I can see the data on HTerm, but with Qt I have trouble getting it. The AT90 sends ones a second, about 100 bytes. I wrote the following code:

    #include <QCoreApplication>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <QDebug>
    
    static QSerialPort *serial;        //serial port
    
    static void open_serial();
    static void close_serial();
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        serial = new QSerialPort;
        open_serial();
    
        QByteArray data_in;                 //incoming data
    
        for(int i = 0; i < 10; i++){
    
            data_in.append(serial->readAll());
            qDebug() << "Empfangene Daten: " << data_in;
            //data_in.clear();
        }
    
        close_serial();
        qDebug() << "Serial closed";
    
        return a.exec();
    }
    
    static void open_serial()
    {
        serial->setPortName("COM14");
        serial->setBaudRate(QSerialPort::Baud57600);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
    
        //connect(serial,SIGNAL(readyRead()),this,SLOT(serialReceived()));
    
    
    
        if (serial->open(QIODevice::ReadWrite))
        {
            qDebug() << "Connected AT90CAN\n";
        } else
        {
            qDebug() << "can not connect AT90CAN\n";
        }
    }
    
    static void close_serial()
    {
        serial->close();
    }
    

    And I get:

    Connected AT90CAN
    
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Empfangene Daten: ""
    Serial closed
    

    What am I doing wrong? Thanks for your help.



  • @SheldonC said in Reading UART (RS485) with Qt:

    What am I doing wrong?

    Not using QSerialPort with Qt signal & slots approach (event-driven way).
    Please take a look at serial terminal example where you'll see how data is read when it is available

    When the serial port receives new data, the signal readyRead() is emitted, and that signal is connected to the MainWindow::readData() slot

    void MainWindow::readData() {
        const QByteArray data = m_serial->readAll();
        m_console->putData(data);
    }
    


  • Hi,
    I am still experiencing the same problem, in the meantime I switched to the terminal example and installed a second Qt on a Linux virtual box. But that does not work with the UART either.
    On Windows I can connect, but I get no data and on Linux comes "permission denied" as soon as I try to connect. Does anyone have a solution to either problem?



  • @SheldonC said in Reading UART (RS485) with Qt:

    I am still experiencing the same problem,

    Have you changed your code to use signals & slots?

    Linux comes "permission denied" as soon as I try to connect

    Does the user you run the Qt example have the proper rights to access the serial port? Check this answer just in case



  • Thank you, it works with Linux now.
    With Windows it doesn't work with signals and slots either.


  • Qt Champions 2018

    @SheldonC

    With Windows it doesn't work with signals and slots either.

    Can you show your code?



  • @SheldonC said in Reading UART (RS485) with Qt:

    serial

    you need make sure the serial buffer has data before you call the serial->readAll():
    int bytes=serial->bytesAvailable();
    if(bytes>0){
    data_in=serial->readAll();
    do anything...
    }

    by the way, you can use the signal-slot without MainWindow, it is work well:
    class SerialMng: public QThread{
    signal:
    void gotData(QByteArray);
    protect:
    void run(){
    while(1){
    int bytes=serial->bytesAvailable();
    if(bytes>0){
    QByteArray dat=serial->readAll();
    emit gotData(dat);
    }
    };
    }
    };
    class SerialData{
    slots:
    void procData(QByteArray dat){
    do anything...
    }
    };
    in main:
    SerialMng *mng=new SerialMng();
    mng->start();

    SerialData *dat=new SerialData();
    connect(mng,SIGNAL(gotData(QByteArray)),dat,SLOT(procData(QByteArray));


  • Lifetime Qt Champion

    @RunThiner There's no need for such a loop. QSerialPort already provides an asynchronous API and if you really want to wait for data to be available, there's a blocking API for that as shown in the QSerialPort details.