LoginSignup
5
4

More than 3 years have passed since last update.

soracomバイナリパーサーを使ってLTE-M Shield for Arduinoのデータ通信量を削減する

Last updated at Posted at 2021-02-26

Quectel 社製 LTE-MモジュールBG96 が搭載されているIoT スターターキット for Arduinoの公式サンプルスケッチを例にデータ利用量を大幅に削減する方法を紹介します。

まず公式soracom-labのリポジトリからsend_multiple_sensor_data_with_soracom.inoを使ってみます。
セットアップページに従って送信を開始するとsoracom Harvest Dataのページでこのようにデータが流れてきているのがわかります。
スクリーンショット 2021-02-26 195538.png

このスケッチではHTTP POSTメソッドでJSON形式のデータを送信しています。

send_multiple_sensor_data_with_soracom.ino
(163行目)
 char payload[90];
  sprintf_P(payload, PSTR("{\"light\":%d,\"sound\":%d,\"temp_c\":%s,\"humi\":%d,\"air_pressure_hpa\":%s}"),
    light_mapped_value, sound_mapped_value, temp_buf, humi, hPa_buf);
  /* example:
   *  {"light":48,"sound":60,"temp_c": 25.0,"humi":34,"air_pressure_hpa":1015.5}
   */
  CONSOLE.println(payload);

  CONSOLE.print(F("Send..."));
  drawText_P(&u8x8, PSTR("Send..."));
  /* connect */
  if (!ctx.connect(ENDPOINT, 80)) {
    CONSOLE.println(F("failed."));
    drawText_P(&u8x8, PSTR("failed."));
    delay(3000);
    return;
  }
  /* send request */
  char hdr_buf[40];
  ctx.println(F("POST / HTTP/1.1"));
  sprintf_P(hdr_buf, PSTR("Host: %s"), ENDPOINT);
  ctx.println(hdr_buf);
  ctx.println(F("Content-Type: application/json"));
  sprintf_P(hdr_buf, PSTR("Content-Length: %d"), strlen(payload));
  ctx.println(hdr_buf);
  ctx.println();
  ctx.println(payload);
  /* receive response */
  // NOTE: response header and body are ignore due to saving for memory
  ctx.stop();
  CONSOLE.println(F("done."));
  u8x8.clearLine(6);

この部分を以下のように変更します
1. int型(float型)の数値を%04X(%08lX)フォーマット指定子をつかって16進数に置き換え

2. ATコマンドの+QISENDEXを使って送信
https://www.quectel.com/product/bg96.htm
にある Quectel_BG96_TCP(IP)_AT_Commands_Manual_V1.1.pdf を参照

2.1.9. AT+QISENDEX Send Hex String
This command cannot be applied for "UDP SERVICE" and "TCP LISTENER" sockets.
Write Command
AT+QISENDEX=<connectID>,<hex_string>
Parameter
<connectID> Integer type. The socket service index. The range is 0-11.
<hex_string> String type. Hex string. The max length is 512 bytes.

3. 送信先をHTTP 80番ポートからTCP 23080番ポートに変更
https://dev.soracom.io/jp/unified_endpoint/how-it-works/

HEX_send_multiple_sensor_data_with_soracom.ino

  char cmd[64]={"0"};
  sprintf_P(cmd, PSTR("+QISENDEX=0,\"%04X%04X%08lX%04X%08lX\""),
       light_mapped_value, sound_mapped_value, temp, humi, hPa);
  /* binary-parser format:
   *  light:0:int:16 sound:2:int:16 temp_c:4:float:32 humi:8:int:16 air_pressure_hpa:10:float:32
   */
  CONSOLE.println(cmd);
  CONSOLE.print(F("Send..."));
  drawText_P(&u8x8, PSTR("Send..."));
  /* connect */
  if (!ctx.connect(ENDPOINT, 23080)) {
    CONSOLE.println(F("failed."));
    drawText_P(&u8x8, PSTR("failed."));
    delay(3000);
    return;
  }
  /*send AT command */
  modem.sendAT(cmd);
  /* receive response */
  // NOTE: response header and body are ignore due to saving for memory
  ctx.stop();
  CONSOLE.println(F("done."));
  u8x8.clearLine(6);

次に ユーザーコンソール > SIM グループ > SORACOM Air for Cellular 設定 > バイナリーパーサーフォーマット に以下のように入力します

light:0:int:16 sound:2:int:16 temp_c:4:float:32 humi:8:int:16 air_pressure_hpa:10:float:32

スクリーンショット 2021-02-26 201201.png
バイナリパーサーカスタムフォーマットについてはhttps://dev.soracom.io/jp/docs/binary_parser/ を参照

再びHarvest Dataで見てみると"binaryParserEnabled":true となっています。
スクリーンショット 2021-02-26 201709.png

データ使用量を比べて見ると1時間あたり420KiB から50KiB程まで削減できました。
無題の図形描画.png

さらに、例えばDHT11の温度は整数で(-127~127)で表せるので
16bitのint型でなくchar(int8_t)にすれば1byteに、

気圧はhPaの小数第2位(Pa)で800.00~1200.00ぐらい表せればいいので
(int)(hPa*100-100000)で送ってバイナリーパーサーoperationsで:+100000/100 
として元の数値に戻せば2byteに削減できます。

またbyte単位でなくbit単位でもカスタムできます。

5
4
1

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
5
4