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でもやります。