ruby serialport は、このあたりで設定できるボーレートを列挙していて、これら以外のボーレートを設定できないようです (unknown baud rate 例外)。
Linux だと ioctl 経由で設定すれば任意の設定ができるので、以下のようにして無理矢理設定します。(Raspberry Pi でテスト済み)
完全に任意ではなく、近いボーレートに丸められることがあるようです。
#!/usr/bin/env ruby
require "serialport"
SerialPort.class_eval do
TCGETS2 = 0x802c542a
TCSETS2 = 0x402c542b
CBAUD = 0x100f
BOTHER = 0x1000
# struct termios2 {
Termios2 = Struct.new(*[
:c_iflag,
:c_oflag,
:c_cflag,
:c_lflag,
:c_line,
(0...19).map {|n| # c_cc[NCCS] NCCS = 19
"c_cc_#{n}".to_sym
},
:c_ispeed,
:c_ospeed
].flatten);
Termios2::FORMAT = "I!I!I!I!CC19I!I!"
Termios2::FORMAT_POINTER = "P44"
# }
def set_custom_baudrate(baud)
tio = Termios2.new
tio.each_pair {|m,_| tio[m] = 0 }
# read
v = tio.values.flatten.pack(Termios2::FORMAT)
self.ioctl(TCGETS2, v)
tio = Termios2.new(*v.unpack(Termios2::FORMAT))
# write
tio.c_cflag &= ~CBAUD
tio.c_cflag |= BOTHER
tio.c_ispeed = baud
tio.c_ospeed = baud
v = tio.values.flatten.pack(Termios2::FORMAT)
self.ioctl(TCSETS2, v)
# read
v = tio.values.flatten.pack(Termios2::FORMAT)
self.ioctl(TCGETS2, v)
tio = Termios2.new(*v.unpack(Termios2::FORMAT))
if tio.c_ispeed == baud && tio.c_ospeed == baud
true
else
raise "failed to set baudrate expected:#{baud} but set:#{tio.c_ispeed}/#{tio.c_ospeed}"
end
end
end
@port = SerialPort.new(
"/dev/ttyUSB0",
230400,
8,
1,
0
)
@port.set_encoding(Encoding::BINARY)
@port.set_custom_baudrate(250000)
sleep 0.1
# @port << "\xA5"
loop do
data = @port.sysread(4096)
p [data, data.size]
@port << "\x5A"
end