9 ProcessingでArduinoの入力を処理 2 [ASCII]
Serial Call Response ASCII
				今回は、コール・アンド・レスポンス(ハンドシェイク)方式を使用した、Arduinoボードからコンピューターへの文字列ベースの通信を紹介しています。
				
				このサンプルスケッチでは、Arduinoが、起動時にASCII 'A'(値65)を送信し、コンピューターからシリアル応答があるまで 'A' 送信を繰り返します。応答があると、ジョイスティクからの3つのセンサー値(Xボリューム、Yボリューム、スティクSW)をASCIIエンコードした文字列として送信します。3つのセンサー値はコンマで区切り順に送信し、改行とキャリッジリターンで終了します。コンピューターの次の応答を待ってから、次の3つのセンサー値を処理し送信します。
				
				Processingでは、カンマ区切りの文字列を受信し、文字列を再び数値に変換します。Arduinoからは文字列で送信されるため、一般的な通信ソフトや Arduino IDE シリアルモニターを使用して送信データを表示することもできます。
				
				これを前回の例と比較してみると、どちらもハンドシェイク方式を使用するという点では似ていますが、前回はセンサーの読み取り値をバイナリ値として送信し、今回は文字列にエンコードして送信します。ASCIIエンコードされた文字列として送信するにはより多くのバイト数が必要ですが、センサーの読み取り値が 255より大きい値でも簡単に送信できる特徴があります。また、シリアル通信プログラムでも読みやすくなっています。
実行時のMacの画面は前回と同様で、黒のウインドが現れ中央に白いボールが表示されています。接続したジョイスティックを動かすと、白いボールがスティックの動きと同じ動きをします。ジョイスティクを押し込むとスティク内のSWがONになり白いボールは見えなくなります。
				
必要なハードウエア
この記事を実行するのに必要なハードウエアは、以下の通りで SW付きジョイスティクを Arduino に接続します。
- Arduino
 - ジョイスティク
 - USBケーブル
 - Mac
 
3つのセンサー信号を発生させるのにジョイスティクを使用しましたが、電圧が 0 から 5vの範囲で変化するものなら、どのようなものでも接続が可能です。例えば、単にポテンショメータを取り付けても十分にこのスケッチの動作確認が可能です。
動作確認
動作確認は以下の手順で行います。
- Arduino にジョイスティクを取り付ける
 - Arduino IDE にスケッチを書く
 - Arduinoボードにスケッチ書き込む
 - Processing IDE にスケッチを書く
 - Processing を実行する
 
1. Arduino に ジョイスティックを取り付ける
Arduino に ジョイスティクを接続します。
配線のための回路図を以下に示します。
				
2. Arduino IDE にスケッチを書く
Arduino IDE に組み込まれているサンプルスケッチを利用します。
Arduino IDE のメニューから
ファイル -> スケッチ例 -> 4.Communicattion -> SerialCallResponse
と選択してください。読み込まれたスケッチには、説明が多く記入され、また、Processing のプログラムコードもコメント欄に書かれているため長いスケッチになっています。
しかし、実際に Arduino に書き込まれるコードだけを取り出すと理解しやすくなります。
重要:ジョイスティックのSWは Arduino 内部でプルアップする必要があります。サンプルスケッチは、Arduino 内部でプルアップされていないため、 setup()関数内のpinMode()関数を INPUT_PULLUP に指定変更します。
				不要部分を削除し、コメントを日本語に翻訳したスケッチを参考のため以下に掲載します。
//   Serial Call and Response in ASCII
int firstSensor = 0;    // N01 アナログ・センサー
int secondSensor = 0;   // N02 アナログ・センサー
int thirdSensor = 0;    // デジタル・センサー
int inByte = 0;         // 受信したシリアルByte
void setup() {
  Serial.begin(9600);  // シリアルポート初期化 9600 bps:
  while (!Serial) {    // シリアアルポートの接続を待つ
    ;
  }
  pinMode(2, INPUT_PULLUP);   // pin 2 プルアップで初期化
  establishContact();         // Byteデータを送り接続の確立を待つ
}
void loop() {
  if (Serial.available() > 0) {     // データ受信したら
    inByte = Serial.read();         // 受信データをから読みする
    firstSensor = analogRead(A0);   // No1センサーの読み込
    secondSensor = analogRead(A1);  // No2センサーの読み込
    // デジタルセンサーは 0 or 255 として取り込む
    thirdSensor = map(digitalRead(2), 0, 1, 0, 255);
    // 取り込んだデータを送信する
    Serial.print(firstSensor);
    Serial.print(",");
    Serial.print(secondSensor);
    Serial.print(",");
    Serial.println(thirdSensor);
  }
}
// シリアアルポートの接続を待つ
// なんらかのデータを受信するまで、何度でも空データを送信し続ける
void establishContact() {
  while (Serial.available() <= 0) {   // 受信しなければ
    Serial.println("0,0,0");          // 空データを送信
    delay(300);                       //   300ms待つ
  }
}
				
3. Arduinoボードにスケッチ書き込む
Arduino IDE にスケッチが読み込まれたら、➡︎ ボタンをクリックして Arduinoマイコンボードにスケッチを書き込みます。
4. Processing IDE にスケッチを書く
Arduino IDE に読み込んだスケッチの後半に、コメントとして Processing IDE 用のスケッチが書かれています。その部分をコピーして Processing IDE にペーストしても構いませんが、以下に該当部分を抜き出して英語のコメントを日本語化したスケッチを示しますので、こちらを利用してください。
//   Serial Call and Response in ASCII
import processing.serial.*;
Serial myPort;                  // シリアルポート
float bgcolor;      // 背景色
float fgcolor;      // 描画色
float xpos, ypos;   // ボールの座標
void setup() {
  //size(640, 480);   // ウインドのサイズ
  size(300, 300);   // ウインドのサイズ (少し小さくしました)
  // 接続しているシリアルポートをリストする
  printArray(Serial.list());
  // このスケッチでは、リストの2番のポートを使用します。
  // ユーザーのArduinoを接続している番号に置き換えてください。
  // 最後のパラメータ(e.g. 9600)は通信速度を示します。
  myPort = new Serial(this, Serial.list()[2], 9600);
  // ラインフィードコード(ASCII 10)を受信するまでバッファに取り込む
  myPort.bufferUntil('\n');
  smooth();                    // 滑らかなエッジで描画する
}
void draw() {
  background(bgcolor);
  fill(fgcolor);
  ellipse(xpos, ypos, 20, 20);  // ボールを描く
}
// setup()関数内でbufferUntil()により設定したコードを
// 受信したときにserialEventが自動実行される
void serialEvent(Serial myPort) {
  // シリアルバッファを読み取る
  String myString = myPort.readStringUntil('\n');
  myString = trim(myString);     // 不要なデータを削除
  // 文字列をコンマで区切り、それぞれを文字列から整数に変換し配列に保存
  int sensors[] = int(split(myString, ','));
  // 値をプリント
  for (int i = 0; i < sensors.length; i++) {
    print("Sensor " + i + ": " + sensors[i] + "\t");
  }
  println();  // 改行する
  if (sensors.length > 1) {
    xpos = map(sensors[0], 0, 1023, 0, width);
    ypos = map(sensors[1], 0, 1023, 0, height);
    fgcolor = sensors[2];
  }
  myPort.write("A");  // 次のデータ要求するために'A' 送信
}
				
5. Processing を実行する
Processing IDE にスケッチを書き込んだら、▶︎ ボタンをクリックして Processingを実行します。
実行されると、Processing IDE のコンソール部に、 Macに接続されているポートの情報が表示されます。
さらに、Mac画面ほぼ中央に、黒のウインドが表示され、接続したジョイスティックを鵜がかすと、白いボールがスティックの動きと同じ動きをします。ジョイスティクを押し込むと白いボールが見えなくなります。
				
[トラブルシュート] 白いボールが表示されない時
動作しない多くの理由が、Arduino 接続ポートの誤指示です。
Processing IDE のコンソール部を確認し、"/dev/cu.usbmodem14xxx" と表示されている番号と、上記スケッチの
port = new Serial(this, Serial.list()[2], 9600);
の list( ) インデックス番号と一致しているか、確認してください。
- 参考
Maに接続されているポートの情報には、/dev/cu と /dev/tty 2種類がが表示されます。歴史的に、tty (TeleTYpe)デバイスは受信、cu (Call Up)デバイスはモデムなどの送信に利用されてきた経緯があるため、2種類のデバイスが用意されています。
なお、どちらのデバイスを使用しても Arduino は正常に動作しました。 
次回は、