Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt Open Serial Port But Not Write



  • I'm trying to open a serial communication with my arduino mega. I open the port and make all the necessary config, but when i write some data, arduino doesnt receive nothing. I cant figure out what am I doing wrong.

    Communication.h

    #ifndef QSERIALCOM_H
    #define QSERIALCOM_H
    
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <QMutex>
    
    #include <string>
    
    class QSerialCom : public QObject {
        Q_OBJECT
    
    public:
        explicit QSerialCom(QObject* parent = nullptr);
        ~QSerialCom();
    
        static void printPortInfo();
    
        void updateThreads();
    
    private:
        QList<QSerialPortInfo> ports;
        QSerialPort opened;
    
        QMutex openedmut;
    
        std::array<int, 6> transmission;
    
        bool automaticPortSelection;
    
    
    
    public slots:
        void recieveUpdate();
        void recieveNewPort(QSerialPortInfo);
        void recieveSetAutomaticPortsSelection(bool);
    
    signals:
        void sendDevicesChanged(QList<QSerialPortInfo> devs);
        void sendDoneUpdating();
    };
    
    namespace codes {
        static const char COMMSTART = 0;
        static const char COMMEND = 1;
        static const char ACK = 2;
        static const char ERR = 3;
    }
    
    
    Q_DECLARE_METATYPE(QSerialPortInfo)
    
    #endif // QSERIALCOM_H
    
    

    Communication.cpp:

    #include "QSerialCom.h"
    
    #include <QDebug>
    
    #include "Control.h"
    
    // Comparador de QSerialPortInfos
    bool operator== (const QSerialPortInfo p1, const QSerialPortInfo p2) {
        return p1.portName() == p2.portName() &&
               p1.systemLocation() == p2.systemLocation() &&
               p1.manufacturer() == p2.manufacturer() &&
               p1.serialNumber() == p2.serialNumber();
    }
    
    void QSerialCom::printPortInfo() {
        for(const auto &port : QSerialPortInfo::availablePorts()) {
            qDebug() << "Nome: " << port.portName();
            qDebug() << "Localização: " << port.systemLocation();
            qDebug() << "Descrição: " << port.description();
            qDebug() << "Ocupado: " << port.isBusy();
            qDebug() << "Produtor: " << port.manufacturer();
            qDebug() << "Id: " << port.productIdentifier();
            qDebug() << "Número Serial: " << port.serialNumber();
            qDebug() << "Id do vendedor: " << port.vendorIdentifier();
        }
    }
    
    QSerialCom::QSerialCom(QObject* parent) : QObject(parent),
        ports(),
        opened(),
        openedmut(),
        transmission(),
        automaticPortSelection(true)
    {}
    
    QSerialCom::~QSerialCom() {}
    
    void QSerialCom::updateThreads() {
        opened.moveToThread(thread());
    }
    
    void QSerialCom::recieveNewPort(QSerialPortInfo newport) {
        QMutexLocker lock(&openedmut);
        opened.setPort(newport);
        if(!opened.isOpen())
            opened.open(QIODevice::ReadWrite);
    }
    
    #include "MacroLogger.h"
    void QSerialCom::recieveUpdate() {
        Control::calculateAngles();
    
        auto newports = QSerialPortInfo::availablePorts();
    
        if(ports != newports) {
            emit sendDevicesChanged(newports);
            ports = newports;
            if(ports.size() != 0 && !opened.isOpen() && automaticPortSelection) {
                recieveNewPort(ports[0]);
            }
            opened.setBaudRate(QSerialPort::Baud9600);
            opened.setDataBits(QSerialPort::Data8);
            opened.setFlowControl(QSerialPort::NoFlowControl);
            opened.setParity(QSerialPort::NoParity);
            opened.setStopBits(QSerialPort::OneStop);
        }
    
        if(opened.isOpen()) {
            char buf[1] = {codes::COMMSTART};
            printf("\n SENDING COMMSTART TO ARDUINO...");
            opened.write("A");
            printf("\n WRITING BYTES...");
            opened.waitForBytesWritten(-1);
            printf("\n COMMSTART SENT \n");
    
            \\THE PROGRAM BLOCKS HERE
            printf("\nWAITING MSG FROM ARDUINO..."); 
            opened.waitForReadyRead(-1);
            printf("\nRECEIVED");
            QLOG(opened.bytesAvailable());
            if(opened.bytesAvailable()) {
                opened.getChar(buf);
                if(buf[0] == codes::COMMSTART)
                    STDLOG("primeira mensagem recebida: codes::COMMSTART");
                else if(buf[0] == codes::ACK)
                    STDLOG("primeira mensagem recebida: codes::ACK");
                else if(buf[0] == codes::ERR)
                    STDLOG("primeira mensagem recebida: codes::ERR");
                else
                    printf("primeira mensagem recebida: %d", buf[0]);
    
                if(buf[0] != codes::COMMSTART) {
                    printf("\n COMMSTART ARDUINO NOT RECEIVED \n");
                    emit sendDoneUpdating();
                    return;
                }
                printf("\n COMMSTART FROM ARDUINO RECEIVED \n");
    
                for(const auto& sent : transmission) {
                    opened.waitForBytesWritten();
                    opened.write(reinterpret_cast<const char*>(&sent), 4);
    
                    opened.waitForReadyRead();
                    opened.getChar(buf);
                    if(buf[0] != codes::ACK) {
                        emit sendDoneUpdating();
                        return;
                    }
                }
    
                opened.putChar(codes::COMMEND);
                opened.waitForBytesWritten();
                opened.waitForReadyRead();
                opened.getChar(buf);
                if(buf[0] != codes::COMMEND) STDLOG("deu merdinha");
                else STDLOG("deu certinho");
            }
        }
    
        else {
            printf("\n NOT OPENED \n");
        }
    
        emit sendDoneUpdating();
    }
    
    void QSerialCom::recieveSetAutomaticPortsSelection(bool newstate) {
        automaticPortSelection = newstate;
    }
    

    Arduino code:

    void setup() {
      Serial.begin(9600);
      //Serial.setTimeout(-1);
      pinMode(13, OUTPUT);
      Serial.flush();
    }
    
    void loop() {
      if (Serial.available()) {
        Serial.println("E");
      }
    }
    

    The Arduino Serial never become available and the letter "E" is never send


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Can you communicate with the Arduino with e.g. the terminal example ?

    Are you sure your settings are correct on both sides ?

    Are you sure you are using the correct com port ?


Log in to reply