Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Ubuntu 18.04 USBTMC device read issue
QtWS25 Last Chance

Ubuntu 18.04 USBTMC device read issue

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 4 Posters 849 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    klaus.schwarzkopf
    wrote on last edited by
    #1

    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

    K 1 Reply Last reply
    0
    • K klaus.schwarzkopf

      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

      K Offline
      K Offline
      kuzulis
      Qt Champions 2020
      wrote on last edited by kuzulis
      #2

      @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.

      K 1 Reply Last reply
      1
      • Kent-DorfmanK Offline
        Kent-DorfmanK Offline
        Kent-Dorfman
        wrote on last edited by
        #3

        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!

        K 1 Reply Last reply
        0
        • K kuzulis

          @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.

          K Offline
          K Offline
          klaus.schwarzkopf
          wrote on last edited by
          #4

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

          JonBJ 1 Reply Last reply
          0
          • K klaus.schwarzkopf

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

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #5

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

            1 Reply Last reply
            0
            • Kent-DorfmanK Kent-Dorfman

              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!

              K Offline
              K Offline
              klaus.schwarzkopf
              wrote on last edited by
              #6

              @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.

              1 Reply Last reply
              1

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved