Problem with data read from USB port



  • Hello All,

    I am new to Qt and I need your suggestions for my problem. I have a sensor connected to USB port and I want to read the data from the sensor. I tried with QSerialPort and I am getting some random values. Could anyone please advice me where I am going wrong. Below is my source code

    #include "dialog.h"
    #include "ui_dialog.h"
    #include <QtSerialPort/QSerialPort>
    #include <QtSerialPort/QSerialPortInfo>
    #include <QDebug>
    #include <QString>
    #include <QMessageBox>
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    
        sensor = new QSerialPort(this); //sensor is included in header file as QSerialPort
        serialBuffer = ""; // included in header file as QString
    
        qDebug() << "Number of ports: " << QSerialPortInfo::availablePorts().length() << "\n";
        foreach(const QSerialPortInfo &serialportinfo, QSerialPortInfo::availablePorts())
        {
            qDebug() << "Description: " <<serialportinfo.description() << "\n";
            qDebug() << "Has vendor id: " <<serialportinfo.hasVendorIdentifier() << "\n";
            qDebug() << "vendor id: " <<serialportinfo.vendorIdentifier() << "\n";
            qDebug() << "Has product id: " <<serialportinfo.hasProductIdentifier() << "\n";
            qDebug() << "prodcut id: " <<serialportinfo.productIdentifier() << "\n";
        }
    
        bool sensor_is_available = false;
        QString sensor_port_name;
    
        foreach(const QSerialPortInfo &serialportinfo, QSerialPortInfo::availablePorts())
        {
            if(serialportinfo.hasProductIdentifier() && serialportinfo.hasVendorIdentifier())
            {
                if((serialportinfo.productIdentifier() == sensor_product_id) && (serialportinfo.vendorIdentifier() == sensor_vendor_id))
                {
                    sensor_is_available = true;
                    sensor_port_name = serialportinfo.portName();
                }
            }
        }
    
        if(sensor_is_available)
        {
            qDebug() << "Found the sensor port\n";
            sensor->setPortName(sensor_port_name);
            sensor->open(QSerialPort::ReadOnly);
            sensor->setBaudRate(QSerialPort::Baud9600);
            sensor->setDataBits(QSerialPort::Data8);
            sensor->setFlowControl(QSerialPort::HardwareControl);
            sensor->setParity(QSerialPort::NoParity);
            sensor->setStopBits(QSerialPort::OneStop);
            QObject::connect(sensor, SIGNAL(readyRead()), this, SLOT(readSerial()));
        }
    
        else{
            qDebug() << "Couldn't find the correct port for the sensor.\n";
            QMessageBox::warning (this, "Serial Port Error", "Couldn't open serial port to sensor");
        }
    }
    
    Dialog::~Dialog()
    {
        if(sensor->isOpen())
            sensor->close();
        delete ui;
    }
    
    void Dialog::readSerial()
    {
        serialData = sensor->readAll(); // serialData included in header file as QByteArray
        serialBuffer += QString::fromStdString(serialData.toStdString());
        ui->textBrowser->setText(serialBuffer);
    
        qDebug() <<serialBuffer;
        qDebug("stopped");
    }
    

    The output which I am getting is as below :

    "\r\u0014f\u0000@\np?>??>?V?>S&?\r\u0014f\u0000@\n?=?'?>?\u0005?>?$??\r\u0014f\u0000ve?????>?f|>????\r\u0014f\u0000ve?=??i>??C>????"
    stopped
    

    I am still figuring out where I went wrong. I read somewhere that data from USB port can be read through serial port functions. Could anyone advice me on the above code?

    Thank you for your time and knowledge.



  • the problem is here: serialBuffer += QString::fromStdString(serialData.toStdString());

    how does your sensor encode the data?



  • @VRonin The sensor is based on capacitive technology. Any change in capacitance gives corresponding values.



  • @pj0909 said in Problem with data read from USB port:

    values

    This still does not answer my question. how are those values represented in binary format to the serial output? is it a 32 bit integer, a 64 bit double precision float, an ASCII encoded string?



  • @VRonin Sorry, I misinterpreted your question. The answer to your question is 64 bit double precision float.


  • Moderators

    @pj0909 Then you should use http://doc.qt.io/qt-5/qbytearray.html#toDouble without converting to string:

    bool ok = false;
    serialBuffer += sensor->readAll().toDouble(&ok);
    if (!ok) // error
    


  • To add to @jsulm, you should also check that serialData contains 64 and only 64 bits of data (i.e. serialData.size()==8) otherwise use QDataStream

    void Dialog::readSerial()
    {
    QDataStream sensorStream(sensor);
    QVector<double> readValues;
    for(;;){
    sensorStream.startTransaction();
    double readValue=0;
    sensorStream >> readValue;
    if(sensorStream.commitTransaction())
    readValues.push_back(readValue);
    else
    break;
    }
    qDebug() << "data read: " << readValues;
    }
    

    P.S.
    If your sensor sends the data in little endian order, you'll have to set the QDataStream byte order http://doc.qt.io/qt-5/qdatastream.html#setByteOrder


  • Qt Champions 2016

    @pj0909 said in Problem with data read from USB port:

    The answer to your question is 64 bit double precision float.

    Then you need to read the data as binary, not as text! Something like this (warning: the code isn't really portable):

    QDataStream in(&serialData, QIODevice::ReadOnly);
    
    double value;
    in >> value;


  • I will implement the suggestions in the code and will see the output from the sensor. Will let you all know if its working correctly or still there is a problem. Thank you for the suggestions.



  • Finally I solved my problem. I set the floating point precision in addition to the suggestions given above and now I am reading the data as expected.

    Thank you all for the suggestions.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.