シリアル通信

 Arduinoなどの組み込みコンピュータは最終的には「自立して」動作することを目的としますが、開発の途中ではPCを利用して、回路の状態をチェックしたり、回路に指示を与えることができると便利です。Arduino のシリアルモニターはこの機能を提供してくれます。また、シリアル通信は他の小型のデバイスとの通信に便利です。

  1. RS通信機能

     現在パソコン(PC)と周辺装置との通信には USB(Universal Serial Bus)が広く利用されています。しかし、このUSBによる通信機能は高度な機能を含むため、多くの小型の組み込みコンピュータには組み込まれていません。 UNO の場合も、USB との接続には MPU とは別のチップを利用しています。UNOには「古典的な(legacy:レガシー)シリアルインタフェース」を行う機能が組み込まれています。この古典的なシリアルインタフェースをここでは RS(シリアル)通信とよびます。
     下図で、USB からのメッセージは USBシリアル変換チップで 「RSシリアル」に変換されます。この信号が MPU と ディジタル端子の 0,1番 に接続されています。

          UNO のUSBとRSシリアルの流れ

     WindowsPC の機種によってはこの RS通信の端子は COM 端子として直接接続することもできますが、最近では、USB の機能を利用して RS通信を行います。また、Arduino の本体には RS通信機能が 「シリアルモニター」として組み込まれています。

  2. UNO側のRS通信機能

     Arduino で RS通信を利用するには、まず、setup() で次の命令を実行します(9600の意味は後で説明します)。
      Serial.begin(9600);
    これで、シリアルモニターが利用できるようになります。文字を送るには、次の命令を利用します。
      Serial.print(<文字列>または<変数> ); 
      Serial.print(<文字列>または<変数> ); //表示後改行する
     Serial.print("val = " ); で は( )内の文字列 "val = " を送信します。 Serial.println(val); では val の値を文字に変換して送信し、改行します(println の最後の ln は改行を指示します)。

  3. PC側でのRS通信

     PC側での Arduino 開発環境では、USB を通して UNO とRS 通信を行います。Arduino の開発環境を組み込むとき必要となったドライバーの組み込みは、この「USB を経由したRS通信機能」の準備だったのです。このRS通信機能を利用して、開発環境は作成したプログラムを送り込みます。
     一方、 UNO 側には、あらかじめ RS通信で送られてくるプログラムを受け取り、プログラムメモリーに書き込む機能(プログラムローダーとも呼ばれます)が組み込まれています。このローダー機能でプログラムを受け取り実行を開始します。
     この中で、RS通信命令(Serial.println())があると、UNO からUSBを通して文字が送られ、Arduino の開発環境にあるシリアルモニターに表示されます。

  4. シリアルモニター

     Aruduino の開発環境には、「シリアルモニター」とよぶ Arduino の値を PC 側で表示する機能が組み込まれています。UNO からシリアルモニターに文字を送るには、Serial.print(<文字列>または<変数> ); を利用します。   Arduinoのメニューバーで 右の (シリアルモニター)をクリックすると、シリアルモニターが起動し、受信した文字を表示します。下段の 「自動スクロール」のチェックをはずすと、画面のスクロールが停止します。この状態で、モニターの文字列をコピーし、別の文書に貼り付けることができます。
     シリアルモニターの上段には、文字を編集する欄があります。ここに文字を入力し、「送信ボタン」を押すと、文字が送信されます。
  5. RS通信プログラム

     まず、setup() が実行され、Serial.begin(9600); でシリアル通信を準備します。次に loop()を繰り返し実行します。まず、sensorValue = analogRead(analogInPin); で analogPin(A1端子)を読みこみ、SerialPrintln()でその値を表示し、100mS待ちます。これを繰り返します。
    //serial テスト
    
    int val;
    void setup(){
      //RS通信準備
      Serial.begin(9600);
      val=0;
    }
    
    void loop(){
      val=val+1;
      //valの値を送信
      Serial.print("val=");
      Serial.println(val);
      delay(500);
    }
    下はシリアルモニターの表示です。


  6. 通信速度(bps)

     RSシリアル通信は電話線を利用してデータを送る方式の基礎技術になっています。この場合、ディジタルを音の変化に変換して送る必要があります。最初に実用化されたのは秒あたり 300回 の音の高低の変化で送る方式でした(この変換装置をモデムとも呼びます)。変換速度は次第に速くなり、600,1200,2400.9600 と倍々に進化してきました。秒当たり9600ビットは電話線で保証される最大の通信速度です。秒当たりのビット数は bps(bit per sec)の単位で表記されます。
     Serial.begin(9600); では、192000 や 384000 も選択できますが、このとき、シリアルモニターの右下にある bps の値を合致させる必要があります。RS通信ではその他に ビット長、ストップビット数、パリティ、などの指定がありますが、ほとんどは 8,1,N(No) の設定で問題ないでしょう。

  7. 配列

     ここで、配列型データの予習をしておきます。「配列」は複数のデータの並びに、同じ名前をつける機能です。以下の例では10個のデータの配列を定義しています。aray[ ] の方は実際のデータの値を指定しています。aray2[] では個数のみを指定し、値は指定していません。
      int aray[]={7,12,25,32,47,52,68,77,83,99};
     int aray2[10];
     特定の配列の値を取り出すには 次のように、配列名の後の [ ] 内に番号をつけて指定します。先頭の番号は 1 でなく 0 ですから注意してください。
     配列名[番号] //番号は 0 が先頭
     aray[0]  //7 
      aray[3]  //32
     配列の値を順にシリアルモニターに送信するプログラムを紹介します。変数 i で配列の番号を指定しています。i の値が 10 になったら、 0 に戻しています。
    //配列のサンプル
    int i;
    int aray[]={7,12,25,32,47,52,68,77,83,99};
    
    void setup(){
      //RS通信準備
      Serial.begin(9600);
      i=0;
    }
    
    void loop(){
      //valの値を送信
      Serial.print("val=");
      Serial.println(aray[i]);
      i=i+1;
      if(i == 10) i=0;
      delay(500);
    }
     シリアルモニターの表示(途中)は以下のようになります。

     
  8. 発展

     
    1. RS通信はどんな波形で送信するのですか?

       下図のように、まず最初に開始の合図として 0 を出力(スタートビット)、,次ぎに下位ビットから順に8ビットを出力し、最後に1ビット以上の1を出力します(ストップビット)。ストップビット終了後、任意の時点で次の文字を出力できます。スタートビットの開始時刻は特定の時刻に限定されないので、非同期通信とも呼ばれます。1ビットの時間間隔が bps を定めます。


    2. 特定のデバイスに指定した送信はできませんか?

       拡張された機能で宛先を指定する方式もありますが、一般的ではありません。宛先を指定するシリアル通信方式として、「I2c接続方式」の章で紹介します。

    3. RSシリアルには、専用のハードウエアが必要ですか?

       bps が大きくなければ、ソフトウエアで送受信可能です。Arduino でも SoftSerial としてライブラリが公開されています。問題は、受信でどのタイミングで到着するか不明な場合、ハードウエアによる受信と割り込み機能が必要です。割り込みを利用した受信については、「割り込み」の章で紹介します。