バイナリ通信を使ってみる
人間の指が10本だったので、世界は10進数で溢れている。しかしながらPCの世界は2進数で表現される。彼らはON/OFFしかないのだ。(量子コンピュータは知らないが) だから、2進数を送ってやると都合が良い。
さっと記事を書こう。前回の記事でUDP通信が使えるようになった。これを利用して、soracomにデータを送ることにした。今回は通信プロトコルだけでなく、通信するものごとも変更し、データ利用量を軽減しよう。バイナリデータを送るのだ。幸いなことにsoracomにはバイナリパーサというサービスが提供されている。バイナリデータを送ると、あちらでJSON形式のデータに変換してくれるのだ。
バイナリパーサの設定
soracomのコンソール画面上でいろいろ設定する。soracom air のところでバイナリパーサをONにする。肝心のデータフォーマットは、バイナリパーサplaygroundを使うと、いい感じに決まる。
binary-parser-playground.soracom.io
わたしはこんな風にしてみた。
flag_1:0:bool:7 flag_2:0:bool:6 flag_3:0:bool:5 flag_4:0:bool:4 Num:0:uint:2:1
データ送信プログラム
ATコマンドで送ってみよう。各種設定をして、以下のようにプログラムを作成した。
const char * host = "uni.soracom.io"; const int port = 23080; int send_byte = 1 略 modem.sendAT(GF("+USOCR=17")); delay(1000); modem.sendAT(GF("+USOCO="), 1, ",\"", host, "\",", port); delay(1000); modem.sendAT(GF("+USOST="), 1, ",\"", host, "\",", port, ",", send_byte); delay(1000); modem.stream.print("00001111");
取得したが…!?
やってみたのだが、なんかうまくいかない。データは送信されているが、期待するデータとは違うのだ。以下の表に示す。
送信データ | 期待する受信データ | 実際の受信データ |
-------- | -------- | -------- |
00001111 | xxxx No.3 | xxoo No.0 |
11111111 | oooo No.3 | xxoo No.1 |
00000000 | xxxx No.0 | xxoo No.0 |
01111111 | xooo No.3 | xxoo No.0 |
00111111 | xxoo No.3 | xxoo No.0 |
00001111 | xxxx No.3 | xxoo No.0 |
00001111 | xxxx No.3 | xxoo No.0 |
左の4bitでo x のbool値を返し、右の2bitでナンバーを返すようにしていた。のだが、なんか違う。バイナリパーサplaygroundではうまくいくのにね。
もしかして、16進数?
そこから小一時間悩み続けて、ふっと閃いた。「もしかして、文字列を送っちゃっているのか!?」そう。自分が2進数だと思っていたのは実は文字列の01だったのだ!!文字列の"0"や "1" はアスキーコードで以下のように表現される
"0" -> 00110000 "1" -> 00110001
これで先ほどの表の結果がかちりとわかった。あれは左の1bit目が0だったら「b00110000」を、 1だったら「b00110001」を返していた結果だったのだ。そうか!!
変換しよう
そういうわけで、ATコマンドで送る前に2進数を16進数のアスキーコードに変換して送る必要があることがわかった。コードは以下のようになる。
int bit_state = B000000; a_s = (int)bit_state; key = (char)a_s; modem.stream.print(key);
bit_stateはbitWriteなどを利用して所望のbitにしてしまおう。
そうしてうまくいった。非常によかった。
おわり
soracomのネタ、まだまだ尽きない。日々のインプットに、アウトプットの速度が負けそうだがなんとか頑張って記事を残していこう。
Photo by Meckl Antal on Unsplash