rust serialport①

e-tipsmemo.hatenablog.com
電力測定のためのアプリを作るために
Rustでserialportを操作する方法を調べた。

非同期だったりとかいろいろあってよくわからなかったが結果的に動いた
serialport-rsを利用することにした。

https://crates.io/crates/serialport

wattchecker-rexが配布しているCのコードで送っているコマンドを表示させた。
f:id:katakanan:20181122221418p:plain

RTC設定→リアルタイム測定2秒ごと繰り返しという処理内容
コマンドをどうやって組み立てているかは見ればわかる

ひとまず
timer : [n]というコマンドを送って
buf[n]という応答が帰ってくればよさそう

fn main() {
    println!("Hello, world!");

    let settings = serialport::SerialPortSettings{
        baud_rate : 115200,
        data_bits : DataBits::Eight,
        flow_control : FlowControl::None,
        parity : Parity::None,
        stop_bits : StopBits::One,
        timeout : Duration::from_millis(1)
    };

    let mut port = match serialport::open_with_settings("/dev/rfcomm0", &settings)
    {
        Ok(p) => p,
        Err(_) => panic!("Error"),
    };

    println!("{:?}", port.settings());
    let cmd = vec![ここにコマンドを入れておく];

    for b in cmd.clone()
    {
        println!("timer : 0x{:02X}", b);
    }

    match port.write(&cmd)
    {
        Ok(_) => println!("OK"),
        Err(e) => eprintln!("{:?}", e),
    }

    let mut buffer : [u8; 1] = unsafe{mem::uninitialized()};
    loop{
        match port.read(&mut buffer)
        {
            Ok(bytes) => if bytes == 1
            {
                println!("0x{:02X}", buffer[0]);
            },
            Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
            Err(e) => eprintln!("{:?}", e),
        }
    }
}

serialportのサンプルコードをそのまま利用
Err(ref e)でタイムアウトのエラーを無視している。
これで特定の長さを受信したら外のloopをbreakすればよさそう。

f:id:katakanan:20181122222046p:plain

うまくいった。(この時はすでにRTCコマンドも計算してしまった)
コマンドの計算にはCRC8なども出てくるのでそれはCRC8-crateなどを利用した。

次回は別スレッドでコマンドを送信しながら
方やデータ受信してそれをどうにかするというものを書く予定。(サンプルdeplexを利用すれば簡単そう)

プログラミングRust

プログラミングRust

Raspberry Pi 3 MODEL B

Raspberry Pi 3 MODEL B

Raspberry Pi 3 Model B+ スターターセット BASIC

Raspberry Pi 3 Model B+ スターターセット BASIC