Question

I have a function that sends data over RS-232 to Hyperterminal. The function works properly out of the while loop, however, in the while loop, it sends only at the first time after that it doesn't send anything.

    qDebug() << MESSAGE;
    int choice;
    std::cin >> choice;

    while( choice != 3 )
    {
        switch (choice)
        {
            case 1:
                // Ready to send data 
                port->write("QSerial Port!\r\n");
                break;
            case 2:
                qDebug() << "Todo...";
                break;
            case 3:
                break;
            default:
                qDebug() << "Invalid Choice ...";
        }
        qDebug() << MESSAGE;
        std::cin >> choice;
    }

Edit:

#include <QCoreApplication>
#include <iostream>
#include <QDebug>
#include <QSerialPort>

const char MESSAGE[] = "\n----- New Menu ----"
                       "\n1- Send Data     \n"
                       "2- Receive Data    \n"
                       "3- Quit:           \n";


int main(int argc, char *argv[])
{
    QCoreApplication  app(argc, argv);

    QSerialPort *port = new QSerialPort;
    port->setPortName("COM4");


    // Check the validity of the port
    if ( !port->open(QIODevice::ReadWrite) )
    {
        qDebug() << "\nError: " << port->portName() << " port can't be opened ...";
        return -1;
    }else{
        qDebug() << '\n' << port->portName() << " port has been opened successfully ...";
        port->setBaudRate(QSerialPort::Baud9600);
        port->setStopBits(QSerialPort::OneStop);
        port->setDataBits(QSerialPort::Data8);
        port->setParity(QSerialPort::NoParity);
        port->setFlowControl(QSerialPort::NoFlowControl);
        qDebug() << port->portName() << " port has been configured correctly ...";
    }

    qDebug() << MESSAGE;
    int choice;
    std::cin >> choice;

    while( choice != 3 )
    {
        switch (choice)
        {
            case 1:
            {
                // Ready to send data 
                if ( port->write("QSerial Port!\r\n", qstrlen("QSerial Port!\r\n")) == -1)
                {
                    qDebug() << port->errorString();
                }
                //port->bytesWritten(strlen("QSerial Port!\r\n"));
                port->waitForBytesWritten(-1);
                //qDebug() << port->errorString();
            }
                break;
            case 2:
                qDebug() << "Todo...";
                break;
            case 3:
                break;
            default:
                qDebug() << "Invalid Choice ...";
        }
        qDebug() << MESSAGE;
        std::cin >> choice;
    }

    qDebug() << "\n Goodbye ....";
    port->close();
    delete port;
    return app.exec();
}
Was it helpful?

Solution

Your code has the following flaws:

1) You do not handle the errors.

2) You do not check the return value of the write operation.

3) You do not seem to wait programatically before writing again. This is not correct. Either use the sync waitForBytesWritten or the async bytesWritten signal to give green light for the next write.

The most critical is probably the last point. It would result "random" behavior how the data is sent out. In this special case, it would probably be sent sequentially as waiting for the input probably takes you longer time, but it is still not stable and robust code to write.

OTHER TIPS

I can't completely agree with point (3). There is nothing which says you can't do a second write, whilst the first is still outstanding. In principle the data should just be added to the transmit queue. It would be like saying "You can't write again to this file until the previous data has been written to disk". I had a similar problem with qtserial where I was doing:

while (..)
{
    <send data>
    <receive data>
}

Turns out you HAVE to do a qApp->processEvents() before you can receive anything or before you can write new data. I was expecting the same behavior as for reading/writing a file. To me qtserial is NOT behaving as you would expect a device to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top