Unsolved Cannot output a value using QSerialPort
-
I am not sure why Qt is not outputting a value in the GUI I have made using QSerialPort. The code compiles, and all the syntax is formatted correctly. I have tried looking at different forum posts, but I am unable to pinpoint the error.
I am currently testing with a breadboard, circuit, and light bulb; all the hardware works and I am able to capture a voltage in the Arduino software (I can add the Arduino code if need be).
The issue I am having is that I can't display a voltage in Qt. I am using an Arduino Uno and an Arduino Voltage sensor (VCC <25V).
voltage_sensor.pro
QT += core gui serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = voltage_sensor TEMPLATE = app # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked 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 it uses 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 \ dialog.cpp HEADERS += \ dialog.h FORMS += \ dialog.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
dialog.h
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include <QtSerialPort/QSerialPortInfo> #include <QByteArray> QT_BEGIN_NAMESPACE namespace Ui { class Dialog; } QT_END_NAMESPACE class Dialog : public QDialog { Q_OBJECT public: Dialog(QWidget *parent = nullptr); ~Dialog(); private slots: void readSerial(); void updateVoltage(QString); private: Ui::Dialog *ui; QSerialPort *arduino; static const quint16 arduino_uno_vendor_id = 9025; static const quint16 arduino_uno_product_id = 67; QByteArray serialData; QString serialBuffer; QString parsed_data; double voltage_value; }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" #include <QSerialPort> #include <QSerialPortInfo> #include <string> #include <QDebug> #include <QMessageBox> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); ui->voltagelcdNumber->display("-------"); arduino = new QSerialPort(this); serialBuffer = ""; parsed_data = ""; voltage_value = 0.0; bool arduino_is_available = false; QString arduino_uno_port_name; foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()){ if(serialPortInfo.hasProductIdentifier() && serialPortInfo.hasVendorIdentifier()){ if((serialPortInfo.productIdentifier() == arduino_uno_product_id) && (serialPortInfo.vendorIdentifier() == arduino_uno_vendor_id)){ arduino_is_available = true; arduino_uno_port_name = serialPortInfo.portName(); } } } if(arduino_is_available) { qDebug()<<"Found the port \n"; arduino->setPortName(arduino_uno_port_name); arduino->open(QSerialPort::ReadOnly); arduino->setBaudRate(QSerialPort::Baud9600); arduino->setDataBits(QSerialPort::Data8); arduino->setFlowControl(QSerialPort::NoFlowControl); arduino->setParity(QSerialPort::NoParity); arduino->setStopBits(QSerialPort::OneStop); QObject::connect(arduino, SIGNAL(readyRead), this, SLOT(readSerial())); } else { qDebug()<<"Could not find the correct port \n"; QMessageBox::information(this,"Serial Port Error", "Could not open the serial port"); } } Dialog::~Dialog() { if(arduino->isOpen()) { arduino->close(); } delete ui; } void Dialog::readSerial() { QStringList buffer_split = serialBuffer.split(","); if(buffer_split.length() < 3) { serialData = arduino->readAll(); serialBuffer = serialBuffer + QString::fromStdString(serialData.toStdString()); serialData.clear(); } else { serialBuffer = ""; qDebug() << buffer_split << "\n"; parsed_data = buffer_split[1]; voltage_value = (parsed_data.toDouble()) - 0.1; qDebug() << "Voltage: " << voltage_value << "\n"; parsed_data = QString::number(voltage_value,'g',4); Dialog::updateVoltage(parsed_data); } } void Dialog::updateVoltage(QString sensor_reading) { ui->voltagelcdNumber->display(sensor_reading); }
main.cpp
#include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.setWindowTitle("Voltage Sensor"); w.setFixedSize(434,122); w.show(); return a.exec(); }
dialog.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>449</width> <height>157</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <layout class="QGridLayout" name="gridLayout"> <item row="0" column="0"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="voltagelabel"> <property name="text"> <string><html><head/><body><p align="center"><span style=" font-size:24pt; font-weight:600; color:#ff0000;">Voltage</span></p></body></html></string> </property> </widget> </item> <item> <widget class="QLCDNumber" name="voltagelcdNumber"> <property name="palette"> <palette> <active> <colorrole role="WindowText"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>0</red> <green>0</green> <blue>255</blue> </color> </brush> </colorrole> <colorrole role="Light"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Dark"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Text"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> <colorrole role="ButtonText"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> <colorrole role="PlaceholderText"> <brush brushstyle="SolidPattern"> <color alpha="128"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> </active> <inactive> <colorrole role="WindowText"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>0</red> <green>0</green> <blue>255</blue> </color> </brush> </colorrole> <colorrole role="Light"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Dark"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Text"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> <colorrole role="ButtonText"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> <colorrole role="PlaceholderText"> <brush brushstyle="SolidPattern"> <color alpha="128"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> </inactive> <disabled> <colorrole role="WindowText"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Light"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Dark"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="Text"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="ButtonText"> <brush brushstyle="SolidPattern"> <color alpha="255"> <red>20</red> <green>20</green> <blue>85</blue> </color> </brush> </colorrole> <colorrole role="PlaceholderText"> <brush brushstyle="SolidPattern"> <color alpha="128"> <red>0</red> <green>0</green> <blue>0</blue> </color> </brush> </colorrole> </disabled> </palette> </property> <property name="digitCount"> <number>7</number> </property> </widget> </item> </layout> </item> </layout> </widget> <resources/> <connections/> </ui>
Application Output
Found the port
-
Maybe this statement doesnot work.
QObject::connect(arduino, SIGNAL(readyRead), this, SLOT(readSerial()));
Maybe the “readyReady” function lack of “()”,or you can try set breakpoint in slot readSerial() to ensure the slot is performed. -
@Simon-sun said in Cannot output a value using QSerialPort:
Maybe the “readyReady”
Not maybe - it does.
Use the new signal/slot syntax to avoid such errors.
-
Thank you for the replies although I'm not 100% sure how I would implement this. Is there code I need to add, or even take away?
-
Your connect statement is simply wrong and if you would have checked the return value you would have seen it by yourself. See https://wiki.qt.io/New_Signal_Slot_Syntax for the new signal/slot syntax
-
I just need to receive from the serial port, with the new syntax it requires a sender, &sender function which I cannot use / don't need
-
I changed
QObject::connect(arduino, SIGNAL(readyRead), this, SLOT(readSerial()));
toQObject::connect(arduino, 0, 0, 0, Qt::ConnectionType());
and I got the same output -
@jude-bato said in Cannot output a value using QSerialPort:
he new syntax it requires a sender, &sender function which I cannot use / don't need
Please please take some time to read the link suggested for @Christian-Ehrlicher and try to understand the concepts of signal & slot under Qt
Tip 1 : sender is a Qt object, and is the sender of a signal; an object that under some conditions will emit (send) a signal
Tip 2: your sender is arduino object -
I was reviewing the link and with trial and error I began trying to implement the new syntax. Saying that, part of the
QObject::connect
requiresconst char *signal
which I have no idea what that means. -
Reading on the new syntax I updated my Qt version as a troubleshooting method and put in
QObject::connect(arduino, &QSerialPort::readyRead, this, &Dialog::readSerial);
and the Application output isno member named 'connect' in 'QDebug'.
I'm very lost -
@jude-bato Please show the code where you call connect()
-
@jsulm
QObject::connect(arduino, SIGNAL(readyRead), this, SLOT(readSerial()));
This is where connect should be called, but with the new syntax I very confused on how I can connect and read from Arduino into Qt -
Hi,
You signal specification is still wrong in the connect statement.
In any case, as already requested several times: please post the current code you are using.
-
@jude-bato Why do you post again your old connect() call (which is wrong because the signal is missing brackets - readyRead())?
Please post the code where you call connect() with new syntax (without SIGNAL/SLOT) and not just the connect() call itself but also the surrounding code... -
QObject::connect(arduino, &QSerialPort::readyRead, this, &Dialog::readSerial);
This is the code line that I have integrated in my current project, I'm just not sure how to convert it to the new syntax. I was using the old code because in the original question I wanted to specify where I was talking about. I know it was wrong and I changed it already. The problem I'm having is with the new syntax. -
@jude-bato And with that code line you get "no member named 'connect' in 'QDebug'"?
-
@jude-bato said in Cannot output a value using QSerialPort:
This is the code line
If you're looking for some help in the forum please make others' life easier.
Why is so difficult to show some code snippet of yours? not just ONE line.
Come on, some context helps understand what might be going on with your issue. -
This is the code snippet, its in my dialog.cpp file
if(arduino_is_available) { qDebug()<<"Found the port \n"; arduino->setPortName(arduino_uno_port_name); arduino->open(QSerialPort::ReadOnly); arduino->setBaudRate(QSerialPort::Baud9600); arduino->setDataBits(QSerialPort::Data8); arduino->setFlowControl(QSerialPort::NoFlowControl); arduino->setParity(QSerialPort::NoParity); arduino->setStopBits(QSerialPort::OneStop); connect(*arduino, Dialog::readSerial(updateVoltage()),this,readSerial()); //too few arguments to function call, expected 1, have 0 } else { qDebug()<<"Could not find the correct port \n"; QMessageBox::information(this,"Serial Port Error", "Could not open the serial port"); } }
and the read serial code I have:
void Dialog::readSerial() { QStringList buffer_split = serialBuffer.split(","); if(buffer_split.length() < 3) { serialData = arduino->readAll(); serialBuffer = serialBuffer + QString::fromStdString(serialData.toStdString()); serialData.clear(); } else { serialBuffer = ""; qDebug() << buffer_split << "\n"; parsed_data = buffer_split[1]; voltage_value = (parsed_data.toDouble()) - 0.1; qDebug() << "Voltage: " << voltage_value << "\n"; parsed_data = QString::number(voltage_value,'g',4); Dialog::updateVoltage(parsed_data); } }
-
Hi,
One thing that is missing: you don't check that the open call is successful. You should add that.
-
@jude-bato said in Cannot output a value using QSerialPort:
connect(*arduino, Dialog::readSerial(updateVoltage()),this,readSerial());
Again, please read the documentation regarding signal and slots. You may want to try this article as well.
Tip: a typical connect sentence has 4 elements, try to identify such elements within your code...
Dialog::updateVoltage(parsed_data);
Do you know why you're calling an static method here?