QT serial communications
-
I am trying to rig up some basic serial communications in QT
I am getting the port COM19 from QSerialPortInfo, and I speaking successfully to the port via Arduino. However, I cannot get anything back via QT.
@
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>int main(int argc, char *argv[]) { QApplication a(argc, argv); foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){ qDebug() << "Name :" << info.portName(); qDebug() << "Description :" << info.description(); qDebug() << "Manufactuer :" << info.manufacturer(); QSerialPort serial; serial.setPort(info); if(serial.open(QIODevice::ReadWrite)) qDebug() << serial.errorString(); serial.write("M114 \n"); qDebug() << serial.readAll(); serial.close(); // Now we need to send and receive commands serial.setPortName("COM19"); serial.setBaudRate(QSerialPort::Baud57600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); serial.setFlowControl(QSerialPort::NoFlowControl); if(serial.open(QIODevice::ReadWrite)){ qDebug() << "opened"; }else{ qDebug() << "Not opened"; } qDebug() << serial.errorString(); serial.write("M114 \n"); qDebug() << serial.readAll(); serial.close(); } MainWindow w; w.show(); return a.exec(); }
@
As you can see, I am trying a simple connection along the lines of the documentation, and one where I write out all the baud rate information. They throw two different errors.
Like I said, I am connecting via arduino to this same port and having success. Any ideas what's wrong?
@Name : "COM19" Description : "USB Serial (Communication Class, Abstract Control Model)" Manufactuer : "PJRC.COM, LLC." "Unknown error" "" opened "The handle is invalid." ""
@
Any ideas for what I am doing wrong?
My idea is to send commands to the device, and read them back to the console.
-
Hi,
You are not using QSerialPort correctly, please have a look at the "terminal example":https://qt-project.org/doc/qt-5.1/qtserialport/terminal.html to see how you should do it.
-
Tried to compile the linked example:
@
12:10:53: Running steps for project terminal...
12:10:53: Configuration unchanged, skipping qmake step.
12:10:53: Starting: "C:\Qt\Tools\mingw48_32\bin\mingw32-make.exe"
C:/Qt/Tools/mingw48_32/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'C:/Qt/Tools/QtCreator/bin/build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug'
g++ -Wl,-subsystem,windows -mthreads -o debug/terminal.exe debug/main.o debug/mainwindow.o debug/console.o debug/settingsdialog.o debug/qrc_terminal.o debug/moc_mainwindow.o debug/moc_console.o debug/moc_settingsdialog.o -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmaind -LC:\Qt\5.1.1\mingw48_32\lib -lQt5Widgetsd -lQt5Guid -lQt5Cored
debug/mainwindow.o: In functionZN10MainWindowC2EP7QWidget': C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:17: undefined reference to
_imp___ZN11QSerialPortC1EP7QObject'
debug/mainwindow.o: In functionZN10MainWindow14openSerialPortEv': C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:43: undefined reference to
_imp___ZN11QSerialPort11setPortNameERK7QString'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:45: undefined reference to_imp___ZN11QSerialPort11setBaudRateEi6QFlagsINS_9DirectionEE' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:46: undefined reference to
_imp___ZN11QSerialPort11setDataBitsENS_8DataBitsE'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:47: undefined reference to_imp___ZN11QSerialPort9setParityENS_6ParityE' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:48: undefined reference to
_imp___ZN11QSerialPort11setStopBitsENS_8StopBitsE'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/mainwindow.cpp:49: undefined reference to_imp___ZN11QSerialPort14setFlowControlENS_11FlowControlE' debug/settingsdialog.o: In function
ZN14SettingsDialog13fillPortsInfoEv':
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:112: undefined reference to_imp___ZN15QSerialPortInfo14availablePortsEv' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:119: undefined reference to
_imp___ZNK15QSerialPortInfo17productIdentifierEv'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:119: undefined reference to_imp___ZNK15QSerialPortInfo17productIdentifierEv' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:118: undefined reference to
_imp___ZNK15QSerialPortInfo16vendorIdentifierEv'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:118: undefined reference to_imp___ZNK15QSerialPortInfo16vendorIdentifierEv' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:117: undefined reference to
imp___ZNK15QSerialPortInfo14systemLocationEv'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:116: undefined reference to_imp___ZNK15QSerialPortInfo12manufacturerEv' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:115: undefined reference to
imp___ZNK15QSerialPortInfo11descriptionEv'
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../terminal/settingsdialog.cpp:114: undefined reference to_imp___ZNK15QSerialPortInfo8portNameEv' debug/settingsdialog.o: In function
ZN5QListI15QSerialPortInfoE13node_destructEPNS1_4NodeES3':
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../../../../5.1.1/mingw48_32/include/QtCore/qlist.h:419: undefined reference to_imp___ZN15QSerialPortInfoD1Ev' debug/settingsdialog.o: In function
ZN5QListI15QSerialPortInfoE9node_copyEPNS1_4NodeES3_S3':
C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../../../../5.1.1/mingw48_32/include/QtCore/qlist.h:387: undefined reference to_imp___ZN15QSerialPortInfoC1ERKS_' C:\Qt\Tools\QtCreator\bin\build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug/../../../../5.1.1/mingw48_32/include/QtCore/qlist.h:393: undefined reference to
_imp___ZN15QSerialPortInfoD1Ev'
collect2.exe: error: ld returned 1 exit status
Makefile.Debug:90: recipe for target 'debug/terminal.exe' failed
mingw32-make[1]: Leaving directory 'C:/Qt/Tools/QtCreator/bin/build-terminal-Desktop_Qt_5_1_1_MinGW_32bit-Debug'
makefile:34: recipe for target 'debug' failed
mingw32-make[1]: *** [debug/terminal.exe] Error 1
mingw32-make: *** [debug] Error 2
12:10:53: The process "C:\Qt\Tools\mingw48_32\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project terminal (kit: Desktop Qt 5.1.1 MinGW 32bit)
When executing step 'Make'
12:10:53: Elapsed time: 00:01.
@I would like to run it to make sure this approach serves my needs. I got the source directly from the gitorious repo. Do you think it could be a compiler settings thing?
-
You should upgrade to the latest version of Qt before going further (5.2.1 at this time)
-
Thank you for the help so far!
OK next small question:
If I go the asych route, which looks best, how do I get the listening function to speak to sending function?
Here's my predicament:
I have file. I want to read it line by line into serial. After each successful send, the firmware on the device should read "OK"
So, it's pretty simple for the listener to check for "OK" messages. What I can't figure out, is if there is a good way for the listener to communicate with the sender.
I have a function that iterates over my file, and sends the individual commands.
Without using blocking IO, is there a way to make the sender wait for an OK before sending more commands? (if it sends too many bad things will happen), or does my use case demand blocking IO in a separate thread?
-
No it doesn't need that. You can implement it using signals and slots. Build something like a QQueue of command and have a slot taking a command form the queue and send it (let's name it sendNextCommand()). In the slot where you receive the data from the serial port, use QTimer::singleShot(0, this, SLOT(sendNextCommand())) when you receive the OK so it does everything automatically for you