バイナリデータの符号拡張と解決(Arduino,C言語)

概要

Arduinoのソフトウェアシリアル入力で受け取った値をシリアルモニタで表示しようとするとFがめっちゃ出るやつの解決法。

起こったこと

BLEレシーバからソフトウェアシリアルで受けたBLEタグIDの一部'0x88'を出力しようと

char data = BLE.read();
Serial.print(data, HEX);

のように記述するとシリアルモニタに FFFFFF88 と表示され、視認性やその後の計算等に支障が出た。

原因

C言語でchar変数をintにキャストするとき、最上位ビットが '1' であると2の補数表現を維持しようと符号拡張を行う。

参考 marycore.jp

解決法

unsigned char変数に代入しておく

unsigned char data = BLE.read();
Serial.print(data, HEX);

てな感じで記述するとよいと思う。

char → int
0x88 → 0xFFFFFF88

unsigned char → int
0x88 → 0x88

IDなど16進数1byteのデータとして評価したい場合などにはこの方法でOK

まとめ

数値として評価したいときには便利なキャストの仕様だが、案外嵌りやすいので、バイナリデータいじってる人は頭の隅に置いてほしい。

単純なキャストの話なんですが、ArduinoIDEを使って開発しててキャストの話と気付かず"Arduino シリアルモニタ F めっちゃ出る"とかで検索してる人に届いて欲しい……