From: Dan Caugherty Date: 2007-08-22T03:19:57+09:00 Subject: Serial port programming Hey all -- I'm trying to find what seems to be the holy grail of Ruby programmers: a portable platform-neutral way to access serial ports. As you'd expect Windows is the most vexing platform to deal with. I *thought* I could get away with something like the following under Cygwin (note the default string for opening a Windows serial port). I'm perfectly happy with opening a port and kicking off a thread to keep reading data into a buffer every few milliseconds: def initialize(filename = "COM1:9600,8,N,1") # die horribly if we can't open file for read/write/append @mon = Monitor.new @buf = "" # kick off our collector thread @collector = Thread.new(filename) do |fname| begin if (! (@hdl = open(filename, "w+"))) raise "Cannot open for IO" end loop do if (select([@hdl],nil,nil,0.01)) if newchars = @hdl.read @mon.synchronize do if (0 < newchars.length) then # stick new data into a buffer, let the read method of the instance read the buffer instead @buf << newchars newchars = nil end end end end end rescue $stderr.print "#{filename}: IO failed: " + $! return end @hdl.close end # needed for Cygwin at least @collector.wakeup if (@collector && @collector.alive?) end -- The big problem is that even though the select call returns with a return value indicating that data is waiting, the read call hangs. Using Fcntl to set the IO instance to use non-blocking IO solves nothing. Am I stuck with using the ruby-serialport extension? (And why isn't it a gem by now anyway? Grr..) Thanks in advance, -- Dan