Anjinsan5
asked on
Help with MSCOMM and enumerating COM ports...
I am working on an application in VB6 which communicates with an external device via a USB/serial adapter (via a virtual COM port) and uses the MSCOMM control for communication. In the form_load event(see attached code), I use a For...Next statement to compile a list of all available COM ports in which I add to a combobox control for the user to select from. The problem I am running into (mainly on laptops) is that the internal modem (usually COM3) is added to this list and when the user selects this port my program's error handling does not throw up an error message but rather attempts to communicate serially with the modem.
1. What I am trying to do is detect which port the modem is connected to (on Form_load) and remove that port from the list of available COM ports the user can select from.
2. Ive also noticed that if the modem port is set to say COM 2, my device (say COM4) is detected as a modem in my routine.
1. What I am trying to do is detect which port the modem is connected to (on Form_load) and remove that port from the list of available COM ports the user can select from.
2. Ive also noticed that if the modem port is set to say COM 2, my device (say COM4) is detected as a modem in my routine.
Private Sub Form_Load()
Dim port, MyPorts
Dim totalport
Dim X As Single
Dim sInput As String
Dim ModemFind As Boolean
'Compile list of ports and add to combobox
For port = 1 To 16
MSComm1.CommPort = port
MSComm1.Settings = "9600,N,8,1"
MSComm1.InputLen = 0
On Error Resume Next
MSComm1.PortOpen = True
If Err.Number = 8002 Then
Err.Clear
End If
If Err.Number = 8005 Then
Err.Clear
End If
If Err = 0 Then
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
cboCommPort.AddItem (CStr(port))
totalport = totalport + 1
End If
'Use this code to detect the modem port
If MSComm1.PortOpen Then
MSComm1.Output = "ATV1Q0" & Chr$(13)
X = Timer
While Timer - X < 1
DoEvents
Wend
sInput = sInput & MSComm1.Input
'MSComm1.PortOpen = False
If InStr(sInput, "OK" & vbCrLf) <> 0 Then
cboCommPort.RemoveItem (CStr(port))
MsgBox " Modem detected on COM" & port
ModemFind = True
MSComm1.PortOpen = False
Exit For
End If
If ModemFind = False Then
Resume Next
End If
If cboCommPort.Text = "" Then cboCommPort.Text = CStr(port)
End If
End If
Next
FrmMain.StatusBar1.Panels(1).Text = "Detected available PC Comm. Ports..."
start_tmrStatusBarText
Err.Clear
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Remove teh Exit For Statement from line 40 so it loop through all COM-Ports
ASKER
It now loops through all COM ports, however it still adds the modem port to the combobox as a selectable option for the user. My goal is to make sure the user doesn't have the option of selecting the modem port as an usable COM port (therefore when my code detects the modem it removes it from the combobox, or never adds it to the combobox in the first place). It would be even better if the Combobox.text property would display the COM port which my device is connected to as the default option. Any ideas?
Are there any Response from your device when you send the AT command?
Have you reset the sInput variable at the end of the
Write at Line 41 after the End If
sInput = ""
Have you reset the sInput variable at the end of the
Write at Line 41 after the End If
sInput = ""
ASKER
Ok I have it somewhat working with the following code below. The modem port is no longer being added to the combobox, however I had it working properly when the device was connected to COM4, but for some reason it does not communicate with the device when the device was connected to COM6. Strange, any ideas?
'----------------------------------------------------------------------------------
'Detect Modem Port First
For port = 1 To 16
sInput = ""
MSComm1.CommPort = port
MSComm1.Settings = "9600,N,8,1"
MSComm1.InputLen = 0
On Error Resume Next
MSComm1.PortOpen = True
If Err.Number = 8002 Then
Err.Clear
End If
If Err.Number = 8005 Then
Err.Clear
End If
If Err = 0 Then
If MSComm1.PortOpen = True Then
MSComm1.Output = "ATV1Q0" & Chr$(13)
X = Timer
While Timer - X < 1
DoEvents
Wend
sInput = sInput & MSComm1.Input
If InStr(sInput, "OK" & vbCrLf) <> 0 Then
MsgBox " Modem detected on COM" & port
MSComm1.PortOpen = False
ElseIf InStr(sInput, "OK" & vbCrLf) = 0 Then
cboCommPort.AddItem (CStr(port))
totalport = totalport + 1
MSComm1.PortOpen = False
End If
If cboCommPort.Text = "" Then cboCommPort.Text = CStr(port)
End If
End If
FrmMain.StatusBar1.Panels(1).Text = "Detected available PC Comm. Ports..."
start_tmrStatusBarText
Err.Clear
Next
'-------------------------------------------------------------------------------------
ASKER
The modem port issue seems resolved and the device will communicate with ports (1-4) however when tested on COM6 and up (COM5 was busy) it will not communicate nor react to my error handling.
Hi!
Why don't you use EnumPorts from the windows API?
I think it will be the best way to do it...
See: http://www.ex-designz.net/apidetail.asp?api_id=556
Why don't you use EnumPorts from the windows API?
I think it will be the best way to do it...
See: http://www.ex-designz.net/apidetail.asp?api_id=556
ASKER
Thanks for the article. I have looked into the Windows API solution however I don't believe it will resolve the issue I'm having now. I am able to list the available COM ports and now weed out the modem port, however my issue is figuring out why there is no communication between the device and mscomm after COM4.
It's possible that other devices are using those ports, like bluetooth devices, or modems. You should use the default port COM1.
ASKER
I have it fully working now, I just had to make a few changes to other parts of my code. One final question, is there any way to have the combobox.text property default to the COM port which my device is connected to?
Do you know what is this port, or you have a way do know it?
ASKER
That is my issue; it can be different every time the user plugs the device in depending on what COM port is assigned to the USB/serial converter. I think I will throw a serial command at the port and if the device responds then I will confirm it is my device. Thanks for your help!
Wasn't it my answer...?
...snifffff
...snifffff
The registry contains infos on the COM ports.
The registry COM port informations are always up to date !
-Here is a sample :
The registry COM port informations are always up to date !
-Here is a sample :
'Read COM ports from registry :
Private Sub Command1_Click()
Const REG_SZ = 1
Const REG_DWORD = 4
Const REG_BINARY = 3
Const REG_MULTI_SZ = 7
Const REG_EXPAND_SZ = 2
Const HKCU = &H80000001
Const HKLM = &H80000002
Set Registry = GetObject("winmgmts:\\.\root\default:StdRegProv")
'myKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
myKey = "HARDWARE\DEVICEMAP\SERIALCOMM"
Registry.EnumValues HKLM, myKey, valueNames, valueTypes
If Not IsNull(valueNames) Then
For i = 0 To UBound(valueNames)
myVal = valueNames(i)
If valueTypes(i) = REG_SZ Then
Registry.GetStringValue HKLM, myKey, myVal, DataCOM12
AutoRedraw = True
Print " " & myVal & ": " & DataCOM12
End If
Next
End If
End Sub
ASKER
What I am trying to achieve, is for Form_load to scan for all available COM ports and add them to a combobox control, however if it detects the internal modem (lines 27-40) it will not add that port to the combobox. It seems I need some alteration to code to allow the loop to continue to scan after it has detected the modem port and disregarded it to find any additional COM ports. So, for example, if COM1, COM2, COM3 (internal modem), and COM8(my device) are found then all ports are added to the combobox except COM3 (internal modem). Thanks.