ProcessingからArduinoへint型のデータを送る
これの逆バージョンの話です。
ヘッダに文字を使う方法
データを分割して送信する際に、先頭に「H」という文字を付けて送る方法です。
Processing
- int型のデータを上位バイトと下位バイトに分けて送信する
- データを正しい順序で受信するためにヘッダをつけて送信する
import processing.serial.*; Serial serial; void setup() { // シリアルポートの番号と通信速度は適宜修正してください。 serial = new Serial(this, "COM114", 9600); } void draw() { } // テストとして、画面をクリックした際に1024という数値を送信 void mousePressed() { sendIntData(1024); } // Processingで扱うintは4バイトなのに対し、 // Arduino UnoやLeonardoで扱うintは2バイトなので注意。 // (よって、使う数値は-32768~32767の範囲にとどめておく) // intデータの送信 void sendIntData(int value) { byte high = (byte)((value & 0xFF00) >> 8); byte low = (byte)( value & 0x00FF); serial.write('H'); // ヘッダの送信 serial.write(high); // 上位バイトの送信 serial.write(low); // 下位バイトの送信 } // Arduino側できちんと受信・復元できたかを確認するために // データを文字列として送り返してもらって、それをコンソールに表示。 // (Processingとの通信中にシリアルモニタが使えないので) // データの受信 void serialEvent(Serial port) { if ( port.available() > 0 ) { String data = trim(port.readStringUntil('\n')); if ( data != null ) { println("data =", data); } } }
Arduino
- 3バイト(ヘッダ+int)以上のデータが着ているか確認
- データが着てたらまずヘッダがあるか確認
- ヘッダがあったら、下位バイトと上位バイトを読み取り、その値を合体してint型のデータを復元
void setup() { Serial.begin(9600); } void loop() { if ( Serial.available() >= 3 ) { if ( Serial.read() == 'H' ) { byte high = Serial.read(); byte low = Serial.read(); int recv_data = high * 256 + low; // 受信データ // 受信確認のために、数値を文字列で送り返す Serial.println(recv_data); } } }
ProcessingからArduinoに「1024」という数値をバイナリデータとして送信します。Arduino側では、受信確認のために、受け取ったデータをProcessingに文字データとして送り返します。その結果、Processingのコンソールに「data = 1024」という文字が表示されます。
ヘッダに文字を使わない方法
ヘッダに文字を使っていると、その文字コードが数値の一部とたまにかぶってしまう問題があります。それを気にする場合は以下のような方法を採ります。
この方法を実装したのが以下のプログラムです。デモ内容は先ほどと同様です。
Processing
import processing.serial.*; Serial serial; void setup() { // シリアルポートの番号と通信速度は適宜修正してください。 serial = new Serial(this, "COM114", 9600); } void draw() { } // テストとして、画面をクリックした際に1024という数値を送信 void mousePressed() { sendIntData(1024); } // Processingで扱うintは4バイトなのに対し、 // Arduino UnoやLeonardoで扱うintは2バイトなので注意。 // (よって、使う数値は-32768~32767の範囲にとどめておく) // intデータの送信 void sendIntData(int value) { byte low = (byte)(value & 127); byte high = (byte)((value >> 7) & 127); byte head = (byte)(((value >> 14) & 127) + 128); serial.write(head); serial.write(high); serial.write(low); } // Arduino側できちんと受信・復元できたかを確認するために // データを文字列として送り返してもらって、それをコンソールに表示。 // (Processingとの通信中にシリアルモニタが使えないので) // データの受信 void serialEvent(Serial port) { if ( port.available() > 0 ) { String data = trim(port.readStringUntil('\n')); if ( data != null ) { println("data =", data); } } }
Arduino
void setup() { Serial.begin(9600); } void loop() { if ( Serial.available() >= 3 ) { byte head = Serial.read(); // 1番目のデータ if ( head >= 128 ) { // 128以上であれば先頭データなので、それに続くデータを読み取る byte high = Serial.read(); // 2番目のデータ byte low = Serial.read(); // 3番目のデータ int recv_data = ((head - 128) << 14) + (high << 7) + low; // 受信データ // 受信確認のために、数値を文字列で送り返す Serial.println(recv_data); } } }
以上です。