Arduinoのシリアル通信では1Byte(8bit)単位で通信が行われます。そのためバイナリ形式で1Byte(0-255)を超える数値をArduinoへ送るためには工夫が必要となります。
以下はArduinoで2Byte(16bit)の数値をシリアル通信で受信して認識した数値を文字列として送信元へ送り返すコードです。
uint8_t buf[2];
void setup() {
Serial.begin(9600);
}
void loop() {
if (!Serial.available()) return;
Serial.readBytes(buf, 2);
uint16_t value16bit = buf[1] << 8 | buf[0];
Serial.println(String(value16bit, DEC));
}
確認方法
PCからArduinoへ2Byteのデータを送ります。今回はCoolTermを使用しました。2Byteのバイナリデータを送信できれば何でも構いません。以下はCoolTerm上での操作を解説します。
まずCoolTermを起動させたらOptionボタンを押して対象のシリアルポートを選択し、ボーレートを9600bpsに設定して[OK]ボタンを押します。その後、Connectボタンを押してシリアルポートに接続します。
次にツールバーメニューの「connection」から「Send String」を選択します。
データを送信するためのウィンドウが表示されるので、Hexにチェックを入れて数値の1023(0x03FF)となる「FF 03」を入力して[Send]ボタンを押します。FFと03の間にはスペースを入れてください。
正常に動作していれば受信ウィンドウに1023と表示されます。
コード解説
PCから0xFF, 0x03のデータを送信してArduinoで受信するとuint8_tの型で宣言したbufにはSerial.readBytes(buf, 2);
の行で以下のようにデータが格納されます。
分かりやすいように、16進数から2進数で表してみます。
uint16_t value16bit = buf[1] << 8 | buf[0];
ではbuf[1](0x03)を左に8bitシフトし、buf[0](0xFF)との論理和をとって16bit幅の型をもつvalue16bitに値を格納しています。
これで1Byteの範囲(255)までしか送れなかったデータを2Byte(65535)まで拡張できるようになりました。この手法を応用すると24bit、32bitなどさらに大きな数値を送ることが可能になります。
最近はESP8266やESP32など32bit幅のCPUを搭載するマイコンが増えてきました。シリアル通信でこれらのマイコンと通信するときは大きな数値を扱うことが多くなってきますので、ぜひこの手法を活用してみてください。