Serial Port Programming

I have an application that needs to talk to a serial port. I was trying to use this library http://ruby-serialport.rubyforge.org/, however I was unable to get blocking IO to work using this. I know what the response I'm supposed to get was, and sometimes I would get it after sending a message. But if I sent a message a bunch of times it seemed far more likely I would correctly read out the right response, but often it was embedded in a bunch of garbage in either case. I know the wire protocol only needs a message to be sent once, but it just seems to act really weird. Anyone have any ideas on this? Any vague ideas of what might be causing problems though?

Charles Comstock

···

---

require 'serialport'

def unhex(msg)
   msg.split(/ /).map {|x| x.hex.chr}.join
end

def hex(msg)
   unless msg.nil?
     return msg.split(//).map {|x| "%X" % x[0]}.reject {|x| x == "F0"}.join(" ")
   else
     return ""
   end
end

def serialport
   sp = SerialPort.new(0,9600,8,2)
   sp.sync = true
   sp.read_timeout = 0 # docs seem to suggest these two settings should
                        # get blocking io
   yield sp
   sp.close
end

START = unhex("F8 55 AA 66")
GETTIME = unhex("F8 55 AA CC")

serialport do |sp|
   sp.syswrite START
   sleep 1
   out = sp.sysread(20)
   p hex(out),out
   sp.syswrite GETTIME
   sleep 1
   out = sp.sysread(20)
   p hex(out),out
end

# this was my old method, using just regular read/write instead of
# sysread/syswrite
# alot of this code I kept modifying as I went as I tried to get it to
# work so there oddities because of this, none of the methods worked
# however

def old()
   #N = 1
   serialport do |sp|
     p sp.methods - Object.new.methods
     out = sp.read
     res = out#.gsub(/#{unhex("F0")}/,"")
     puts "#{out.size} - #{res.size} #{res}"
     N.times {sp.write START}
     out = sp.read
     puts hex(out.gsub(/#{START}/,"")),out
   end
   puts "time"
   serialport do |sp|
     out = sp.read
     res = out#.gsub(/#{unhex("F0")}/,"")
     puts "#{out.size} - #{res.size} #{res}"
     N.times {sp.write GETTIME}
     out = sp.read
     puts hex(out.gsub(/#{GETTIME}/,"")),out
   end
end