RubyでIOを使いたい(シリアルポート編)
さて、先日の
http://d.hatena.ne.jp/xibbar/20110405#1302101791
の記事はソースはCで作ったのですが、
Rubyでやりたくなりますよね。
だって、irbでIOの制御とかかっこよすぎです。(ホントか?)
というわけで、Rubyで書いてみました。
まず、/usr/include/asm-generic/ioctls.h の
定数がいくつか重要なので、メモっておきます。
#define TIOCM_LE 0x001 #define TIOCM_DTR 0x002 #define TIOCM_RTS 0x004 #define TIOCM_ST 0x008 #define TIOCM_SR 0x010 #define TIOCM_CTS 0x020 #define TIOCM_CAR 0x040 #define TIOCM_RNG 0x080 #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG
こんな感じで定義されています。
あと、ioctlのTIOCMGETも必要ですね。
/usr/include/asm-generic/ioctls.h
で定義されています。
#define TIOCMGET 0x5415
これらを全部Rubyの中に書いちゃいましょう。
#!/usr/bin/env ruby TIOCM_LE =0x001 TIOCM_DTR=0x002 TIOCM_RTS=0x004 TIOCM_ST =0x008 TIOCM_SR =0x010 TIOCM_CTS=0x020 TIOCM_CAR=0x040 TIOCM_RNG=0x080 TIOCM_DSR=0x100 TIOCM_CD =TIOCM_CAR TIOCM_RI =TIOCM_RNG TIOCMGET =0x5415 DEVICE="/dev/ttyUSB0" fh=open(DEVICE,"r") ret="" loop do fh.ioctl(TIOCMGET,ret) lsstat=ret.unpack("S")[0] print (lsstat & TIOCM_CTS >0) ? " CTS on " : " CTS off " print (lsstat & TIOCM_CD >0) ? " DCD on " : " DCD off " print (lsstat & TIOCM_DSR >0) ? " DSR on " : " DSR off " puts (lsstat & TIOCM_RI >0) ? " RI on " : " RI off " sleep(3); end
sudo ruby serial_test.rb
とかってやって実行してみると、
$ sudo ruby serial_test.rb CTS on DCD on DSR on RI on CTS on DCD on DSR on RI on CTS on DCD on DSR off RI on CTS on DCD off DSR off RI on CTS on DCD off DSR off RI off CTS off DCD off DSR off RI off
こんな感じに値が得られます。
Cのソースとの長さの違いには驚きますが、
まあいいでしょう。用途が全然違いますし。
とりあえず、入力を取ることはできたのですが、
電源を別に用意しなければならないのは超めんどくさいです。
電池でもなんでもいいんですけど、
別で用意するのは面倒です。
USBは5V電源が入っているので、
これを流用できたらレギュレータで3.3Vぐらいに落として
使えるのになぁと思いました。