Page 1 of 1

IsSerialPort()

Posted: Sun Aug 11, 2019 3:01 pm
by drahneir
I have an application in which a GPS-Mouse is used to keep time synch. The GPS is connected to the PC via USB.
Everything is working OK. The application has no user surface, so to end the program, I have included the following code.

Code: Select all

 If Not IsSerialPort(0)
      End
    EndIf
When I disconnect the GPS from the PC the CommPort disappears in the device manager, but my program is still running, nothing happens.
What is wrong?

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 3:33 pm
by plouf
afaik this is because you have already open the "serial"

i guess you have to use
if SerialPortError(#SerialPort) = #PB_SerialPort_IOE
as a more proper way

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 4:14 pm
by drahneir
Plouf, tnx for your suggestion, but the result is the same.

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 4:48 pm
by plouf
i did some test here .. its Driver depended
in the following code error's apear in CH340 chip's but MCP2221 did nothink !

so you have to test by yourself otherwise you must have a handshake with device periodically (if it is supported by device)
to ensure communication, in reality real serial cannot be detached while a PC is running anyway :)

Code: Select all

*buffer = AllocateMemory(1024)
OpenSerialPort(0,"COM5",9600,#PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)


Repeat  
  Debug "Error" + Str(SerialPortError(0))
  Delay(1000)
Until 0

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 5:40 pm
by infratec
If your program sends always some data to the device,
you can check with AvailableSerialPortOutput() if the buffer went down to 0.
If not, the OS can not send the data to the device.
But it really depends on the driver.

Give it a try.

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 5:46 pm
by drahneir
Since I set the system time, administrator prvileges are required. When I start the program in the IDE, the debugger window opens. When I disconnect the GPS, nothing happens. When I reconnect the GPS and start the program, no error message, a second instance of the debugger appears.
When I start the compiled exe-file and disconnect the GPS, nothing visible happens. In the task manager my program appears under backgraound processes. When I disconnect and reconnect the GPS, I can start the program again and a second instance of it appears.
So far, so bad.
I think its a bug with the IsSerialPort() command. When the commport isn't existing anymore, as the device manager proves, the command shouldn't say its ok.
BTW, my commport is Prolific.

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 5:47 pm
by drahneir
infratec, yes, that's what my program is doing, but vice versa.
I only read data from the device, and use AvailableSerialPortInput() until there is no more input.

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 6:39 pm
by infratec
But if the gps mouse sends continiously data, then you can check with a timeout if still data arrives.
If not exit the program.

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 7:20 pm
by HeX0R
drahneir wrote:I think its a bug with the IsSerialPort() command. When the commport isn't existing anymore, as the device manager proves, the command shouldn't say its ok.
BTW, my commport is Prolific.
This is for sure no bug, IsSerialPort() only tells you if a #ComPort has been successfully opened.
Almost any terminal out there would also still show a com port open, even if you physically disconnected your USB->RS232 adapter.

If this is for windows, you should be able to use something like this to get informed as soon as a device dis/connects:

Code: Select all

Procedure CallBack_NewDevice(WindowID, Message, wParam, lParam)              ;add/delete live connecting USB devices (windows only)
	Protected Result, ComPort.s
	Protected *db.DEV_BROADCAST_HDR
	
	Result = #PB_ProcessPureBasicEvents
	Select Message
			
		Case #WM_DEVICECHANGE
			Select wParam
				Case #DBT_DEVICEARRIVAL
					*db = lParam
					If *db\dbch_devicetype = #DBT_DEVTYP_PORT
						ComPort     = PeekS(*db + SizeOf(DEV_BROADCAST_HDR))
						Debug "New COM Port: " + ComPort
					EndIf
				Case #DBT_DEVICEREMOVECOMPLETE
					*db = lParam
					If *db\dbch_devicetype = #DBT_DEVTYP_PORT
						ComPort = PeekS(*db + SizeOf(DEV_BROADCAST_HDR))
						Debug "Com Port Disconnected: " + ComPort
					EndIf
			EndSelect		

	EndSelect
	
	ProcedureReturn Result
EndProcedure

OpenWindow(0, 0, 0, 250, 150, "Live COM Ports", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowCallback(@CallBack_NewDevice(), 0)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: IsSerialPort()

Posted: Sun Aug 11, 2019 11:23 pm
by TassyJim
Windows does not handle the removal of active ports very well.
It depends on the version of Windows and the make of USB device but generally, if you have a port open when the USB is removed, Windows will keep the port open and not be very happy if the USB is reinserted while the program is still running with the port supposedly open.
The user will have to close the program then remove and reinsert the USB before the serial port is usable again.

It is something that has caused me and my end users much pain over the years.

As already mentioned, you have two choices.
1. when no data is received, assume the USB has been unplugged and shutdown.
2. monitor the Windows messages for notification that the port has been removed.

Jim

Re: IsSerialPort()

Posted: Mon Aug 12, 2019 5:05 am
by drahneir
Windows detects the removal of open commports immedeately, as you can observe in the device manager. Once disconnected and connected again, it is a complete new port and can be opened.
Another thing is how the running program is informed about the removal.
I found a very simple solution to end my program. In it is a ReadSerialPortData() command, which is performed periodically. Since the read of a non existing commport doesn't deliver any data, the data in the input buffer remain unchanged. When two sequential reads deliver the same data from the buffer, the program is ended. Under normal conditions the read data can't be the same, because they are actual time data.
[Edit] I now use another way to detect the missing port. After having read out the comm buffer, it is deleted. When in the next read cycle the buffer isn't filled with new data, the program ends.