Correct way to close a serial port QT - windows

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).

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.

There are two possible answers, I think:
Your process doesn't terminate in spite of you closing the main window. How have you verified that the process is, in fact, terminated?
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.

Related

Closing a COM port with command prompt

I need to be able to close COM ports through the command prompt (Windows 7 OS). The reason for this is that I work with a lot of experimental equipment, controlled with a language called LabVIEW, and communication to these devices is sometimes lost. Right now the only fix is to either rename the COM in device manager, or reboot. Ideally I'd like to close the port in command prompt, which I can implement programatically in my control software.
Does anyone know either; how to close a COM port in command prompt, or a quick and easy way of closing a COM port, so then I can reestablish a connection with my device?
Cheers!
I don't think you can simply close a resource that is in use by another program, this will undoubtedly lead to errors. Programmed correctly LabVIEW should not leave ports open, even if port are left open simply closing labview should be enough.
In LabVIEW programatically open and close the COM port, don't rely on the auto-closing of the VISA system. Also add timeouts to the serial connections, than you should get a connection error time out and be able to clean up the resource.
Basically you need to solve your problem at the origin, if help needed post your LabVIEW code.
Presuming you read from the serial port in a while loop, simply stop the while loop when an error is found, see the code snippet. This stops the loop and the resource will be closed outside the loop regardless of the error.

Debugging stm32f4 via bluetooth

I'm rather unexperienced on the field of microcontrollers, I come from a Java background so the question might seem a bit noob but I didn't find much information on this.
So is it possible to debug an STM32F4 board via bluetooth (using eclipse or some othe IDE)? And if so could you send me some links that might help? We're building a robotic car controlled by a discovery board and debugging using an USB cable is not really an option if we don't want to disassemble the whole stuff every time something goes wrong. Hence this would really come in handy. So any help is appreciated
For doing this you would need to find a "Bluetooth Enabled" Debugger. I have never seen any and not sure whether there exists such thing or not.
I would suggest you one thing:
Assuming you have bluetooth connectivity between your board and your Machine,
Insert Debug strings: Send some strings from your board to your PC via Bluetooth. These strings will give you what's going on in Circuit.
For example, After Initialization, send "Init Completed" and like that. You can see these strings and see what's wrong.
I usually do this for my Wireless Device.
What you're wanting to do is really not practical; you're coming at this from way too high a level and trying to imagine the system as if it were running an operating system from the word go.
When you get the STM32 it as empty shell; you need to program it to do what you need to do and the only [sensible] way to get register-level debugging is to use a JTAG interface.
If, and this is a big if, you get it working reliably, but just want to give some debug information back while it is running, you could write a load of routines within the code to send out debugging messages when it enters certain parts of the program - and send it out over Bluetooth - but this is nothing like what you're used to single stepping through your Java code with Eclipse. If you want to do that kind of thing, you are going to have to put a little connector on that allows you to connect your JTAG or two-wire debugger cable to the processor. Even then, when you do that, you will be completely resetting your program and not simply single stepping through from where it went wrong.
You could insert a monitor program within your program to send out register values, program status etc over Bluetooth, but you still have to write the inital code and the only way to do this with out a ridiculous amount of trail and error is via your JTAG or two-wire interface.
Would this product work? It's a "IOGEAR Bluetooth Serial Adapter, GBC232A" for connecting to a serial port over bluetooth. I'm interested in wireless debugging too because my surface-clone dev computer only has one usb and this seems like it could be convenient over a tangle of usb cords and a usb hub. I have zero experience with any of this, so maybe you could validate or invalidate it as an option. I figure it just needs a proper serial connector wired up on the board and power from on-board?

Device misdetected as serial mouse

I'm working on a device which communicates with a PC through a (virtual) serial port. The problem is that the data we are sending occasionally gets incorrectly identified by Windows as a bus mouse, after which the "Microsoft Serial Ballpoint" driver is loaded and the mouse pointer starts jumping around on the screen and randomly clicking on things.
A bit of Googling reveals that is an old and well-known problem with serial devices where the usual work-around is a bit of registry hacking to disable the offending driver. That it is a lot to demand from our users however and I'd rather not have our application messing around with the user's registry. Especially not when the fix is dependent on the Windows version and the user may well be using a bus mouse.
Instead I'd like to avoid the problem by changing our protocol to not send any data which may get us misidentified as a mouse. The only problem is that I'm not quite certain what patterns to avoid.
Apparently Microsoft's Mouse protocol consists of packets of four bytes where the MSB of the first is set and that of the last three is clear.
Would sending only 7-bit ASCII suffice? Are there any other devices I need to worry about being detected as?
I just encountered this problem myself on Windows 7 Professional x64, and a solution that worked for me was to go into the registry and edit the following value:
Location: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\sermouse
Key: Start
Value: 3
Change Value to 4 and it will stop this problem occurring.
Here is a list of all valid Start values:
0 Boot (loaded by kernel loader). Components of the driver stack for the boot (startup) volume must be loaded by the kernel loader.
1 System (loaded by I/O subsystem). Specifies that the driver is loaded at kernel initialization.
2 Automatic (loaded by Service Control Manager). Specifies that the service is loaded or started automatically.
3 Manual. Specifies that the service does not start until the user starts it manually, such as by using Device Manager.
4 Disabled. Specifies that the service should not be started.
A reg edit command would be as follows:
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\sermouse" /V Start /T REG_DWORD /F /D 4
You then need to restart the computer, which should now start correctly and not attempt to discover a serial mouse.
good luck.
It turns out that mouse detection in Windows is normally handled by the serenum.sys filter driver. This driver implements support for legacy serial mice along with serial plug-and-play. Microsoft has even provided the sourcecode as a WDK sample.
During detection the ports switches to 1200-7-N-1 mode while asserting DTR+RTS to which a response is expected within 200 ms, with a couple of retries in case of failure. Unfortunately for a legacy mouse a single M or B character suffices as identification.
In our case the protocol was reworked to avoid these characters and now appears not to be misidentified anymore.
However we were using a virtual USB serial port and for a traditional serial port this approach may be somewhat difficult as anything sent at a different baud rate is liable to look like line noise. In this case I suppose the easiest workaround is probably, as has already been suggested, to avoid making any unsolicited transmissions.
Alternatively with the serial control signals actually hooked up, or intercepted by a USB CDC device, processing the DTR or RTS signals and holding off on output. Actually implementing the plug-and-play protocol would be an even niftier option. Supposedly there are cheap RS232 cables around without a full complement of control signals though so this approach might still fail.
I also encountered this problem, fixed it by disabling "serial enumerator" in the advanced properties of the FTDI driver (properties of COM ports in Device Manager). This is described in http://www.ftdichip.com/Support/Documents/AppNotes/AN_107_AdvancedDriverOptions_AN_000073.pdf.
I have encountered this Windows bug myself. Here is my own research on the topic:
Microsoft acknowledges this bug: http://support.microsoft.com/kb/819036
Start with downloading their tool and see if it solves the issue.
Download & install their program.
Run it from the command prompt from C:\program\Microsoft comdisable\
Write comdisable /list when executing the program.
All ports on the computer will be shown.
Write comdisable /disable COMx where x is the port number.
Do this for all ports on the computer.
Reboot.
This should hopefully work as an universal solution.
Alternatively, you can hack in boot.ini but I don't believe this works in Vista/Win 7. I have some app note from Cisco systems describing how to do this. If the above doesn't solve your problem, please let me know.
In my development environment, I've simply disabled Microsoft Serial Mouse from the Device Manager.
This seems to solve the culprit of my problem. Before doing so, the CH340G chip I've used in my design used to lower the DTR five times before initiating the connection, effectively rebooting my Arduino-based board and render it useless.
Maybe this helps:
We had the same problem with FTDI FT232RL.We found out, that it was a hardware issue of our PCB.
FTDI-Datasheet says about #RESET-Pin: Active low reset pin. This can be used by an external device to reset the FT232R. If not required can be left unconnected, or pulled up to VCC.
RESET-Pin was not required in our application, so we connected it to Vcc via 1k Pull-Up.
It seemed that the pull-up of #RESET-Pin caused an undefined start-up of the FT232RL, at least every second converter, we connected to a USB-socket caused a serial-ball-point in the devive manager. We removed the pull-up-resistor at #RESET-Pin, therewith the #RESET-Pin is unconnected. Since then every interface worked proberly and didn't any longer create serial-ball-points in the Windows device manager.
If you have a "true" serial port, or an USB dongle (RS-232, RS-485, it does not matter) this problem can be worked around by first opening the serial port in question with a terminal, or whatever application you want to monitor it with, and only then plugging the device in. For your own sake, you should also pay attention to remove the device before terminating the connection.
With FTDI chips soldered on the device itself, you are busted. It took a few rounds for me to explain the management that a device communicating on it's own paired with an FTDI chip soldered on the PCB meeting Windows computers won't likely pass for user-friendliness, no matter how slick an USB socket may look like on the cabinet... (Thankfully, all these conditions coming together are quite rare and unusual)
I had this problem since 2010 with serial scale heads connected to the pc. Usb to serial converter or not.. I use onkly SILABS device's CP2102 or the like.. I worked around it by simply allowing the driver to install and then in device manager look for the ballpoint driver under mouse/HIDA and then simply DISABLE the driver, DO NOT UNINSTALL IT simply disable it. Then when you reboot even with the driver instaled it seems windows ignores the comport as serial mouse and uses the data from the input. You will also find that if the ballpoint driver is active then that COMport is in use and sometimes returns a COM PORT not accessible... hope this helps some one out there :) Tx Ben
Code tot stop GPS from being detected as serial mouse.
Below is the code for a subroutine in C#.net. It checks if the registry key is set to 4 and if not it issues the configuration command to disable sermouse.
Embed this subroutine in a program which runs at startup and it will correct the setting after a windows update.
Maybe useful if you get annoyed when this problem happens time and again
private void Stop_sermouse()
{
string k =
"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\sermouse";
object v = Microsoft.Win32.Registry.GetValue(k, "Start", null);
if (v==null)
{
MessageBox.Show("No Registry Key for sermouse");
}
else
{
string sr = v.ToString();
if (sr == "4")
{; }
else
{
DialogResult mbox = MessageBox.Show("disable sermouse ? " + v.ToString(), "Found sermouse enabled! ", MessageBoxButtons.YesNo);
if (mbox == DialogResult.Yes)
{
// prepare a small job to issue confuguration command
ProcessStartInfo s = new ProcessStartInfo("cmd.exe", "/c sc config sermouse start=disabled");
Process p = new Process();
s.Verb = "runas"; // Must run as administrator
s.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo = s;
// and run the command
p.Start();
//check if the registry is modified indeed
v = Microsoft.Win32.Registry.GetValue(k, "Start", null);
sr = v.ToString();
if (sr == "4")
{
MessageBox.Show("finished ''sc config sermouse start=disabled'' but not succesfull in registry!");
}
else
{
MessageBox.Show("sermouse is disabled");
}
}
}
}
}
Turns out there is a setting to stop windows trying to enmumerate devices that connect as a COM port.
Make sure that "Serial Enumerator" is unchecked under "Miscellaneous Options"

COM port quits working

Environment: WinXP; PowerBuilder 11.5 (though probably not relevant because this portion is almost entirely WinAPI calls)
My application opens a COM port for writing using overlapped method calls. The port is opened when the application is opened. The app leaves the port open at all times.
Occasionally, the attached device stops receiving data even though the app is still sending data. The app receives no error messages. Stopping and restarting the app doesn't fix it. Rebooting the computer doesn't fix it. However, connecting via hyperterminal fixes it.
This particular device prints barcode labels. The app will be printing just fine, then suddenly, it won't print. Close the app; open and connect with hyperterminal; disconnect and close hyperterminal; open the app. It works just fine again... for a while. (I've had similar issues with other devices that also communicate via COM port, so I know it's not the device itself.)
The closest similar issue I can find on the web is at http://www.eggheadcafe.com/microsoft/Windows-XP-Hardware/30829577/com1-not-behaving.aspx which speaks of IRQ conflicts and offers no solution. I can only guess that my problem is similar.
Does anyone know what hyperterminal might be doing to clear things up?
I've explicitly set the handshake method using SetCommState and that appears to have resolved the issue. PowerBuilder doesn't have bit operands, so I had to create a method that turned a DWORD number into a character array of '1's and '0's. I created a corresponding method that turned the character array back into a DWORD. So, I grabbed the current state using GetCommState, translated the flags into an array, walked the array copying the existing values except for the ones that specify flow control (DTR Control and RTS Control-- not sure if I needed both) which I explicitely set to '0', then translated the resulting array back to a DWORD and used SetCommState to apply it.
For those researching, please remember that DTR Control and RTS Control are both two bits each. Decimal values for these are:
CONSTANT ULong fDtrControl_Enable = 2^4
CONSTANT ULong fDtrControl_Handshake = 2^5
CONSTANT ULong fRtsControl_Enable = 2^12
CONSTANT ULong fRtsControl_Handshake = 2^13
CONSTANT ULong fRtsControl_Toggle = fRtsControl_Enable + fRtsControl_Handshake
Well, this is very late, but I've experienced similar problems on multiple devices, primarily on USB devices that have a USB/COM port driver.
The symptom that I have found is the COM port sporadically closes all on its own. I've traced this problem to two potential issues:
The USB/COM driver can have bugs that cause the port to close. Try an updated driver.
Electrical noise on the USB wire coming into the computer can cause the port to close. If you experience this problem, you may not be able to solve the problem easily.
Try to isolate the electrical environment so noise doesn't enter via the USB wire.
If you can't, you may have to modify your application to detect a closed port, and then perform a driver reset, which is the same thing as unplugging and re-plugging the USB cable, then pause a little to make sure the reset actually takes.

SMS war continues, ideas welcome

I am trying to make U9 telit modem send SMS messages. I think I handle protocol correctly, at least, I manage to send them, but only under these circumstances: the native application was executed beforehand, and killed by task manager (without giving it a chance to initialize things).
It looks like the supplied application is good at doing certain initialization/deinitialization which is critical. I also see the difference between the two states in output of AT+CIND command. When I am trying to do things on my own, it returns zeroes (including signal quality), but when I run the same command after killing the native application, the output looks reasonable.
I am out nearly of ideas. I have tried many things, including attempts to spy at modem's COM ports (didn't work). Haven't tried setting windows hooks to see what the application is trying to get thru.
Perhaps you have encountered a similar situation?
Agg's "Advanced Serial Port Monitor" actually helped a lot. Sometimes it caused blue screen, but it helped uncover secret commands which seem to help. AT+PCFULL is not described anywhere on the net, for example. The real trigger of non-operatio was AT+CFUN, the power disable/standby feature.
Also, it appeared that we have more issues. At first, the modem appears on the bus only as disk drive. It doesn't want to appear as any other devices before the drivers are installed. So, the U9 Telit software sends an IOCTL to disk driver to tell the modem to reappear as more devices (modem, 3 serial ports, another disk drive).

Resources