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

Unable to read the proper data through UART.



  • Hi,

    I am trying to communicate with my hardware through UART and trying to store in a text file. But, I am getting the garbage data.

    dialog.h

    #include "dialog.h"
    #include "ui_dialog.h"
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <QDebug>
    #include <QtWidgets>
    #include <QString>
    #include <QObject>
    #include <QApplication>
    #include <QtSerialPort>
    #include <QTimer>
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
        //ui->temp1_lcdNumber->display("-------");
        serial_is_available = false;
        port_name = "";
        serial =new QSerialPort(this);
        serialBuffer = "";
        parsed_data = "";
        temperature_value = 0.0;
        qDebug()<<"No of available ports"<<QSerialPortInfo::availablePorts().length();
    
            serial->setPortName(port_name);
            serial->open(QSerialPort::ReadWrite);
            serial->setBaudRate(QSerialPort::Baud19200);
            serial->setDataBits(QSerialPort::Data8);
            serial->setParity(QSerialPort::NoParity);
            serial->setStopBits(QSerialPort::OneStop);
            serial->setFlowControl(QSerialPort::NoFlowControl);
            connect(serial,&QSerialPort::readyRead,this,&Dialog::serialReceived);
    }
    
    
    Dialog::~Dialog()
    {
        if(serial->isOpen()){
            serial->close();
        }
        delete ui;
    }
    
    template <class T> bool hasError(const QIODevice & d) {
        return qobject_cast<const T *>(&d) && static_cast<const T &>(d).error() != T::NoError;
    }
    
    void chkError(const QIODevice & d) {
        if (hasError<QFile>(d) || hasError<QSerialPort>(d))
            qFatal("I/O Error on %s: %s", d.objectName().toLocal8Bit().constData(),
                   d.errorString().toLocal8Bit().constData());
    }
    
    void logData(QTextStream & log, const QByteArray & data) {
        log << data.toHex() << "\nLength: " << data.size() << "\n\n";
        log.flush();
        chkError(*log.device());
    }
    
    void transmit(QSerialPort & port, const QByteArray & data, QTextStream & log) {
        port.write(data);
        qDebug() << "\nWrote" << data.size() << ":" << data.toHex().constData();
        chkError(port);
        logData(log, data);
    }
    
    void receive(QSerialPort & port, QTextStream & log) {
        QByteArray data = port.readAll();
        qDebug() << "\nRead" << data.size() << ":" << data.toHex().constData();
        chkError(port);
        logData(log, data);
    }
    
    void Dialog::on_write_pushButton_clicked()
    {
        QFile logFile("Data.txt");
        if (!logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
            qFatal("Can't open the log file: %s", logFile.errorString().toLocal8Bit().constData());
        QTextStream log(&logFile);
    
        serial =new QSerialPort(this);
        serial->setPortName("COM4");
        serial->setBaudRate(QSerialPort::Baud19200);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::EvenParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
    
        if (!serial->open(QIODevice::ReadWrite))
            qFatal("Can't open the serial port: %s", serial->errorString().toLocal8Bit().constData());
    
        logFile.setObjectName("Log File");
        serial->setObjectName("Serial Port");
        //QTimer *timer = new QTimer(this);
     QMessageBox::information(this,"Motor Controller","Write data");
     QByteArray sendPacket = QByteArrayLiteral("\x01\x02");
    // sendPacket.resize(2);
    // transmit(*serial, sendPacket, log);
    // while (serial->waitForReadyRead(400))
    // {
    //     receive(*serial, log);
    //     QTimer::singleShot(300, this, SLOT(quit()));
    // }
    
     if(serial->isWritable())
     {
    
         //serial->write(output1.toStdString().c_str());
         serial->flush();
         serial->waitForBytesWritten(100);
     }
     else
     {
         qDebug()<<"write to serial";
     }
    
     while (true) {
         transmit(*serial, sendPacket, log);
         do {
             receive(*serial, log);
         } while (serial->waitForReadyRead(3000));
    
    
     //qDebug()<<output1;
    }
    }
    void Dialog::serialReceived()
    {
        /*int data1  =0;
         char *dataBuffer;
         int size = arduino->bytesAvailable();
         dataBuffer = new char[size+1];
         data1 = arduino->read(dataBuffer,size);
         dataBuffer[data1]='\0';
         //delete dataBuffer;*/
    
        QStringList buffer_split = serialBuffer.split(",");
         if(buffer_split.length() < 3){
             serialData = serial->readAll();
             serialBuffer = serialBuffer + QString::fromStdString(serialData.toStdString());
             serialData.clear();
         }else{
             serialBuffer = "";
            qDebug() << buffer_split << "\n";
             //   Dialog::updatelcd1(buffer_split[0]);
                qDebug()<<"No reading";
         }
    }
    
    

    main.cpp

    #include "dialog.h"
    #include <QApplication>
    #include <QIcon>
    #include <QPixmap>
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Dialog w;
        w.setFixedSize(960,520);
        w.setWindowIcon(QIcon(QPixmap("C:/Users/BALARAJU/Documents/icon1.png").scaled(320,300,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
        w.setWindowTitle("Motor Controller");
        w.show();
        return a.exec();
    }
    

    dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    #include <QSerialPort>
    
    namespace Ui {
    class Dialog;
    }
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget *parent = 0);
        ~Dialog();
        void serialReceived();
         void updateLCD(const QString);
         void updatelcd1(QString);
    
    
    
    private:
        Ui::Dialog *ui;
        QSerialPort *serial;
        static const quint16 serial_uno_vendorid =9025;
        static const quint16 serial_uno_productid =67;
        QString port_name;
        QByteArray serialData;
        QByteArray sendPacket;
        QString serialBuffer;
        QString parsed_data;
        double temperature_value;
        bool serial_is_available;
       // void updateLCD(QString);
    
    private slots:
    
        void on_write_pushButton_clicked();
    
    public:
    
    };
    
    #endif // DIALOG_H
    
    

    motor_controller.pro

    #-------------------------------------------------
    #
    # Project created by QtCreator 2018-03-15T17:29:54
    #
    #-------------------------------------------------
    
    QT       += core gui  serialport
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = motor_controller
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += \
            main.cpp \
            dialog.cpp
    
    HEADERS += \
            dialog.h
    
    FORMS += \
            dialog.ui
    
    DISTFILES += \
        moh.qml
    
    

    Can I know where I am doing wrong?
    I should get the like this format. I have stored into Hercules Terminal.

    ***Timestamp RTC: 1563194715
    [GENERAL EVENT] - ID=[-109] Sender=[5]
    Watchdog int occured :: 3

    Connection to server created successfully
    Time status 200

    Timestamp Server: 1563194716
    Freeing allocated databuffer

    WRITE TS 1563194715
    "duration":"0",
    "remember_me":true***


  • Lifetime Qt Champion

    Hi,

    What do you mean by garbage ?
    What does it look like ?

    serialBuffer = serialBuffer + QString::fromStdString(serialData.toStdString());

    Don't do that kind of conversion. Make serialBuffer a QByteArray and only convert it to QString if needed and when needed.

    while (true) {
    transmit(*serial, sendPacket, log);
    do {
    receive(*serial, log);
    } while (serial->waitForReadyRead(3000));

    //qDebug()<<output1;
    }

    You are creating an infinite loop without any way to exit from it. That's bad design.

    Since it looks like you want to use the blocking API, then take a look at the QSerialPort related examples to implement that.


  • Lifetime Qt Champion

    @Mohit-Tripathi If you really get garbage, then you should first check the baud rate, data bits, stop bits and parity settings.

    Also, as @SGaist said, try one of the examples, like the terminal example first.

    Once that is running, modify it to your needs.

    Regards


Log in to reply