I've tried the following code on Windows XP, Ubuntu, and SuSE, I've verified
that the serial connection is opened and if I call serial_receiver manually
everything works, the problem is fileevent is never calling serial_receiver.
I've tried the latest 8.4 and 8.5 TCL releases both from tcl.tk and
ActiveTCL.
I've tried adding the fileevent before and after the proc to no avail.
Any help is greatly appreciated.
# this is changed based on OS, windows in this case
set serial [open com1: r+]
fconfigure $serial -mode "9600,n,8,1" -blocking 0 -buffering
none -translation binary
fileevent $serial readable [list serial_receiver $serial]
proc serial_receiver { chan } {
if { [eof $chan] } {
puts stderr "Closing $chan"
catch {close $chan}
return
}
set data [read $chan]
set size [string length $data]
puts "received $size bytes: $data"
Should not make a difference since the filevent only triggers when TCL
becomes idle.
| proc serial_receiver { chan } {
| if { [eof $chan] } {
| puts stderr "Closing $chan"
| catch {close $chan}
| return
| }
| set data [read $chan]
| set size [string length $data]
| puts "received $size bytes: $data"
Apart from the obvious missing close brace for the proc this should
work...
You also need to make sure that the output at the writing end of the
serial port is unbuffered and flushed properly.
R'
Thanks for the response, the close brace was a copy paste error (oops :)).
I've configured the port for unbuffered but it still doesn't work, the
frustrating thing is Moni uses fileevent and it works fine on Windows with
this device, I even took their serial port initializing code and it still
doesn't work.
Here is my latest attempt which has the same problem, when Read is called
manually everything works, but fileevent isn't calling Read. At this point
I'm considering emulating fileevent with a second thread calling -queue
every so many ms but would like to avoid that.
proc Read {} {
global serial
if { [eof $serial] } {
puts stderr "Closing $serial"
catch {close $serial}
return
}
set data [read $serial]
set size [string length $data]
puts "received $size bytes: $data"
}
set serial [open com1: r+]
fconfigure $serial -translation binary -blocking 0
fconfigure $serial -buffering none
fconfigure $serial -mode "9600,n,8,1"
fileevent $serial readable Read
Thanks Helmut, it is a plain TCL program, adding vwait forever solved the
problem.
Thanks again!
Jason