Serial Ports on Windows
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 - [email protected]
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 :)
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 [L1 ])
# 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.