IOを使いたい(シリアルポート編)
みんなよく知っているシリアルポート、
これはデータの通信に使う、かなりレガシーなしくみです。
ただ、シンプルなので、やはり使いやすいのがミソです。
シリアルポートと一般的に呼ばれている
RS-232CのD-sub9ピンには次のようなピンがあります。
1 | DCD | キャリア検出 | 入力 |
1 | RXD | 受信データ | 入力 |
1 | TXD | 送信データ | 出力 |
1 | DTR | データ端末レディ | 出力 |
1 | GND | グラウンド | なし |
1 | DSR | データセットレディ | 入力 |
1 | RTS | 送信要求 | 出力 |
1 | CTS | 送信可能 | 入力 |
1 | RI | 被呼表示 | 入力 |
このうち、RXDとTXDだけがデータのやり取りをしていて、
それ以外はモデムの状態のやりとりしか
使われていないようなものです。
つまり、IOとして使えそうです。
というわけでやってみました。
まずは入力のテスト。
各ポートからスイッチ経由でGNDにつなげばOKです。
チェックするソースはこちら。
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <unistd.h> #include <stdlib.h> #define DEVICE "/dev/ttyUSB0" int main() { int fd; int arg, lstat; fd = open( DEVICE, O_RDWR | O_NOCTTY | O_NDELAY); if( fd < 0 ){ perror( "device open error" ); exit(1); } while(1){ ioctl( fd, TIOCMGET, &lstat ); if( lstat & TIOCM_CTS ){ printf( " CTS on " ); }else{ printf( " CTS off " ); } if( lstat & TIOCM_CD ){ printf( " DCD on " ); }else{ printf( " DCD off " ); } if( lstat & TIOCM_DSR ){ printf( " DSR on " ); }else{ printf( " DSR off " ); } if( lstat & TIOCM_RI ){ printf( " RI on " ); }else{ printf( " RI off " ); } printf( "\n" ); fflush(stdout); usleep(500000); // 500usec delay(検出周期を設定) } return 0; }
結果は、
CTS off DCD off DSR off RI off CTS off DCD off DSR off RI off CTS off DCD off DSR off RI on CTS off DCD off DSR on RI on CTS off DCD on DSR on RI on CTS on DCD on DSR on RI on
私が使ったUSBシリアルの変換ケーブルは
秋月電子で売っている950円のものですね。
チップはprolificのようです。
こんな感じになります。
GNDに直接ポートを繋ぐだけではだめで、
電圧をかける必要があります。
私は隣に見えるICから3.3V電源を拝借して使いました。
スイッチも面倒だったので、
ブレッドボードに直接差してしまいました。
というわけで、シリアルポートをつかって、
スイッチのオンオフを検出することはできました。
でも、電源が必要だったりして、めんどくさい。
回路を組んだ方が楽だと思います。
次はシリアルポートを使って、LEDでもやります。