Rust serialport お試し①
はじめに
Rust でシリアル通信したくなったので、serialport クレートを使ってみます。
serialport クレート
serialport クレートはクロスプラットフォームで使えるシリアルポートライブラリです。 各プラットフォーム固有の API も提供しています。
using blocking I/O with serial ports
とあるので、async には対応していなさそうです。
環境
open
シリアルポートの open はビルダーで行います。デバイスパスとボーレートを指定して SerialPortBuilder
オブジェクトを取得し、シリアルポートの設定を行います。
let mut port = serialport::new("/dev/ttyUSB0", 115200) .stop_bits(serialport::StopBits::One) .data_bits(serialport::DataBits::Eight) .timeout(Duration::from_millis(10)) .open() .unwrap_or_else(|e| { eprintln!("Failed to open \"{}\". Error: {}", "/dev/ttyUSB", e); ::std::process::exit(1); });
new()
は下の通りなので、ストップビットとデータビットはデフォルト値で良いのですが、お試しのために設定しています。
serialport/src/lib.rs
pub fn new<'a>(path: impl Into<std::borrow::Cow<'a, str>>, baud_rate: u32) -> SerialPortBuilder { SerialPortBuilder { path: path.into().into_owned(), baud_rate, data_bits: DataBits::Eight, flow_control: FlowControl::None, parity: Parity::None, stop_bits: StopBits::One, timeout: Duration::from_millis(0), } }
大体普通のシリアルポート設定が SerialPortBuilder
でできます。受信時のタイムアウトが timeout()
で設定できます。
serialport/src/lib.rs
/// Set the amount of time to wait to receive data before timing out pub fn timeout(mut self, timeout: Duration) -> Self { self.timeout = timeout; self }
open()
の代わりに open_native()
すると、プラットフォーム固有のシリアルポートオブジェクトが取得できます。
serialport/src/lib.rs
/// Open a platform-specific interface to the port with the specified settings #[cfg(unix)] pub fn open_native(self) -> Result<TTYPort> { posix::TTYPort::open(&self) } /// Open a platform-specific interface to the port with the specified settings #[cfg(windows)] pub fn open_native(self) -> Result<COMPort> { windows::COMPort::open(&self) }
read
手元のマイコンボードから送信された Hello World
を受信してみます (とりあえずエラーは無視しています) 。
let mut serial_buf: Vec<u8> = vec![0; 1000]; loop { match port.read(serial_buf.as_mut_slice()) { Ok(t) => io::stdout().write_all(&serial_buf[..t]).unwrap(), Err(_e) => {}, } }
$ cargo run # マイコンボードをリセットします hello world
お、ええやん。