vbscript for detecting usb serial com port number (can be used with avrdude for programming avr)

I was using the adruino bootloader on a ATmega32 and for uploading the new firmware is done using avrdude. Initially I was using a windows batch file to upload the content. Since the development board contains an FTDI chip for USB to serial conversion(same in arduino boards), the driver will assign different com port number for  different PC/board combination for which it was necessary to update the com port number manually. So I thought of writing a vbscript to automatically detect the correct com port and run the avrdude.
I started searching in google for the help. There was scripts to list the serial ports(Win32_SerialPort), but that does not list the USB serial devices. Then I found that using wmi services it is possible to parse through the Plug and Play(PnP) devices in windows(Win32_PnPEntity). Another thing I found is the name string for each device will contain the comport number also.

PnP device information for the FTDI chip in my development board
Class GUID: {4D36E978-E325-11CE-BFC1-08002BE10318} 
Description: USB Serial Port 
Device ID: FTDIBUS\VID_0403+PID_6001+A700DZAFA\0000
Manufacturer: FTDI 
Name: USB Serial Port (COM4) 
PNP Device ID: FTDIBUS\VID_0403+PID_6001+A700DZAFA\0000
Service: FTSER2K 

Same name string is also showed as the name of the device if we open the windows device manager.
The  script I have listed below will use the Name string to find the com port and then uses it.

' +----------------------------------------------------------------------------+
' |                                 Arun                                       |
' |                           frmkla@gmail.com                                 |
' |                     http://collectns.blogspot.com                          |
' |----------------------------------------------------------------------------|
' |            Copyright (c) 1998-2011 Arun. All rights reserved.              |
' +----------------------------------------------------------------------------+

Option Explicit

Const BAUDRATE = "19200" 'Set "" if baud rate setting is not necessary
Const AVR_PARTNO = "m32"

Dim strPortName' As String
Dim objArgs
Dim strHexFile
Dim strScriptPath
strScriptPath = Replace(WScript.ScriptFullName, WScript.ScriptName, "") 

Set objArgs = WScript.Arguments

strPortName = GetComPort

If strPortName = "" Then
    MsgBox "Cannot find the USB COM Port" & vbCrLf & "Please verify the USB conncetion"
    If objArgs.Count <> 1 Then
        'MsgBox "Usage " & WScript.ScriptName &" <Hex File>"
        Dim objWshShell, objExec
        Dim strExecCmd
        Dim tmp
        strExecCmd = """" & strScriptPath & "OpnFile.exe"""
        strExecCmd = strExecCmd & " ""1""""Hex File (*.hex)""""*.hex""""Hex""""Open Hex File"""

        Set objWshShell = CreateObject("WScript.Shell")
        Set objExec = objWshShell.Exec(strExecCmd)

        Do While objExec.Status = 0
             WScript.Sleep 100

        If objExec.ExitCode = 0 Then
            tmp = Split(objExec.StdOut.ReadLine(), "~")
            strHexFile = tmp(0)
        End If 
        strHexFile = objArgs.Item(0)
    End If
    Dim oShell
    Dim strRunCMD

    'Generate command string
    strRunCMD = """" & strScriptPath & "avrdude"" "
    strRunCMD = strRunCMD & "-C " & """" & strScriptPath & "avrdude.conf"" "
    strRunCMD = strRunCMD & "-p" & AVR_PARTNO & " -cstk500v1 -P\\.\" & strPortName
    If (BAUDRATE <> "") Then strRunCMD = strRunCMD & " -b" & BAUDRATE
    strRunCMD = strRunCMD & " -D -Uflash:w:""" & strHexFile & """:i"

    'Execute the upload command
    Set oShell = WScript.CreateObject ("WScript.Shell")
    oShell.run strRunCMD
    'Wscript.Echo strRunCMD
    Set oShell = Nothing
End If

Function GetComPort()
    Dim strComputer
    Dim objWMIService
    Dim colItems
    Dim objItem
    Dim objRgx 'As RegExp
    Dim objRegMatches 'As MatchCollection
    Dim strDevName

    GetComPort = ""
    strComputer = "."
    Set objWMIService = GetObject( _
        "winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
        ("Select * from Win32_PnPEntity")
    For Each objItem In colItems
        If ("FTSER2K" = objItem.Service) And ("FTDI" = objItem.Manufacturer) Then
            set objRgx = CreateObject("vbScript.RegExp")

            strDevName = objItem.Name
            objRgx.Pattern = "COM[0-9]+"
            Set objRegMatches = objRgx.Execute(strDevName)
            If objRegMatches.Count = 1 Then
                GetComPort = objRegMatches.Item(0).Value
            End If
        End If
End Function

In the script listed above, the function GetComPort returns retruns the comport number if the port is detected, else it will return empty string "". This script also uses an exe file OpenFile.exe to show the open file dialog box.

Click here to download a copy of the script with avrdude and other support files.

1 comment :