QML Slot not displaying double value from serial input

667 Views Asked by At

I'm struggling to get my serial input "analogread2" converted to a double, to display in QML.

Ive added the Q_property, the root context in the main.cpp, and I can add the property in the qml, but I cant get it to display in text format.

QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
SerialPort serialport;
//engine.rootContext()->setContextProperty("serialport", &serialport);
qmlRegisterType<SerialPort>("SerialPortlib", 1, 0, "SerialPort");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")))

header.

Q_PROPERTY(double newValue MEMBER m_oil_pressure_volt WRITE set_oil_pressure_volt NOTIFY oil_pressure_volt_Changed )

qml

Window {
    visible: true
    width: 640
    height: 480
    id: gauge

    SerialPort{
        // what would I put in here to display the text value (double)
    }
}

any help is much appreciated.

1

There are 1 best solutions below

15
eyllanesc On BEST ANSWER

To do the test I am assuming that you are sending the data from the arduino in one of the following ways:

Serial.println(data);
Serial.print(data);

Assuming the above has been implemented the serialport class, this has a function called openDefault that scans the devices that are connected through serial and searches for the word "Arduino" within description or manufacturer and if one finds it connects to it.

The complete code can be found at: https://github.com/eyllanesc/stackoverflow/tree/master/Arduino-QML

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();

signals:
    void oil_pressure_volt_Changed(double newValue);

private:
    QSerialPort *arduino;

    double mOil_pressure_volt;

    QSerialPortInfo portInfo;

    void openDefault();
};

serialport.cpp

#include "serialport.h"

#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();

        QString value = QString(data).trimmed();
        qDebug()<< value;
        bool ok;
        double val = value.toDouble(&ok);
        if(ok)
            set_oil_pressure_volt(val);
    }
}

void SerialPort::openDefault()
{
    for(auto info: QSerialPortInfo::availablePorts()){
        qDebug()<<info.portName()<<info.description()<<info.manufacturer();
        if(!info.isBusy() && (info.description().contains("Arduino") || info.manufacturer().contains("Arduino"))){
            portInfo = info;
            break;
        }
    }

    if(portInfo.isNull()){
        return;
    }

    arduino->setPortName(portInfo.portName());
    arduino->setBaudRate(QSerialPort::Baud115200);
    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;
}

Example:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "serialport.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlRegisterType<SerialPort>("SerialPortLib", 1, 0, "SerialPort");


    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

main.qml

import QtQuick 2.6
import QtQuick.Window 2.2
import SerialPortLib 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Test")

    SerialPort{
        onOil_pressure_voltChanged: {
            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
    }
}