I created this page in case some people may have some questions or answers about [using a serial port] on [Windows]. I just tried to communicate with com1 on a Windows 2000 machine. For some reason I could not receive any data using the following commands in Wish. ====== % proc rd_chid {chid} { set msg [gets $chid] puts $msg } % set com [open com1: r+] % fconfigure $com -mode 9600,n,8,1 -blocking 0 -translation auto -buffering line % fileevent $com readable [list rd_chid $com] ====== However, I was able to receive data by putting those last 3 lines into its own procedure... ====== % proc rd_chid {chid} { set msg [gets $chid] puts $msg } % proc open_com {} { global com set com [open com1: r+] fconfigure $com -mode 9600,n,8,1 -blocking 0 -translation auto -buffering line fileevent $com readable [list rd_chid $com] } % open_com # lots of data comes streaming :) % close $com ====== jg ---- Tcl 8.4 greatly improved serial port control across platforms. Refer to the updated [fconfigure] documentation for more info. ---- To retrieve details on input/output errors--which are, in general, frequent, when working with serial lines--interrogate ====== set details [fconfigure $serial_handle -lasterror] ====== 8.3.4 introduced this capability. ---- How can I connect to a com port higher than 9? (I am using a terminal server, and its driver creates com ports upto 16 or so.) Would appreciate answer by mail - anner@flexlight-networks.com Thanks 25Aug2003 [PS]: You need to use the 'generic' name (I think it is actually the UNC path) of the com port. Use the file name \\.\com13 to open 'com13:' Mind you, windows wants to see those all those \ chars, so use [[open \\\\.\\com13 r+]]. I have not tested this myself... E_NO_ACCESS_TO_BIG_SERIAL_CARD. But it does work :) 20111014 tested with 8.5.9: open //./com13 definitely works (or \\\\.\\com13), shorter variants don't. Interesting detail: if you are using a tclkit app, you can open com5 etc only if you have the current directory NOT within tclkit VFS, but outside of this (com1...4 always open regardless current dir). But using the absolute path as proposed above, VFS or normal current directory does not matter. ---- The following code will enumerate the serial devices on a windows XP machine - including USB devices. ====== package require registry proc get_serial_ports { } { set serial_base "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM" set values [ registry values $serial_base ] set result {} foreach valueName $values { lappend result [ registry get $serial_base $valueName ] } return $result } ====== ---- Yep, the above works fine on XP. Try " return [lsort -dictionary $result]" to get the list sorted... -regards [ZB] 20111012 - yes, it works on my Win XP - but I had the problem, that id did list also the "virtual serial ports" left by Bluetooth device (not connected). Trying to open such serial port resulted in very long pause (almost a minute), before "open" gave up. ---- enumerate serial devices on win2k-win7(Jee Labs version [http://talk.jeelabs.net/topic/208]) ====== # 2010-04-21 improved version, see http://talk.jeelabs.net/topic/208 proc RawListSerialPorts {} { set result {} set ccs {HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet} foreach {type match} { Serenum {^FTDIBUS.*_6001.(\w+)} usbser {^USB\B.*\B(.*)$} } { # ignore registry access errors catch { set enum "$ccs\\Services\\$type\\Enum" set n [registry get $enum Count] for {set i 0} {$i < $n} {incr i} { set desc [registry get $enum $i] if {[regexp $match $desc - serial]} { set p [registry get "$ccs\\Enum\\$desc\\Device Parameters" PortName] # Log . {usb-$serial Port: $p\ Friendly: [registry get "$ccs\\Enum\\$desc" FriendlyName]} lappend result usb-$serial $p } } } } return $result } ====== ---- Note that you most frequently see code something like this: ====== set serial [open "COM1:" "RDWR"] fconfigure $serial -mode 9600,n,8,1 ====== where fconfigure sets the baud rate, etc. of the serial port. [ZB] The above procedure didn't work at all on my Win XP. [PY] As for me, I use next snippet to obtain virtual COM ports: ====== # List all ports as FTDIBUS and USB. Returns list of {PortName, FriendlyName, Auto?} # where Auto is flag - port for HMC6343 or not proc ls_virt {} { set res {} foreach type {FTDIBUS USB} { set k0 "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\$type" set k0ch [registry keys "$k0" VID_*] foreach k1 $k0ch { set k1ch [registry keys "$k0\\$k1"] foreach k2 $k1ch { set Class [registry get "$k0\\$k1\\$k2" Class] if {$Class == "Ports"} { set FriendlyName [registry get "$k0\\$k1\\$k2" FriendlyName] set PortName [registry get "$k0\\$k1\\$k2\\Device Parameters" PortName] set Auto [expr {"silabser" == [registry get "$k0\\$k1\\$k2" "Service"]}]; #auto-detected lappend res [list $PortName $FriendlyName $Auto] } } } } return $res } ====== Third item is a flag - is it our device (I'm looking for HMC6343 sensor, but it's possible to test instead of silabser any other driver/service type). <>Device Control|Windows