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

Ubuntu 18.04 USBTMC device read issue



  • Hello,
    i want to read from the device /dev/usbtmc2. It's a Keithley 2110 multimeter.

    Here is my test code:

    #include <QCoreApplication>
    
    #include <QElapsedTimer>
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    #include <QDebug>
    #include <QFile>
    
    char bytes[60] = {0};
    int fd ;
    
    int main(int argc, char *argv[])
    {
    
    #if QT_VERSION >= 0x050000
        // Qt5 code
        //http://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
        qSetMessagePattern("%{function}:%{line}: %{message}");
    #endif
    
        QElapsedTimer timer;
    
    
        QString line;
        QFile file("/dev/usbtmc2");
    
        qDebug() << "buffered qt";
        if (file.exists() && file.open(QIODevice::ReadWrite | QIODevice::Text))
        {
    
            file.write("*IDN?\n");
            timer.start();
            line = file.readAll();
            qDebug() << "readAll:" << line << timer.elapsed();
    
            file.write("*IDN?\n");
            timer.start();
            line = file.read(57);
            qDebug() << "read 57:" << line << timer.elapsed();
    
            file.write("*IDN?\n");
            timer.start();
            line = file.read(60);
            qDebug() << "read 60:"<< line << timer.elapsed();
    
            file.write("*IDN?\n");
            timer.start();
            line = file.readLine();
            qDebug() << "readLine:" << line << timer.elapsed();
    
            file.close();
        }
    
        qDebug() << "unbuffered qt";
        if (file.exists() && file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Unbuffered))
        {
    
            file.write("*IDN?\n");
            timer.start();
            line = file.readAll();
            qDebug() << "readAll:" << line << timer.elapsed();
    
            file.write("*IDN?\n");
            timer.start();
            line = file.read(57);
            qDebug() << "read 57:" << line << timer.elapsed();
    
            file.write("*IDN?\n");
            timer.start();
            line = file.read(60);
            qDebug() << "read 60:"<< line << timer.elapsed();
    
            file.write("*IDN?\n");
            timer.start();
            line = file.readLine();
            qDebug() << "readLine:" << line << timer.elapsed();
    
            file.close();
        }
    
    
        qDebug() << "linux low level";
    
        fd = open("/dev/usbtmc2", O_RDWR | O_NONBLOCK);
        write(fd, "*IDN?\n", 6);
        timer.start();
        read(fd, &bytes, 60);
        line = QString(bytes);
        qDebug() << "read 60:" << line << timer.elapsed();
    
        close(fd);
    
        return 0;
    }
    
    

    Output:

    main:31: buffered qt
    main:38: readAll: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 10144
    main:43: read 57: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 5119
    main:48: read 60: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 5119
    main:53: readLine: "KH TE .D2,2,03\n" 2
    main:58: unbuffered qt
    main:65: readAll: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 10236
    main:70: read 57: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 0
    main:75: read 60: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 5119
    main:80: readLine: "KH TE .D2,2,03\n" 2
    main:86: linux low level
    main:93: read 60: "KEITHLEY INSTRUMENTS INC.,MODEL 2110,8012620,02.03-03-20\n" 0
    

    I don't know, why it takes such a long time in buffered mode and especially the readAll function. Why does the readLine function loss chars?
    The only fast way, i see, is to use the qt read function when i exactly know the size or i use the Linux low level file functions.

    What is my mistake? Can someone explain it to me.

    Best Regards,
    Klaus


  • Qt Champions 2020

    @klaus-schwarzkopf , qfile implements only the usual file access. But you want to use the device access! Just use the native POSIX API and use the qsocketnotifier to watch for a data change.



  • that of course assumes qsocketnotifier actually works outside of the standard Qt event loop. OP isn't event using the Qt event handler so it's questionable what features will work and which ones won't. They would be better off ditching Qt altogether if they are going to use a structured sequential programming approach to communicating with the device. Qt is meant for event driven programming!



  • @kuzulis I thought i can do it with qt too.



  • @klaus-schwarzkopf
    If you look carefully, your readLine() ones are displaying exactly every 4th character! I have no idea why... :)



  • @Kent-Dorfman It's only an example to show the differences. The event loop isn't necessary in this example. But i understand what you mean.

    I will have a look at the qsocketnotifier. Thanks.


Log in to reply