2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【通信量80%削減!】バイナリパーサー使ってデータ送ってみた!

Last updated at Posted at 2020-10-02

#はじめに
こんにちは、AITOYA株式会社の胡本(えべすもと)です!

お待たせしました!「アルコール消毒状況がひと目で分かるIoTデバイス」シリーズ第3弾です!
今回は「バイナリパーサー」を使用してデータ量を少なくして送信できるようにしてみようと思います。
それでは始めていきましょう!

#目次

#これまでのダイジェスト
これまでの記事では、「アルコール消毒状況がひと目で分かる」デバイスの作成手順や SORACOM Harvest を使ったクラウド管理の手順を記載してきました。気になる方はこちらのリンクからご覧ください。

【第1回】【コロナ対策IoT】アルコール消毒状況がひと目で分かるデバイス作ってみた!
【第2回】【SORACOM×コロナ対策】アルコール消毒状況から店の混雑度合いを可視化してみた

今回はこの続きで、SORACOM 内にある「バイナリパーサー」というものを使用してデータ量を少なくしてみようと思います。

#バイナリパーサーとは
そもそも「バイナリパーサー」はご存じでしょうか?
バイナリパーサーとは、バイナリデータをテキストデータや JSON データなどに変換する変換器の役割を果たすものです。

……え???

だと思います(自分もはじめはそうでした)。
なので、できるだけ簡単に説明していきます!

一般的にデータを送る際は、主に ASCII コードと呼ばれる文字コード表に従ってテキスト形式で送信していたり、またそれを JSON というテキストベースのデータフォーマットに変換して送信しています。
ASCIIコード表

しかし、パソコンはバイナリデータという「0」と「1」の2進数の連続体(いわゆるバイト)でデータを記憶されています。そのため、例えば「20」という数字をテキスト形式で送信する際は、まずパソコン上で ASCII コードを通じて 2(0x32)0(0x30) に分けて変換され、0011001000110000 (0x32と0x30) の2バイトで送信されます。
(ちなみに「0」と「1」ひとつずつがいわゆる「1ビット」と言い、8個で「1バイト」と言います。どちらもメモリー関連でよく聞く言葉です。)

また、さらに「 ” 」(0x22)や「 ; 」(0x59)が文字と文字の間につくことも多く、JSON のフォーマットを維持するバイト容量も必要なため、「20」という数値ひとつ送るにも多くのデータを使用してしまいます。

しかし、「バイナリー送信」という考え方では、最初に記述した通り、データ送信時には「0」と「1」のバイナリデータのままデータを送信し、そしてクラウド上で設定した独自の変換フォーマット(以下「バイナリパーサーフォーマット」と言います)を使用して JSON データやテキストデータに変換する機能です。

例えば、バイナリパーサーフォーマットで「送信データの最初の1バイト(「0」と「1」の羅列8個分)を符号なしの数値(uint)として読み込む。」と決めておけば、先程の例の「20」は「00010100」(0x14)のたった1バイトのバイナリデータを送信するだけで良くなります。そのため送信時にかなりのデータ量を削減することができます。

つまり、概要としては以下の図のようになります。
binaryParser_detail
先程は「20」を例にしましたが、単純な bool 判定で「0をfalse」、「1をtrue」とバイナリパーサーフォーマットで決めておけば、データ送信上は「0」だけ(1ビット)を送るだけでデータの判別もできます。

**この方法によって、ASCII に変換する分や「 ” 」や「 ; 」といった表記を全て省くことができるので、データ量を80~90%!?とかなり圧縮することができます。 さらにデータ量を圧縮できるので通信料金をかなり下げることができます。**お得でしかないです……その他にも、**データを圧縮した分だけ通信時間も減るため、消費電力も削減されます。**お得尽くしです。

このようにデータ量の小さいバイナリデータを上手く変換してくれる便利な変換器が「バイナリパーサー」なのです。

方法自体はビットを使ったデータの記憶であるため理解が難しいですが、理解できるとかなり便利な方法です。
詳しいバイナリパーサーのフォーマット形式は SORACOM の公式ページをご覧ください。
バイナリパーサー詳細 | SORACOM Users

また、実際に実装する際はバイナリパーサーの挙動を気軽に試すサービスも出ているので、こちらも利用してみてください。自分はかなり利用させて頂きました 笑
Binary Parser Playground | SORACOM Developers

#バイナリパーサーのSORACOM側の設定方法
さて、説明が長くなってしまいましたが、バイナリパーサーの設定をしていきましょう!
まずは SORACOM 側の設定です。ユーザーコンソール左上のメニューから「SIMグループ」をクリックし、
SORACOM_group

自分が作成したSIMグループを選択します。
ここでは前回作成した「hand-wash」を選択しました。
(SIMグループを作成してない方は、下記リンクを参考にしてください)
【SORACOM×コロナ対策】アルコール消毒状況から店の混雑度合いを可視化してみた「SORACOM 側の設定」

その後、SIMグループ内の「SORACOM Air for Cellular設定」をクリックし、
SORACOM_Air-for-cellular

バイナリパーサーフォーマットを「ON」に変更後、バイナリデータをどのように変換するかフォーマットを作成し記入します。
binary-parser-format
今回フォーマットは

t_0:0:uint:16 t_1:2:uint:8 t_2:3:uint:8 t_3:4:uint:8 t_4:5:uint:8 t_5:6:uint:8 t_6:7:uint:8 t_7:8:uint:8 t_8:9:uint:8 t_9:10:uint:8 t_10:11:uint:8 t_11:12:uint:8 t_12:13:uint:8

と設定しました。
最初の16ビット(2バイト)を**「1時間の総プッシュ回数」**、その後の8ビット(1バイト)をそれぞれ 「5分間のプッシュ回数」 を記録するように設定しています。これにより送信データ数はたった13バイトなのですが、最初の2バイトで最大65536までの数値を、その後の1バイトで最大256までの数値をそれぞれ読み込むことが出来ます。

最後に「保存」を押せば、SORACOM 側の設定は完了です!

#WioLTE側でのプログラムの構成
WioLTE 側で書くソースコードは、SeeedJP の公式ライブラリに SORACOM Harvest と通信を行うソースコードが記載してあります。今回もこちらのソースコードを使用させて頂きました。
WioLTEforArduino/soracom-harvest.ino at master · SeeedJP/WioLTEforArduino · GitHub
この中のデータ送信のコードを変更していきます。

まず送信するデータを格納する変数を定義します。
今回はコード内45行目の data を書き換え、byte data[13] としました。この変数にビットのデータを格納していきます。
この時使われるのが「ビットシフト」という考え方です。これは文字通りビットを左右に移動させる方法です。
例えば、「00100110」というものを右に1だけシフトすると「00010011」となる。というものです。
詳しくはこちらをご覧ください。
シフト演算子 - 演算子 - C言語 入門

この方法を用いて、配列に順番にビットを詰めていきます。
8ビットごとに詰めていきたいので、右シフト演算子の >> を用いて詰めていきます。

今回のコードでは、1時間の総プッシュ回数を記録する変数を
int HourSprayCount = 0; と定義し、data の各配列に

data[0] = (HourSprayCount >> 8) & 0xFF;
data[1] = HourSprayCount & 0xFF;

としていくことで数値を 16ビットに組み込んでいきます。
その後5分ごとの総プッシュ回数は int MiniteSprayCount = 0;
と定義し、data の各配列に

data[2] = MiniteSprayCount & 0xFF;

……と記述していくことでビットの配列で格納することができます。
最後に、13バイト分送ることを設定するため、80行目の

Wio.SocketSend(connectId, data)

を変更し、

Wio.SocketSend(connectId, data, 13)

と記述して WioLTE 経由でデータ送信を行います。
これで WioLTE 側の設定が完了しました!

#実際の送信結果
さて、設定が終わったので、実際にデバイスを動かしてみましょう!
shiratoriMove
動かしたことで送信された WioLTE 側のデータはこちら!
result_WioLTE
今回はテストなので、総プッシュ回数は356回、5分ごとのプッシュ回数は22回に固定して送信しています。

シリアルモニター上では、1時間の総プッシュ回数は356回ですが、格納されたデータは、
data[0] (16進数表示) : 0x01
data[1] (16進数表示) : 0x64
と表示されています。

ただこれは間違いではありません。データは8ビットずつ送っています。

これは8バイト = 2の8乗 = 256 なので、上位1バイトを格納している data[0] とは
data[0] = 256 × 0x01 = 256 × 1 = 256
となり、下位8バイトを格納している data[1]
data[1] = 0x64 = 100
となります。なので、
data[0] + data[1] = 256 + 100 = 356
となり値としては合っています。

さて、これを SORACOM Harvest 上で確認した結果がこちら!
result_SORACOM-Harvest
この結果から、バイナリパーサーを使用してデータ量を削減して送信できました!

また1時間の総プッシュ回数は送信時は
data[0] = 0x01、data[1] = 0x64
ですが、バイナリパーサーフォーマットでは先頭「16ビット」を読み取るように設定してあるので、無事「356」と読み取ることができました。

#バイナリパーサーを使用したデータ削減量
さて、今回のバイナリパーサーを使用すると、どれくらいデータ量削減できるのでしょうか?
ここで作ったデバイスでは正確な削減量は計測していませんが、
【新発表】SORACOM Air に省電力LPWAセルラー通信「LTE-M」が追加、合わせて2種のデバイスや新機能をリリース - SORACOM公式ブログ では、
「出力された JSON はスペースなどを削除して約 60 バイトになります。一方入力側のデータは 9 バイトです。この例では、おおよそ 85% のデータサイズ削減に成功しています。」と記載してあったり、

SORACOM Beamによる通信量の削減効果を金額と電力量の数値で示す - Qiita では、「バイナリパーサーを使用することで98.1%のデータ量削減が行えた。」という記載があり、送信方法や送信データ内容にもよりますが、80%以上のデータ量削減が行えているようです。
これはすごい 笑

#終わりに
ここまで読んでいただきありがとうございました!
バイナリパーサーの実装が完了したことで、高頻度で定期的に通信をしてもあまり通信量のかからない、より実用的なデバイスに仕上がった気がします 笑

元々情報系ではない(機械系出身の)自分が、2進数やメモリの概念をゴリゴリ使うバイナリパーサーを理解するのは苦戦しましたが、使えるようになると、メモリの概念も理解でき、知識を深めながら実装できるとても良い機会になりました!
難しいですが、皆さんも是非一度挑戦してみるのはいかがでしょうか?

当社は、cm級位置情報測位デバイスの「iChidori®(いちどり)」シリーズを始めとした、位置情報ソリューションをお客様に提供している企業です。 製品の説明はこちら をご覧ください!
よい、いちどりを。

本記事は、AITOYA株式会社HPに掲載している内容と同一のものです。→AITOYA株式会社HP

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?