Runner Posted December 20, 2013 Posted December 20, 2013 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: expandcollapse popupDim $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.
Runner Posted December 20, 2013 Author Posted December 20, 2013 Is it possible to get this kind of info? I mean can AutoIt pull this info or PowerScript or something? 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.
martin Posted December 20, 2013 Posted December 20, 2013 (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 expandcollapse popup#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 December 22, 2013 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.
Runner Posted December 23, 2013 Author Posted December 23, 2013 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
martin Posted December 23, 2013 Posted December 23, 2013 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.
Runner Posted December 24, 2013 Author Posted December 24, 2013 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. 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.
martin Posted December 24, 2013 Posted December 24, 2013 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.
Runner Posted December 24, 2013 Author Posted December 24, 2013 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.
martin Posted December 24, 2013 Posted December 24, 2013 $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.
Runner Posted January 6, 2014 Author Posted January 6, 2014 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
martin Posted January 6, 2014 Posted January 6, 2014 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now