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