2017年6月10日土曜日

部活で始めるArduino④「シリアル通信編」

コンピューターやほかの機器と連携する

(マウスでモーターを動かせたらな…)
 とか
(コンピューターの近くの気温が知りたい…)
 と思ったことはありませんか?

ArduinoにはUSBポートとシリアル通信の機能が付いているのでとても簡単に実装することができます。
シリアル通信とはUSBケーブル等を通して0と1の信号を送ったり受け取ったりする技術です。かなり歴史のある通信方法でシンプルかつ汎用性が高いです。

では作業に移りましょう。
今回はArduinoに文字を送り、Arduinoの内蔵LEDを点灯・消灯させてみます。

文字を送り、Arduinoの内蔵LEDを点灯・消灯させる

Arduinoでシリアル通信をする場合、数字や半角文字を送るのが一般的です。そこで例えば「a」が届いたらLEDを点灯、「b」が届いたらLEDを消灯することにします。LEDの点灯消灯については部活で始めるArduino① 「入手と準備と確認編」のプログラムを改造することにします。

ここで使用する関数は

・Serial.begin(通信速度)  … 初期化と通信速度の設定(最初に一回実行)速度はパソコン側の設定と合わせる
・int型もしくはchar型変数 = Serial.read()  … 受信済みの1バイトを読込む(何も届いていないときは−1が返る)
・int型変数 = Serial.available()  … バッファに何バイトたまっているかを返す

の3つだけです。

1バイトを読み込むというのがわかりずらいかもしれませんが、1バイト≒1文字と考えてもらえば分かりやすいです。

▽詳しい説明ですが読まなくてもいいです▽
例えばシリアル通信でパソコンから"a b ¥n"(¥nはwindowsで改行を表す文字コードです)と送ったとします。
パソコンが文字列をASCIIコードで16進数に変換、さらに16進数を2進数に変換してUSBケーブルでピコピコーと発射します。
受け取ったArduinoは2進数を16進数(=1バイト)に戻しバッファ(一時置き場)に届いた順にためていきます。
Serial.read()を実行すると届いた順に1バイトずつ読み込まれる、というわけですさらにchar型変数に格納すると逆のルートをたどって文字に変換されます。

プログラムはこんな感じです。



void setup() {
     pinMode(LED_BUILTIN, OUTPUT);
    Serial.begin(9600) ;
}
void loop() {
    char c ;
    if (Serial.available() > 0) {
        c = Serial.read() ;
        if(c == 'a'){
            digitalWrite(LED_BUILTIN, HIGH);
        }
        if(c == 'b'){
            digitalWrite(LED_BUILTIN, LOW);
        }
    }
}

こちらのサイトやArduino日本語リファレンスを参考にしています。

パソコン側の操作は

①Arduinoと接続する
②Arduino IDEのツール→シリアルモニタを開く
③入力して送信ボタンを押す

です。
文字列で送るとバッファに一文字ずつたまって順番に読み込まれます。

a を送ってLEDが点灯し、bを送ってLEDが消灯したら成功です。

このシリアル通信を使えるということは

  外の世界の状況を観測する(センサーやカメラ)
   ↓
  計算や処理を行う(AIやキーボードからの入力)
   ↓
  外の世界に影響を及ぼす(モーターやLED)

の流れができるということです。ほかの技術と組み合わせれば日々の生活やロボコンにも役立てることができます。


シリアル通信はパソコン側のソフトも(比較的)簡単に自作できるので画像処理なんかと組み合わせても面白いと思います。私は二軸のサーボモータの台座にWebカメラを乗せて顔を追いかけてくる装置を部活で作りました。

このページが困っている人の助けになれば幸いです。