Arduinoのシリアル通信でint型のデータをやりとりする
Arduinoのシリアル通信のメモです。1回のSerial.write()で送れるデータは1バイト、すなわち数値として表現できる範囲は0〜255です。int型ならもっと広い範囲の数値(-32768〜32767)を扱えるわけですが、intは2バイトなのでこれを送受信するにはちょっと工夫が必要です。
要点
送信側では、
- int型のデータを上位バイトと下位バイトに分けて送信する
- データを正しい順序で受信するためにヘッダをつけて送信する
受信側では、
- 3バイト(ヘッダ+int)以上のデータが着ているか確認
- データが着てたらまずヘッダがあるか確認
- ヘッダがあったら、下位バイトと上位バイトを読み取り、その値を合体してint型のデータを復元
Arduino同士の通信
例として、2個のArduino間のデータの送受信を考えます。配線はこんな感じです。
GNDとGND、VinとVin(または5Vと5V)をつなぎます。これで片方のArduinoからもう片方のArduinoに向かって電力供給されます。通信線は送信側のTxが受信側のRxにつながるようにします。なお、通信線の配線はArduinoにプログラムを書き込んでから行ってください(書き込み時に干渉が起こるからです)。
プログラム例を以下に示します。きちんとint型のデータが送受信できているかを確かめるために、Arduino1から「12345」と「-12345」の2種類のデータを交互に送り、受け側のArduino2でどちらのデータがきたかチェックして13番ピンに繋がっているLEDをON/OFFします。500ms間隔でLEDが点滅すればOKです。
送信側プログラム(Arduino1)
void setup() { Serial.begin(9600); } void loop() { sendIntData(12345); // int型データの送信 delay(500); sendIntData(-12345); // int型データの送信 delay(500); } // int型のデータを送信する関数 void sendIntData(int value) { Serial.write('H'); // ヘッダの送信 Serial.write(lowByte(value)); // 下位バイトの送信 Serial.write(highByte(value)); // 上位バイトの送信 }
受信側プログラム(Arduino2)
int recv_data; // 受信データ void setup() { Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { // 受信バッファに3バイト(ヘッダ+int)以上のデータが着ているか確認 if ( Serial.available() >= sizeof('H') + sizeof(int) ) { // ヘッダの確認 if ( Serial.read() == 'H' ) { int low = Serial.read(); // 下位バイトの読み取り int high = Serial.read(); // 上位バイトの読み取り recv_data = makeWord(high,low); // 上位バイトと下位バイトを合体させてint型データを復元 } } // 受信したデータに基づいてLEDをON/OFF if ( recv_data == 12345 ) { digitalWrite(13, HIGH); } if ( recv_data == -12345 ) { digitalWrite(13, LOW); } }
参考文献
Arduinoならいい感じの関数がありそうな気がしますが、本にこのテクの記載があるくらいなので、ないのかな。
- 作者: Michael Margolis
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2011/03/29
- メディア: ペーパーバック
- クリック: 19回
- この商品を含むブログを見る