Question

I'm interfacing to a hardware serial device using QT, I've based my application roughly around the Terminal example, but as the communication needs to be very synchronous the serial handler is living in another thread. The connection is via a 2xRS232 to USB adaptor with an FTDI chipset.

The serial comms are fine, I can connect, send commands, etc. However, when I quit and reload the application the serial port seems to be blocked.

Let COM1 be the connected device, COM2 is unconnected.

If I run the program, do a bit of talking to the hardware and quit, I can no longer connect to COM1 the next time I run the program (the data leds don't flash on the adaptor) unless I attempt to connect to COM2 first. Once I've tried this I can then connect back to COM1 as usual. This behaviour is not seen in the reference utility for the hardware and so must be down to some way I'm handling the port.

My close code is:

void mydevice::closeSerialPort()
{
    this->stop();
    serial->close();
    emit serialClosed();
    emit log("Serial port closed.");
}

serial is a QTSerialPort. First a stop command is sent to turn off the hardware (not relevant to the problem, it's just a convenience) and then I send a close command to the serial.

I have a subclassed QWidget for my main window, which calls this command on exit:

/* In the constructor */
connect(this, SIGNAL(WindowClosed()), mydevice, SLOT(closeSerialPort()));


void mainwindow::closeEvent(QCloseEvent *event)
{
      emit WindowClosed();
      event->accept();
}

Is there any reason for this behaviour? I assume I'm blocking the port open somehow, but surely it would complain that it's already open.

Another odd issue is that say the device is on COM1 and I open it in my application, COM1 is unresponsive in the other utility and the device appears on COM2. However, when I switch back to my program and fiddle a bit, the device appears on COM1 again (though always in COM2 in the other application).

Was it helpful?

Solution

So there seems to be a fairly simple solution, though I don't understand exactly what was causing the problem.

I have two threads, each controlling a different serial device. The serial configuration is accessed through a dialog which I stole from a QT example (the terminal). Each thread has an instance of this settings dialog. It seems that something goes wrong when selecting the port - for instance all the selections in the dialog actually point to the same COM port if checked in a debugger.

Anyway, I chalked this up to non-thread-safe code and changed the program to just ask for the serial port name as the data rates, stop bits, parity, etc are fixed by the hardware and aren't going to change. This has fixed the problem.

OTHER TIPS

There are two possible answers, I think:

  1. Your process doesn't terminate in spite of you closing the main window. How have you verified that the process is, in fact, terminated?

  2. Your use of qt's serialport module exposes a bug in FTDI's driver. That's not unthinkable, but I'd call it a remote possibility at the moment.

Personally I don't see any use for the serial port emulation of the FTDI driver, it's adding an extra layer for no good reason. The D2XX interface is the way to do it, if you don't want to use something like libftdi. On Windows, I've found D2XX and libftdi to be the only viable alternatives, with libftdi working much better than D2XX on virtual machines.

Don't know if this could be useful.

I have a similar issue (but not the same) with a prolific pl2303. In my case when i close the port (or even at startup, before opening it!), data is received anyway somehow and presented immediately when i open the port.

This happens only with an usb-rs232 adapter, if I use the ttyS0 (physical serial port) the problem does not appear.

The solution for me was forcing QSerialPort::clear() to clear buffers just after QSerialPort::open(). This avoids signal readyRead to be emitted and thus unwanted data to be received.

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