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

QML : Read data from Serial Port



  • I am working over QT quick kiosk based GUI application and communicating with Arduino to send and receive data over serial port. I've successfully sent and received the data between Arduino and QT Single QML file.

    Issue : I've two QML files: main.qml and sample.qml, Sending the data on button press from main.qml and receiving some string data on sample.qml. I am successfully sending the data from main.qml and but not able to read the data from sample.qml. I realized the issue is because of re-initializing serial port in sample.qml file.

    If anyone can help me out with this problem, It would be greatly appreciated.Thanks in advance.

    Serialport.cpp

    #include "serialport.h"
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <QDebug>
    
    SerialPort::SerialPort(QObject *parent):QObject(parent)
    {
    
        arduino = new QSerialPort(this);
        connect(arduino, &QSerialPort::readyRead, this, &SerialPort::onReadData);
        openDefault();
    }
    
    SerialPort::~SerialPort()
    {
        delete arduino;
    }
    
    void SerialPort::set_oil_pressure_volt(double newValue)
    {
        if (mOil_pressure_volt == newValue)
            return;
    
        mOil_pressure_volt = newValue;
        emit oil_pressure_volt_Changed(mOil_pressure_volt);
    }
    
    void SerialPort::onReadData()
    {
        if(arduino->bytesAvailable()>0){
    
            QByteArray data = arduino->readAll();
            qDebug()<<QString(data).trimmed();
            QString value = QString(data).trimmed();
            bool ok;
            double val = value.toDouble(&ok);
            if(ok)
                set_oil_pressure_volt(val);
        }
    }
    
    void SerialPort::onWriteData(const QByteArray &data)
    {
        arduino->write(data);
        qDebug() << data;
    }
    
    
    void SerialPort::openDefault()
    {
        for(auto info: QSerialPortInfo::availablePorts()){
            qDebug()<<info.portName()<<info.description()<<info.manufacturer();
            if(!info.isBusy() && (info.description().contains("USB Serial Devic") || info.manufacturer().contains("Microsoft"))){
                portInfo = info;
                break;
            }
        }
    
        if(portInfo.isNull()){
            return;
        }
    
        arduino->setPortName(portInfo.portName());
        arduino->setBaudRate(QSerialPort::Baud9600);
        arduino->setDataBits(QSerialPort::Data8);
        arduino->setParity(QSerialPort::NoParity);
        arduino->setStopBits(QSerialPort::OneStop);
        arduino->setFlowControl(QSerialPort::NoFlowControl);
    
        if(arduino->open(QSerialPort::ReadWrite))
            qDebug()<<"Connected to "<< portInfo.manufacturer()<< " on " << portInfo.portName();
        else
            qCritical()<<"Serial Port error: " << arduino->errorString();
    
    }
    
    double SerialPort::get_oil_pressure_volt() const
    {
        return mOil_pressure_volt;
    }
    
    

    Serialport.h

    #ifndef SERIALPORT_H
    #define SERIALPORT_H
    
    #include <QObject>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    
    class SerialPort : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(double oil_pressure_volt READ get_oil_pressure_volt WRITE set_oil_pressure_volt NOTIFY oil_pressure_volt_Changed )
    
    public:
        SerialPort(QObject *parent = 0);
        ~SerialPort();
    
        double get_oil_pressure_volt() const;
        void set_oil_pressure_volt(double newValue);
    
    public slots:
        void onReadData();
        void onWriteData(const QByteArray &data = QByteArray("r255"));
    
    
    signals:
        void oil_pressure_volt_Changed(double newValue);
    
    private:
        QSerialPort *arduino;
        static const quint16 arduino_uno_vendor_id = 9025;
        static const quint16 arduino_uno_product_id = 67;
    
        double mOil_pressure_volt;
    
        QSerialPortInfo portInfo;
    
        void openDefault();
    };
    
    #endif // SERIALPORT_H
    
    

    main.qml code snippet:

    import QtQuick 2.13
    import QtQuick.Window 2.13
    import QtQuick.Controls 2.13
    import QtMultimedia 5.12
    
    import SerialPortLib 1.0
    
    Window {
        readonly property int appWidth: 1366
        readonly property int appHeight: 768
    
        id: root
        visible: true
        width: appWidth
        height: appHeight
        title: qsTr("V 2.0")
    
        SerialPort{
            id: serial
        }
    SwipeView{
            id: mainSwipeView
            currentIndex: 1
            anchors.fill: parent
            orientation: Qt.Vertical
            interactive: false
            Page{
                width: appWidth
                height: appHeight
                FlowButton {
                    id: flowButton
                    x: 760
                    y: 76
                    width: 373
                    height: 717
                    imageSrc: "images/A.png"
                    area.onClicked: {
                        serial.onWriteData("H")
                    }
                }
             }
           }     
    
    

    Sample.qml

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.12
    import SerialPortLib 1.0
    
    Item {
        width: 1366
        height: 768 - 80
       // title: qsTr("Test")
    
        SerialPort{
            id: abc
           onOil_pressure_voltChanged: {
                console.log("122")
                topBar.timerValue = 20
                topBar.timer.start()
                tx.text = "%1".arg(oil_pressure_volt);
            }
        }
    
        Text {
            id: tx
            anchors.fill: parent
            font.family: "Helvetica"
            font.pointSize: 20
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
        }
    }
    
    

  • Lifetime Qt Champion

    Hi,

    That's because you instantiate two objects of SerialPort class.

    One alternative is to create the instance in your main function and set it as a context property.



  • Hi @SGaist, Thanks for your kind support. Can you share some example for this. I am new to qt ad learning it.


  • Lifetime Qt Champion

    Please take a look at the documentation.



  • @SGaist Really thank you for pointing me in the right direction. The problem solved with setting context property!


Log in to reply