Sign in to follow this  
Followers 0
Runner

How to detect which Arduino COM port being used

11 posts in this topic

Hi all,

I am looking for a script that can detect an Arduino when connected by USB and display the COM number as a ToolTip.

What I have so far, is two programs. The first one displays a ToolTip of a random (for now) COM number. I want this ($j) to be the number assigned under the device driver.

The second one was copied from the forum and I got it to create a folder on my C: drive.

This is were I need help and I am new to AutoIt so small steps please.

This one displays the way I want it:

$j = Random(1,6,1)
For $i = 1 To 200
   ToolTip("COM " & $j)   
   Sleep(10)
Next

And this one is over my head:

Dim $DBT_DEVICEARRIVAL = "0x00008000"
Dim $DBT_DEVICECOMPLETEREMOVAL = "0x00008004"
Dim $USB_ATTENTION = "0x00000007"
Dim $WM_DEVICECHANGE = 0x0219
Dim $Drives
Dim $Drive_Type = "ALL" ; Set to ALL because some USB Drives are detected as Fixed Disks, and we don't want to miss those
Dim $WATCH = False
Dim $MyDrive = "STUFF"

;Get Initial List of Drives to Check Against
UpdateDrives()
;Setup The GUI to watch for the DeviceChange Event
GUICreate("")
GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange")   ;Whenever a WM_DEVICECHANGE message is sent by my GUI, 
                                                   ;please intercept it and pass it through
                                                   ;the 'DeviceChange' function in this script. 
Func DeviceChange($hWndGUI, $MsgID, $WParam, $LParam)  ;which is here
 Switch $WParam
 Case $USB_ATTENTION
 ; This only happens when USB drives are inserted, so I use it to tell the difference between these and CDROMs
 $WATCH = True
 ;Case $DBT_DEVICECOMPLETEREMOVAL
 ; Whenever a Drive is Removed, Update the Drive List
 ;UpdateDrives()
 Case $DBT_DEVICEARRIVAL
 ; A drive was inserted
 ; Use $WATCH to tell if this was a CDROM or USB
 ;If $WATCH = True Then
 ; New USB Drive Was Detected, Time to Find it's Letter
 $New = FindNewDrive(); $New now has the Drive Letter of our New Drive, so USE IT!!!
 $Label = DriveGetLabel($New)

    DirCreate("C:\USB Connect_Test\")
 
 EndSwitch
EndFunc ;==>DeviceChange

; This just jumps through the new Drive List, comparing them until it finds the entry that is in the new one that isn't in the old one
Func FindNewDrive()
 $Temp = DriveGetDrive( "REMOVABLE" )
 For $i = 1 to $Temp[0]
 $Old = False
 For $j = 1 to $DRIVES[0]
 If $DRIVES[$j] == $Temp[$i] Then $Old = True
 Next
 If $Old == False Then Return $Temp[$i] 
 Next
EndFunc ;==>FindNewDrive

; Just to keep things neat, and so if Variables Ever Change, this makes updating easier
Func UpdateDrives()
 $Drives = DriveGetDrive( $Drive_Type )  ;ALL
EndFunc ;==>UpdateDrives

; Main Loop to Keep the Program Open
; No Real Way of ending this program, except for just killing the process
; Which is what I want, an always on backup for my drive every time I insert it
While 1
 $GuiMsg = GUIGetMsg()
; This is needed because the watch event above not only triggers before a USB Drive is inserted/removed,
; but also AFTER insertion too, and if not reset, a subsequent CD insertion will trigger it again.
; So, every second, we reset $WATCH, to keep things clean
 Sleep (1000)
 $WATCH = False
WEnd

So could someone help mash these two together, I only need to detect USB connected Arduino(s) I have more than one.

Any help or direction to examples greatly appreciated.

Share this post


Link to post
Share on other sites



Is it possible to get this kind of info? I mean can AutoIt pull this info or PowerScript or something? :unsure:

I have many Arduino boards that have a different COM # assigned to each one. The IDE doesn't auto detect for the one that is being programmed so each time I have to go to device manager to lookup the port #.

Now, thinking about it might be possible to edit the driver assigned port # to be the same for each one since I don't have two boards connected at the same time. Another option is to put a label on them.

However, I would like to find a solution with AutoIt and learn something along the way.

Any comments welcomed.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

A label is my favorite!

I would expect that all you need to look for is COM ports and not worry about whether they are usb or not. Suppose you used my COM port UDF (because I am familiar with that) then you can list all the COM ports on the PC with a single function call. Suppose you know that the COM port will be either 12 or 23 (or any list of possibles to choose from)  then your script can check every few seconds to see which one is connected and set the tooltip. So the code would be something like this

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "commmg.au3"  ;Only needed if using my UDF
#AutoIt3Wrapper_Add_Constants=n

HotKeySet("^!{F11}", "EndAll")
msgbox(262144,"Scanning","Press" & @CRLF & "  Ctrl Alt F11"  & @CRLF & "to end")

$portgui = GUICreate("portgui", 100, 30, 0, 0, $WS_POPUP)
GUISetBkColor(0x3333FF)
$Lab1 = GUICtrlCreateLabel("No connection", 3, 3)
GUICtrlSetColor(-1, 0xffffff)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT + $GUI_DOCKWIDTH)
$size = ControlGetPos($portgui, '', $Lab1)
GUISetState()
WinMove($portgui, '', 0, 0, $size[2], $size[3])

$LastLabText = ''

GUISetState()
while 1

    $Text = CheckPortsFromList("Com23,Com38")
    if $Text <> $LastLabText Then
        GUICtrlSetData($Lab1, $Text)
        $LastLabText = $Text
    EndIf

    Sleep(1000)

wend

Func CheckPortsFromList($sList)
    ;Local $aPorts = _CommListPorts(0);using my UDF
    ;OR
    Local $aPorts = CommListPorts(); without using my UDF

    $aList = StringSplit($sList, ',')

    For $i = 1 to $aList[0]
        for $k = 1 to $aPorts[0]
            if $aPorts[$k] = StringStripWS($aList[$i], 3) then return $aList[$i]
        next
    next

    return 'No connection'

EndFunc   ;==>CheckPortsFromList

Func CommListPorts()

    $inst = 1
    $Result = ''
    While 1
        $key = RegEnumVal("HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM", $inst);
        If @error = -1 Then ExitLoop
        $Result &= RegRead("HKLM\HARDWARE\DEVICEMAP\SERIALCOMM", $key)& ','
        ;ConsoleWrite($inst & ' ' & $key & "--->" & RegRead("HKLM\HARDWARE\DEVICEMAP\SERIALCOMM", $key) & @CRLF)
        $inst += 1
    WEnd

    if StringRight($Result, 1) = ',' then $Result = StringTrimRight($Result, 1)

    return stringsplit($Result,',')
EndFunc   ;==>CommListPorts


func EndAll()
    Exit
EndFunc   ;==>EndAll

EDIT: Changed code to be a working example. Requires commmg.au3 and commg.dll - see "Serial port... " in my signature.

EDIT2; Gave option to scan ports without using my serial COMs UDF

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Thanks Martin for your reply, I'm still going through it.

My searches have come across other stuff connected with the Arduino that come back to using your commg.dll file (which is of interest when talking with the board, this will come in handy later). But I'm trying to determine if I can detect which port is the current one that the board is connected to.

I've been seeing the GUIRegisterMsg() function come up in examples and I'm not sure what the 'msgID' is all about. I get that the $WM_COMMAND is a value of 0x111 from  the 'WindowsConstants.au3' file but how does that value come from within the GUI?

On the other hand if the GUI prefix is a windows thing then what function would be for the device manager thing (not sure of the right wording so please bare with me in this learning curve, which is very steep). When I plug into the USB port, I get a pc sound, so there must be something that could be used to trigger a script or UDF. Right? Hmm....am I on the right track?

I enjoyed the video of the glass cutting cnc equipment, just wondering how noise it is? I myself working in a chocolate factory as a maintenance electrician with a lot of automation.

Cheers

Arne

Share this post


Link to post
Share on other sites

I don't know if it's very easy to find which port the arduino is connected to unless there is no other application using that port. The code I gave will let you see which COM ports exists. If there is only one Arduino coonnected at a time and the port for each one only exists when the particular Arduino is connected then the code I showed gives the answer.

If no apps are using the COM port and you don't know which Arduino is plugged in then all you need to do, I suppose, is to send a string to each possible port which isn't already in use and detect an answer which only an Arduino will give.

The glass cutting machines aren't very noisey, but in the same factories there are often toughening plants and they can be extremely noisey. (> 100dB)


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Let me see if I understand correctly. I use BrayTerminal that shows com ports 1 though 7, but only the ones that are available (the ones that aren't grayed out) can be selected.

So if I scan (test) each port save that to a table, then when a com port changes an update compared to the old table should equal the Arduino port I want. :huh2:

Hmmm, that I will have to chew on for a bit but I can see where it's going.

And would the answer to the device manager thing be a...No? I would have thought that getting/detecting that pc sound would have been doable.

Thanks for your time.

Arne

Anyone have knowledge or any small examples about GUI's?  Video's would be good.

Share this post


Link to post
Share on other sites

I maybe misunderstood what you want so here is how I thought it was.

You have one or another Arduino connected but only one at a time.

Each one has a different serial port created when it's plugged in. Suppose these ports are 13, and 23 as in my example. Then the script I showed will tell you which if any is connected.

The sound produced by Windows events is a diversion as far as I can see.

Tell me,

Have I understood?

Have you tried my example?


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Yes, you've got it right, I have twisted it a bit. I thought that your program was to scan a range of ports to see what comes up. Now I see what the idea is.

I have quite a few Arduino's at this point (over 5). And yes, when they are first connected each one is set to a com#.

I did try your example but I thought that it was to scan a range of ports. So I first change the only thing that I thought I understood and that was the port numbers. I used com2 to com11 thinking that was the range I was looking in. And the 'CheckPortsFromList()'  I understood that as, from com2 to com11 not com2,com11,etc.

Okay, so now I see that the list could be as "com11,com6,com4,com5" and this would result in $aList[0] = 4.  Right? And each one will be checked.

I will have to try again.

 

Share this post


Link to post
Share on other sites

$List is only used in the function you need to call. It contains all the COM ports installed on the PC. That list is compared to the string of comma-separated possible ports you pass to the function which returns the first match or returns "no connection".


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

martin, thank you for your replies.
 
I posted another topic that got a reply from jaberwocky6669, that I was able to strip down to just enough lines that work.

Global $hWnd = GUICreate("")
Global Const $WM_DEVICECHANGE = 0x0219
GUIRegisterMsg($WM_DEVICECHANGE, "Find_Arduino")

While 1
    Sleep(100)
WEnd

Func Find_Arduino()
    ToolTip("Com3", 20, 20)
EndFunc ;==>MY_WM_DEVICECHANGE

>Link to other post.

Thanks again

Share this post


Link to post
Share on other sites

Glad you made some progress. How do you know what COM port if any has been changed? The code I posted told you by displaying a message in the top left corner of the screen.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0