Qt gui with arduino
-
I am using QtSerial to toggle the LED on arduino. I have my gui and arduino codes ready but I can't really figure out how to link these codes.
I am using radio buttons, when the user selects "On", 13 is sent to the serial port to select pin 13 on arduino.
Both, the QT code and the arduino codes are running fine on their respective IDEs but how to make them work together? Do i need to copy the code from arduino IDE to the main.cpp in QtCreator? -
Hi and welcome to devnet,
Are you trying to put together the code that is running on the arduino and your desktop application ?
-
Do you want to develop the Arduino side with Qt Creator or are you trying to mix the two sources ?
In the second case, that would be no. You are building your GUI for desktop machine which is usually x86 or x86_64 while the Arduino is a completely different beast. And in this case, the code for the Arduino board should not be mixed with your application.
-
@jkprog So you can type 13 in the Arduino IDE serial console, send it to the Arduino device and it reacts correctly? If so, the Arduino part should be fine. Close the Arduino IDE so that it doesn't keep the serial port reserved or anything. The Arduino code will stay in the Arduino, the IDE doesn't actually have anything to do with it after you have uploaded the code into the device, it just happens to be that you can use it to manually communicate with the device.
In your Qt app you open the serial port, presumably using QSerialPortInfo and QSerialPort, is that so? What actually happens? Have you tried catching all signals from QSerialPort, especially errorOccurred? Seeing your Qt serial code (opening and using the connection) would of course help.
-
Yeah everything works fine on the arduino code.
Yes I am using QSerialPortInfo and QSerial to communicate with serial port.
I am getting the error: "couldn't write to serial" . I dont know whats wrong..This is my code:
The project file:
QT += core gui serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = try1 TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h FORMS += mainwindow.ui
mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPort> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_On_clicked(bool checked); void on_Off_clicked(bool checked); private: Ui::MainWindow *ui; QSerialPort *arduino; static const quint16 arduino_mega_vendor_id = 9025; static const quint16 arduino_mega_product_id = 66; QString arduino_port_name; bool arduino_is_available; }; #endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QSerialPort> #include <QSerialPortInfo> #include <QDebug> #include <QString> #include <QtWidgets> // Initialize Serial QSerialPort serial; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); arduino_is_available = false; arduino_port_name = ""; arduino = new QSerialPort; /* qDebug() << "Number of available ports: " << QSerialPortInfo::availablePorts().length(); // for each available serial port, get the product and vendor ID foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { qDebug() << "Has vendor ID: " << serialPortInfo.hasVendorIdentifier(); if(serialPortInfo.hasVendorIdentifier()) { qDebug() << "Vendor ID: " << serialPortInfo.vendorIdentifier(); } qDebug() << "Has product ID: " << serialPortInfo.hasProductIdentifier(); if(serialPortInfo.hasProductIdentifier()) { qDebug() << "Product ID: " << serialPortInfo.productIdentifier(); } } */ foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { if(serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()) { if(serialPortInfo.vendorIdentifier() == arduino_mega_vendor_id) { if(serialPortInfo.productIdentifier() == arduino_mega_product_id) { arduino_port_name = serialPortInfo.portName(); arduino_is_available = true; } } } if(arduino_is_available) { // open and configure the port arduino->setPortName(arduino_port_name); arduino->open(QSerialPort::WriteOnly); arduino->setBaudRate(QSerialPort::Baud9600); arduino->setDataBits(QSerialPort::Data8); arduino->setParity(QSerialPort::NoParity); arduino->setStopBits(QSerialPort::OneStop); arduino->setFlowControl(QSerialPort::NoFlowControl); } else { // give error message QMessageBox::warning(this, "Port error", "Couldn't find the Arduino!"); } } } MainWindow::~MainWindow() { if(arduino->isOpen()) { arduino->close(); } delete ui; } void MainWindow::on_On_clicked(bool checked) { if(checked == true) { ui->lcdNumber->display(1); if (serial.isOpen() && serial.isWritable()) { QByteArray ba("13"); serial.write(ba); serial.flush(); qDebug() << "data has been send" << endl; serial.close(); } else { qDebug() << "Couldn't write to serial!"; } } } void MainWindow::on_Off_clicked(bool checked) { if(checked == true) { ui->lcdNumber->display(0); if (serial.isOpen() && serial.isWritable()) { QByteArray ba("13"); serial.write(ba); serial.flush(); qDebug() << "data has been send" << endl; serial.close(); } else { qDebug() << "Couldn't write to serial!"; } } }
main.cpp:
#include "mainwindow.h" #include <QApplication> #include <QtCore/QCoreApplication> #include <QtCore/QDebug> #include <QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QString> QT_USE_NAMESPACE int main(int argc, char *argv[]) { QApplication a(argc, argv); QSerialPortInfo info("COM3"); // Check info of the port qDebug() << "Name: " << info.portName(); qDebug() << "Manufacturer " << info.manufacturer(); qDebug() << "Busy: " << info.isBusy() << endl; QSerialPort serial; MainWindow w; w.show(); return a.exec(); }
When I run this project, my output is:
Name: "COM3" Manufacturer "Arduino LLC (www.arduino.cc)" Busy: false Couldn't write to serial! Couldn't write to serial! Couldn't write to serial!
-
@jkprog I don't understand what you're trying to do with QSerialPort objects. I haven't actually used the class myself, but I believe in this case you should have only one instance (QSerialPort *arduino) which you can initialize as you do now. Then you should use that same instance for writing - why do you have that extra QSerialPort serial; and why do you initialize it that way? It's not actually initialized with any meaningful values at all.
EDIT: you can set the mainwindow as the parent for QSerialPort, it will be automatically closed on destruction, no need to close it explicitly if it's meant to have the same lifetime as the mainwindow.
-
I modified my code so that now it sends data to serial port, but I want to send data as ASCII to serial port since the code on arduino requires ascii characters.
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QSerialPort> #include <QSerialPortInfo> #include <QDebug> #include <QString> #include <QtWidgets> #include <QString> // Initialize Serial QSerialPort serial; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); arduino_is_available = false; arduino_port_name = ""; arduino = new QSerialPort; /* qDebug() << "Number of available ports: " << QSerialPortInfo::availablePorts().length(); // for each available serial port, get the product and vendor ID foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { qDebug() << "Has vendor ID: " << serialPortInfo.hasVendorIdentifier(); if(serialPortInfo.hasVendorIdentifier()) { qDebug() << "Vendor ID: " << serialPortInfo.vendorIdentifier(); } qDebug() << "Has product ID: " << serialPortInfo.hasProductIdentifier(); if(serialPortInfo.hasProductIdentifier()) { qDebug() << "Product ID: " << serialPortInfo.productIdentifier(); } } */ foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { if(serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()) { if(serialPortInfo.vendorIdentifier() == arduino_mega_vendor_id) { if(serialPortInfo.productIdentifier() == arduino_mega_product_id) { arduino_port_name = serialPortInfo.portName(); arduino_is_available = true; } } } if(arduino_is_available) { // open and configure the port arduino->setPortName(arduino_port_name); arduino->open(QSerialPort::WriteOnly); arduino->setBaudRate(QSerialPort::Baud9600); arduino->setDataBits(QSerialPort::Data8); arduino->setParity(QSerialPort::NoParity); arduino->setStopBits(QSerialPort::OneStop); arduino->setFlowControl(QSerialPort::NoFlowControl); } else { // give error message QMessageBox::warning(this, "Port error", "Couldn't find the Arduino!"); } } } MainWindow::~MainWindow() { if(arduino->isOpen()) { arduino->close(); } delete ui; } void MainWindow::on_On_clicked(bool checked) { //int val = 13; QString val = QString::number ( 13 ); if(checked == true) { MainWindow::updateValue(QString("b%1").arg(val)); arduino->flush(); qDebug() << "data has been send" << endl; qDebug() << val; } else { qDebug() << "Couldn't write to serial!"; } } void MainWindow::on_Off_clicked(bool checked) { int val = 13; if(checked == true) { MainWindow::updateValue(QString("b%1").arg(val)); arduino->flush(); qDebug() << "data has been send" << endl; qDebug() << val; } } void MainWindow::updateValue(QString command) { if(arduino->isWritable()) { arduino->write(command.toStdString().c_str()); //arduino->write(command.toStdString()); } else { qDebug() << "Couldn't write to serial!"; } }
The output is:
Name: "COM3" Manufacturer "Arduino LLC (www.arduino.cc)" Busy: false data has been send "13" data has been send 13 data has been send "13"
-
@jkprog Hii Could you show me the IDE Code