简体   繁体   中英

Qt C++ and QSerialDevice: Windows 7 USB->Serial Port Reading/Writing

I am attempting to read from/write to an RS-232 capable device. This works without issue on Linux. The device is connected via a Digitus USB/Serial Adapter.

The device shows up in Device Manager as COM4.

void PayLife::run() {
    this->sendingData = 0;
    this->running = true;
    qDebug() << "Starting PayLife Thread";
    this->port = new AbstractSerial();
    this->port->setDeviceName(this->addy);
    QByteArray ba;
    if (port->open(AbstractSerial::ReadWrite| AbstractSerial::Unbuffered)) {
        if (!port->setBaudRate(AbstractSerial::BaudRate19200)) {
            qDebug() << "Set baud rate " <<  AbstractSerial::BaudRate19200 << " error.";
            goto end_thread;
        };

        if (!port->setDataBits(AbstractSerial::DataBits7)) {
            qDebug() << "Set data bits " <<  AbstractSerial::DataBits7 << " error.";
            goto end_thread;
        }

        if (!port->setParity(AbstractSerial::ParityEven)) {
            qDebug() << "Set parity " <<  AbstractSerial::ParityEven << " error.";
            goto end_thread;
        }

        if (!port->setStopBits(AbstractSerial::StopBits1)) {
            qDebug() << "Set stop bits " <<  AbstractSerial::StopBits1 << " error.";
            goto end_thread;
        }

        if (!port->setFlowControl(AbstractSerial::FlowControlOff)) {
            qDebug() << "Set flow " <<  AbstractSerial::FlowControlOff << " error.";
            goto end_thread;
        }
        while(this->running) {
            if ((port->bytesAvailable() > 0) ||  port->waitForReadyRead(900)) {
                ba.clear();
                ba = port->read(1024);
                qDebug() << "Readed is : " << ba.size() << " bytes";
            }
            else {
                qDebug() << "Timeout read data in time : " << QTime::currentTime();
            }
        }
    }
    end_thread:
    this->running = false;
}

On Linux, I don't use QSerialDevice, just regular serial reading/writing.

No matter what, I always get:

Starting PayLife Thread 
Readed is :  0  bytes 
Timeout read data in time :  QTime("16:27:43") 
Timeout read data in time :  QTime("16:27:44") 
Timeout read data in time :  QTime("16:27:45") 
Timeout read data in time :  QTime("16:27:46")

I am not exactly sure why.

Note, I tried first to use regular Windows API reading and writing with the same results, ie it just doesn't ready any data from the device.

I am 100% sure that there is always something to read from the device, as it spams ENQ across the connection.

You should generate the doxygen documentation of QSerialDevice if you haven't already done so. The problem seems to be explained there.

On Windows in unbuffered mode:

Necessary to avoid the values of CharIntervalTimeout and TotalReadConstantTimeout equal to 0. In theory, it was planned that at zero values of timeouts method AbstractSerial::read() will read the data which are in the buffer device driver (not to be confused with the buffer AbstractSerial !) and return them immediately. But for unknown reasons, this reading always returns 0, not depending on whether or not a ready-made data in the buffer.

Because read waits for the data in unbuffered mode, I guess waitForReadyReady doesn't do anything useful in that mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM