See Also edit
- chan configure (fconfigure)
- the standard command for configuring serial port channels
- channel
- nearly everything but the socket information is related to serial ports
- close
- for closing a serial port channel
- fileevent
- for readable/writable callbacks
- open
- the standard command to open serial ports. port names are platform-dependent. all relevant serial-port options to fconfigure are described on th man page for open
- Parallel port
- serial ports on Windows
- Serial Port Central
- Jan Axelson's site about serial links and networks, including RS-232, RS-485, COM ports, and USB virtual COM ports, and his book, "Serial Port Complete"
RS485 communication guide - RS485 Testing: Main information about RS485 communication. What is RS485: main features of RS232 communication. How to monitor and analyze RS485 port activity with RS485 Tester app.
Documentation edit
- serial port ,Wikipedia
- RS-232 ,Wikipedia
Examples edit
- apache tcl cgi script with serial port access
- Bwise, a serial port tcl script and a Xilinx demo board
- A simple serial terminal
- How to build a simple serial terminal in a text widget
- How to read the serial port, and display in hexadezimal
- List computations in a FPGA, driven by Tcl
- More Serial Port Samples
- How to read the serial port, and display in hexadezimal
- Serial Port Logic Analyzer Screen Capture
- SerPortChat
Tools edit
moni: a serial line monitorSerial Player: a Windows utility for recording and playing back data from the serial communications port of the computerSerial Port Monitor: is a professional and powerful system utility for monitoring, logging and analyzing RS232/422/485 COM port activity.Portmon for Windows: a proprietary but freely available program that displays all serial and parallel port activity on a systemSerial line sniffer: open-source licenseSerial over IP/TCP: allows to share and access serial port over IP NetworkVirtual COM Port Driver: create virtual COM ports paired by virtual Null Modem to be applied in serial port programmingSerial Port Communication Software: emulate ports for interfacing with serial devices and apps - an ideal solution in case you are developing a software for Windows OS.Serial Port Splitter: is a versatile tool that allows to split one port among several applications in such way that they can all get the same data at the same time.- Tcl-DP
- provides serial line features
Description edit
On Linux, opening a special device with the proper major/minor numbers always succeeds independent of there being any hardware attached or not. The first error usually happens when doing chan configure -mode ... with -mode not a valid option for ...On NetBSD, when a terminal file is opened, it normally causes the process to wait until a connection is established. For most hardware, the presence of a connection is indicated by the assertion of the hardware CARRIER DETECT (DCD) line. This is a problem since most hardware and/or cables in common use ignores this line. Using the NONBLOCK flag with open is not enough to get things right, because the DCD is also used to detect the eof condition, causing the channel to assert eof after the first read or gets. There's patch at feature request 603 which adds a new flag to chan configure, -ignoredcd (only on unix machines with conforming termios interface) which controls whether the underlying device driver ignores the DCD line or not. Without this patch, the (non-portable) way to use a serial port lacking the DCD line is:set device /dev/tty00 set fd [open $device {RDWR NONBLOCK}] exec stty -f $device clocalSerial lines have many characteristics known to Tcl. fconfigure is their usual interface. Typical options include -ttycontrol, -ttystatus, -timeout, and more.
Basic Example edit
D. J. Hagberg mailto:dhagberg@millibits.com:Here is a simple example... The [send_exp] stuff is pretty generic and should work for any channel that supports non- blocking I/O.# simple serial port example to send AT to modem and # wait for OK response in a fixed amount of time. At the # bottom is a simple loop to do this 20x to check serial # handler reliability... # # Works well on Tcl 8.0 and up on Unix (Solaris/NT), poorly on # the tclsh included with Tcl 8.1.1 on NT, but pretty well on # the wish included with same. # # NOTE may need to set comPort appropriately for your # platform. Must have a modem configured to respond # with "OK" to "AT" commands. # switch $tcl_platform(os) { {Linux} {set comPort /dev/modem} {SunOS} {set comPort /dev/cua/a} {Windows NT} {set comPort COM2:} default {error "Must configure comPort"} } set waitSecs 2 set nTries 20 # # A cheap version of expect. # # Set up a event-driven I/O reader on the channel, output the # string, and wait some number of seconds for the result. # # @param fh # a channel opened in non-blocking mode for I/O # with buffering turned off. # # @param outstr # a string to send to the output channel -- note: end- # of-line characters must be included in this string, # if desired. # # @param regexp # regular expression to match in the incoming data. # # @param seconds # number of seconds to wait for above match # # @throws error # if eof is detected on the channel while waiting # # @returns int # 1 if a match is found, 0 otherwise. # proc send_expect {fh outstr regexp seconds} { global send_exp # make sure global vars are initialized properly set send_exp($fh.matched) 0 if {![info exists send_exp($fh.buffer)]} { set send_exp($fh.buffer) {} } # set up our Read handler before outputting the string. if {![info exists send_exp($fh.setReader)]} { fileevent $fh readable [list private_send_exp_reader \ $fh $regexp] set send_exp($fh.setReader) 1 } # output the string to send puts -nonewline $fh $outstr flush $fh # set up a timer so that we wait a limited amt of seconds set afterId [after [expr {$seconds*1000}] \ [list set send_exp($fh.matched) 0]] vwait send_exp($fh.matched) set matched $send_exp($fh.matched) unset send_exp($fh.matched) catch [list after cancel $afterId] # If we got an eof, then throw an error if {$matched < 0} { error "Channel EOF while waiting for data" return 0 } return $matched } # # PRIVATE channel read event handler for send_expect. Should # not be called by user. # proc private_send_exp_reader {fh regexp} { global send_exp if {[eof $fh]} { close $fh set send_exp($fh.matched) -1 return } append send_exp($fh.buffer) [read $fh] if {[regexp $regexp $send_exp($fh.buffer)]} { set send_exp($fh.matched) 1 } } # # Return the current contents of the send_expect buffer # # @param fh # channel identifier that was used with send_expect # # @returns string # the current contents of the buffer for the channel # proc send_exp_getbuf {fh} { global send_exp return $send_exp($fh.buffer) } # # Reset the send_expect buffer, returning its contents # # @param fh # channel identifier that was used with send_expect # # @returns string # the current contents of the buffer for the channel # proc send_exp_resetbuf {fh} { global send_exp set buf $send_exp($fh.buffer) set send_exp($fh.buffer) {} return $buf } # # Close out a send_expect session, closing I/O event handler # # @param fh # channel identifier that was used with send_expect # # @returns # the channel identifier passed as the fh parameter # proc send_exp_end {fh} { global send_exp fileevent $fh readable {} foreach v [array names send_exp $fh.*] { catch [list unset send_exp($v)] } return $fh } ## ## MAIN ## set fh [open $comPort RDWR] fconfigure $fh -blocking 0 -buffering none \ -mode 9600,n,8,1 -translation binary -eofchar {} # Loop nTries times, sending AT to modem and expecting OK. set nMatches 0 for {set i 0} {$i < $nTries} {incr i} { if {[send_expect $fh "AT\r" "OK" $waitSecs]} { incr nMatches regsub -all "\r" [send_exp_getbuf $fh] {\r} buf regsub -all "\n" $buf {\n} buf puts "GOT MATCH: <$buf>" } else { puts "NO MATCH IN $waitSecs SECONDS" } send_exp_resetbuf $fh } send_exp_end $fh close $fh puts "Matched $nMatches/$nTries\ ([expr 100.0*$nMatches/$nTries]%)"
RJM: Via the serial communication resources, one can also communicate via USB. However, this will surely work with one specific USB peripheral chip, namely from FTDI.Resource: http://www.ftdichip.com/FTDrivers.htmThey provide a royalty-free USB driver. With Tcl apps the virtual com port driver can be used.Advantages over RS-232:
- USB protocol handles transmission errors, so protocol free communication is possible
- high speed
Twylite: Note that on Windows you can use the device aliases "COM1" .. "COM9" (the trailing colon is not necessary), but to access higher numbered COM ports (quite common when using USB-to-serial converters or Bluetooth dongles) you must use the Win32 device name e.g. {\\.\COM14} .HaO 2015-05-29: We are currently (Tcl/Tk8.6.4) suffering from a bug ed5be77734 that in wish (not tclsh), serial port names are not accepted with following ":".
[George] - 2015-11-24 11:52:35Helpful code! I'm a complete beginner and I wanted to try to alter this to send messages over an RS422 loopback and read out the reply. I had some issues, but learned that for anyone trying to do something similar, sending longer messages over serial ports, I had to add:puts -nonewline $fh $outstr after 200 flush $fhThis "after 200" command fixed the issues of only part of the message being sent. I suspect this may not be a far reaching issue but on the off chance anyone has a similar problem! :)