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
  1. トップ
  2. tech
  3. ruby-serialport で任意のボーレートを設定するには (ただし Linux に限る)