Detecting Disconnection of USB Serial Device
I am connected to an Arduino board via a USB link. My code catches exceptions when the USB cable is disconnected and any code references the SerialPort object. This works fine, but what is the simplest way of detecting when the Serialport object disappears so that I can rescan the available ports, list them to the user and flash a message to the effect that the device has been disconnected? I found a reference in a search to capturing the "WM_DEVICECHANGE message". Would this be the way to go about doing this?
Re: Detecting Disconnection of USB Serial Device
this is the basics of what you're trying to do:
Code:
Public Class Form1
Private Const WM_DEVICECHANGE As Integer = &H219
Private Const DBT_DEVICEARRIVAL As Integer = &H8000
Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_DEVICECHANGE Then
If m.WParam.ToInt32 = DBT_DEVICEARRIVAL Then
MsgBox("Device inserted")
ElseIf m.WParam.ToInt32 = DBT_DEVICEREMOVECOMPLETE Then
MsgBox("Device removed")
End If
End If
MyBase.WndProc(m)
End Sub
End Class
someone else might be able to help you to test it is the correct device being inserted or removed
Re: Detecting Disconnection of USB Serial Device
WParam is returning DBT_DEVNODES_CHANGED rather than DBT_DEVICEREMOVECOMPLETE, so apparently I have to use the RegisterDeviceNotification function to get more information.
Re: Detecting Disconnection of USB Serial Device
I thought you just needed notification of device removed?
i'm assuming you can just run your detection code, or whatever it is, any time the WM_DEVICECHANGE message is received with WParam DBT_DEVNODES_CHANGED
Re: Detecting Disconnection of USB Serial Device
Yes I've settled for that. The problem now is that when I check for the list of ports available using ports = System.IO.Ports.SerialPort.GetPortNames(), the USB port is still available even though the cable is disconnected. I tried adding a thread sleep delay before using the GetPortNames method to allow time for the port to be unlisted. However this just makes everything unresponsive. Half a second is necessary for the port to disappear, however DBT_DEVNODES_CHANGED occurs 13 times on cable insertion with a large resultant delay.
This is the code. When a device is connected or disconnected, I wipe the contents of a group box and update it with a new list of ports
Code:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_DEVICECHANGE Then
If m.WParam.ToInt32 = DBT_DEVNODES_CHANGED Then
Console.WriteLine(m.WParam.ToInt32)
ScanForPorts()
End If
End If
MyBase.WndProc(m)
End Sub
Private Sub ScanForPorts()
Dim row As Integer = 1
Dim ports As String() = System.IO.Ports.SerialPort.GetPortNames()
' Remove controls from group box listing available ports
For i As Integer = (grpBoxComPort.Controls.Count - 1) To 0 Step -1
Dim ctrl As Control = grpBoxComPort.Controls(i)
grpBoxComPort.Controls.Remove(ctrl)
ctrl.Dispose()
Next i
' Populate a group box with a list of available ports and add
' the same handler to each radio button which will detect which button is checked
For Each port In ports
Dim radBtnPort As New RadioButton
radBtnPort.Name = port.ToString
radBtnPort.Text = port.ToString
radBtnPort.Location = New Point(5, row * 20)
radBtnPort.Size = New Size(80, 20)
grpBoxComPort.Controls.Add(radBtnPort)
AddHandler radBtnPort.CheckedChanged, AddressOf radBtnPort_CheckedChanged
row = row + 1
Next
End Sub
Re: Detecting Disconnection of USB Serial Device
Quote:
Originally Posted by
Eugbug
Yes I've settled for that. The problem now is that when I check for the list of ports available using ports = System.IO.Ports.SerialPort.GetPortNames(), the USB port is still available even though the cable is disconnected. I tried adding a thread sleep delay before using the GetPortNames method to alow time for the port to be unlisted. However this just makes everything unresponsive. Half a second is necessary for the port to disappear, however DBT_DEVNODES_CHANGED occurs 13 times on cable insertion with a large resultant delay...
That sounds normal for USB devices.
Re: Detecting Disconnection of USB Serial Device
I decided to use a timer to handle the handle this problem. The timer is reset every time the WndProc sub runs and wparam equals DBT_DEVNODES_CHANGED is returned. When the timer eventually "ticks", I scan for a list of port names.