2005年6月2日木曜日

「シリアル通信」

私は現在は主にJavaを利用した比較的大規模なシステム構築に携わっています。
でもこのシステムは世で頻繁に使用されているWebシステムではありません。
さらにこのシステムはJavaでRS232C通信、Socket通信等を使用しています。
なぜなら対象が人間ではなくて装置であることが多いためにこのような構成を必要としているからです。

今回は私が経験した中で世間ではあまり使われていないであろうJavaによるRS232C通信について必要なライブラリー、サンプルを紹介します。

以下の話はJavaで開発できる環境が整っている前提で進めます。

実行するためには「Java Communication API」が必要です。
こちらからダウンロードして下さい
ダウンロードしたら配置手順に従って拡張ライブラリーを配置してください。

1.シリアルポートのオープン
 Java Communication APIにはシリアルポートを制御するクラスが用意されています。
 シリアルポートを利用するにはまずどのポートを利用するかを宣言してCommPortIdentifierオブジェクトを取得します。
 次に取得したCommPortIdentifierをOpenしてSerialPortクラスにキャストします。
 このままでも利用できますが各パラメータの設定方法も合わせて載せておきます。

CommPortIdentifier port = CommPortIdentifier.getPortIdentifier("COM1");
// ユニークな名前でシリアルポートを開く
SerialPort serialPort = (SerialPort) port.open("SerialPort", 30000);
// シリアルポートのパラメータを設定
serialPort.setSerialPortParams( 9600,        // Baudrate
              SerialPort.DATABITS_8,   // Data Bits
              SerialPort.STOPBITS_1,   // Stop Bits
              SerialPort.PARITY_NONE); // Parity Bit
              // Flow Control Mode
              serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

2.入力/出力ストリーム
 ポートを開いただけではデータの送信/受信ができませんよね。
 データ送受信はストリームを介して行います。ファイルの読み書きのように扱えます。

// 入力ストリームを取得
in = serialPort.getInputStream();
// 出力ストリームを取得
out = serialPort.getOutputStream();

3.リスナー登録
 シリアルポートからのデータはリスナー登録することでイベントが飛んできます。
 インプリメントするリスナークラスはSerialPortEventListener。

// イベントリスナー登録
serialPort.addEventListener(this);
// シリアルポートがデータを受信した際に教えてねと設定
serialPort.notifyOnDataAvailable(true);

4.データ送信
 送信は先ほど取得した出力ストリームを使用して送信できます。

byte[] bytes = "送信テスト".getBytes();
out.write(bytes);    // 出力ストリームにバイト列を書き込む
out.flush();       // 出力ストリームをフラッシュ

5.データ受信
 受信はSerialPortEventListenerのserialEvent(SerialPortEvent)メソッドを実装。

public void serialEvent(SerialPortEvent arg0) {
  if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
    StringBuffer inputBuffer = new StringBuffer();
    int newData = 0;
    while (true) {
      try {
        newData = is.read();// 入力ストリームから読み込み
        if (newData == -1 || newData == 0x02) {// EOF or ETX?
          break;
        }
        if ('\r' == (char)newData) {
          inputBuffer.append('\n');
        } else {
          inputBuffer.append((char)newData);
        }
      } catch (IOException ex) {
        System.err.println(ex);
        return;
      }
    }
  }
}

6.クローズ
 オープンしていたシリアルポート、ストリームはちゃんと閉じましょう。

in.close();
out.close();
serialPort.close();


まあこんな感じでシリアル通信のテストが出来るはずです。
他のPCと接続してテストする際はシリアルケーブルのクロスを使用しないとできませんよ!!

どうです?動きました?