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 -
@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!
-
@klaus-schwarzkopf
If you look carefully, yourreadLine()
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.