工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

SORACOMのIoT SIM plan-D D-300MBとLTE-M Shield for Arduinoを使ってみる(2) --- ESP-WROOM-32との組み合わせ ---

概要

LTE-M Shield for ArduinoをESP-WROOM-32と組み合わせ、動作を確認した。画像の送信がどうにか行えそうな見通しが立った。

  • 2021/09/18追記
    • BG96へ一度に書き込むデータ量
    • BG96とのボーレート変更



背景と目的

前回、SORACOMのIoT SIM plan-D D-300MBとLTE-M Shield for Arduinoを使って、データを送信することができた。今回は、ESP-WROOM-32(以下、ESP32)と組み合わせて、大きいサイズのデータを送れるか動作を確認する。



詳細

0. やりたいこと

  • LTE-M Shield for Arduinoとの間のシリアルのボーレートを115200bpsまで上げられるかを確認する
  • 画像ファイル等を想定した数100kB程度のデータが送信できるか確認する


1. 配線

ピンク字が接続先ESP32側端子の名前。基本的に電源とリセット端子とシリアル用GPIOだけ。GPIO16,17は、後述のHardwareSerialで使用する。

dragino/NB-IoT回路図より抜粋


2. LTE-M Shield for Arduinoとの間のシリアルのボーレートをどのくらいまで上げられるか

前回、ArduinoUNOとの組み合わせでは57600bpsまで(SoftwareSerial使用)しか使えなかった。なので、ESP32と組み合わせてどのくらいまで使えるか試したところ、

HardwareSerialを使うことで、230400bpsで通信可能 (2021/09/18更新)

ということが分かった。関連するソースコードだけ抜き出せば、

#define BAUDRATE 230400 // 2021/09/18更新
#include <HardwareSerial.h>

// オブジェクト作成
HardwareSerial LTE_M_shieldUART(2);

// シリアルポートを渡す
TinyGsm modem(LTE_M_shieldUART);

となる。ちなみに、SoftwareSerialでは、うまくいかなかった。低速なら動くかもしれないが。

また、230400bps以外に460800、921600を試してみたところ、うまく書き込めないのだが、ボーレート設定に対するレスポンスではOKが返ってきているので、もしかするとハードウェア周りを注意して実装すれば通信可能かもしれない。(今は実験のため、ブレッドボードや10cm弱の配線を使ってやっている。)


3. 画像ファイル等を想定した数100kB程度のデータが送信できるか確認する

LTE-M Shield for Arduinoを使ってやりたいこととして、カメラで撮影した画像の送信を考えている。以前作成した成長記録用カメラでは、1枚あたり200-300kBの画像となるのでこのくらいのサイズのデータを送信できるか試しておきたい。

今回は、カメラを動かす環境がないので、疑似画像データとして300kB程度の適当なjpgファイルのデータをソースコードに埋め込んで、それを読み取って送信してみることにした。条件は以下。

  • 送信先: SORACOM Beamエンドポイント
  • SORACOM Beamからの転送先: AWS

3.1 結果まとめ

  1. ESP32からLTE-M Shield for Arduinoへシリアルで送る際、1度に送信できるサイズは1460byte(2021/09/18更新)が限界らしい
  2. それ以上のデータを送りたい場合は、Serial.writeとSerial.flushを組み合わせて分割して書き込むとうまくいく(実はこのときも同じ問題にぶつかったためそのノウハウを活用)。しかし、細切れで渡すことで、ESP32からLTE-M Shield for Arduinoの実質の通信速度がだいたい10kB/s弱となった。(2021/09/18更新)
  3. レスポンスステータスコードが400になるが、SORACOM Beamからの転送先のAWSではちゃんとデータが受け取れている

3.2 分割して書き込む

今回画像データを送信するためBody部分が数100kBと大きい。(payloadという変数に入っている)したがって、以下のようにBody部分を1460byte(2021/09/18更新)に細切れにして送信している。

  /* connect */
  // 8888はSORACOM Beamエンドポイントの都合
  if (!ctx.connect(ENDPOINT, 8888)) {
    CONSOLE.println(F("failed."));
    delay(3000);
    return;
  }

  size_t contentLength = strlen(payload);
  CONSOLE.println(contentLength);
  
  /* send request */
  char hdr_buf[511];
  ctx.println(F("POST / HTTP/1.1"));
  sprintf_P(hdr_buf, PSTR("Host: %s"), ENDPOINT);
  ctx.println(hdr_buf);
  ctx.println("Connection: Close");
  ctx.println(F("Content-Type: application/json"));
  sprintf_P(hdr_buf, PSTR("Content-Length: %d"), contentLength);
  ctx.println(hdr_buf);
  ctx.println();
  // ボディ
  // 一度に大きなデータをprintlnするとうまくいかない
  // mバイトに分割してwriteする
  int m = 1460; // 1460byteが限界(2021/09/18更新)
  int i, j = 0;
  uint8_t * p = (uint8_t *) malloc(m);
  while (true) {
    for (i = 0; i < m; i++) {
      p[i] = payload[i + j * m];
      if (i + j * m == contentLength - 1) break;
    }
    ctx.write(p, m);
    ctx.flush();
    // CONSOLE.printf("j=%d, length=%d\n", j, i); // 確認用
    if (i + j * m == contentLength - 1) break;
    j++;
  }
  // 空行を最後に
  ctx.println(); // 2つprintlnがないとだめ 
  ctx.println(); 

3.3 一度に書き込めない理由

推測だが、LTE-M Shield for Arduinoの受信バッファのサイズではないかと考える。

https://auroraevernet.ru/upload/iblock/538/538e779e251d00d8aa99ebad4c479d5c.pdf

これかも。AT+QISENDコマンドで、1460byteまでしか一度に送信できなそう?

2021/09/18 その通りだった。

3.4 レスポンスステータスコードが400

AWS側では正しく処理されているので、SORACOM Beamエンドポイントとして400を返しているように見える。送信できてしまったので、今回はとりあえずいいとして、いずれは解決したい。



まとめと今後の課題

LTE-M Shield for ArduinoとESP32を組み合わせて、シリアルの速度、大きなサイズのデータ送信を確認できた。通信速度が遅いことが課題としてあるので、今後解決できないか継続的に取り組む必要がある。ひとまず、通信速度は満足できるレベルではないが、一応どうにか画像の送信が実用になりそうなので、OKとする。(2021/09/18更新)


SORACOMのIoT SIM plan-D D-300MBとLTE-M Shield for Arduinoを使ってみる(1) --- 手始めにArduino UNOと組み合わせて動かす ---

概要

SORACOMのIoT SIM plan-D D-300MBとLTE-M Shield for Arduinoを使い、通信できることを確認した。



背景と目的

ここ最近作成に取り組んできた家庭菜園系アイテムである自動水やり器観察用カメラは、自宅ベランダで動かしているのだが、今後は畑やビニールハウスといった場所でも稼働させたい。そこで、価格と容量のバランスに優れたLTE通信の選択肢を検討していたところ、今年SORACOMから出た300MB/月までは330円(SMSなし)という低価格の通信プランである IoT SIM plan-D D-300MB に魅力を感じた。 というわけで、実際に使って試してみる。



詳細

0. 目標

  • モジュールをマイコン等と接続し、画像データ(300kB程度)をクラウドに送信できるようにする
  • スリープ等、使用しないときに消費電力を抑える手段を知っておく


0. 環境

お試しなので、Arduino UNOを使ってLTE-M Shield for Arduinoとやりとりし、データがLTEで飛ばせればOK。


1. 調達

自作のシステム組み込みを想定し、以下を調達することにした。SIMカードと通信モジュールの開発ボードだ。費用は7000円程度の初期投資と、月々の通信料330円を足してもまあ小遣いで十分遊べる範囲だ。

  • SORACOM IoT SIM plan-D D-300MB データ通信のみ
  • LTE-M Shield for Arduino(LTEモジュール基板部分を以降BG96と呼ぶ)

soracom.jphttps://soracom.jp/services/air/cellular/price_specific_area_sim/#D-300MB

soracom.jp


2. デバイス稼働時間を SORACOM Harvest へ送信する

https://users.soracom.io/ja-jp/guides/starter-kits/arduino/harvest/

上記に従って、とりあえず送信できるか試す。

2.1 USBドライバーのインストール

https://users.soracom.io/ja-jp/guides/starter-kits/arduino/development-environment/

上記に従い、PCに、CP210x Universal Windows Driverをダウンロードし、zipを解凍してインストーラを叩く。


2.2 ハードウェア接続

以下のように、Arduino UNOに接続した。SIMカードも挿してある。USBケーブルはPCへ。

2.3 ネットワーク設定の書き込み

ボーレートと改行コードに注意。

※注意 安易にコピペすると、行末に思わぬ改行コードが付加されていることに気づかずエラーになるため、手入力するのが無難。

AT+CGDCONT=1,"IP","soracom.io","0.0.0.0",0,0,0,0
AT+QCFG="nwscanmode",0,0
AT+QCFG="iotopmode",0,0
AT+QCFG="nwscanseq",00,1

2.4 SORACOMコンソール上でセットアップ

SIMは、コンソールで受け取り完了通知をした時点で登録されているので、使用開始した。 参考URLの通りなので、SORACOM harvestのセットアップを行った。ちなみに、SORACOM harvestの利用料金は1日5.5円だが、SIM 1枚は無料使用枠で賄えるようなので、とりあえず今回はお金はかからない。

2.5 TinyGSM ライブラリのインストールとスケッチの書き込み

参考URLに従い、TinyGSM ライブラリをダウンロードし、Arduino IDEでzip形式のライブラリとしてインクルード。 send_uptime_with_soracom.inoを書き込んだ。

2.6 データの確認

シリアルコンソールを開き、ボーレートを115200bpsに変更して、しばらく待っていると以下の通り、送信された。

SORACOMコンソールで確認した結果。ちゃんとデータが受信されている。


3. ボーレートの変更

Arduino UNOとBG96の間は9600bpsのシリアル通信でATコマンドのやりとりしていて、LTE区間での速度はさすがにもっと出せるはずなので、このままだとこの部分がボトルネックになってしまいそうだ。そこで、ボーレートを上げてみる。

情報を漁ってみたところ、

https://github.com/vshymanskyy/TinyGSM#baud-rates

に記載があり、

https://github.com/vshymanskyy/TinyGSM/blob/a57014d0e6ef5a5431a68ec444c2aabfbd89defb/src/TinyGsmCommon.h

などを参考に、send_uptime_with_soracom.inoを変更した。

  #define BAUDRATE 57600 // 適宜変更

  :

  // まずArduino UNO側ソフトウェアシリアルを9600bpsで有効化
  LTE_M_shieldUART.begin(9600);

  // BG96をリセット
  CONSOLE.print(F("modem.restart()"));
  modem.restart();
  CONSOLE.println(F(" done."));

  // ATコマンドでボーレートを変える
  LTE_M_shieldUART.print("AT+IPR=" + String(BAUDRATE) + "\r\n");

  // レスポンス
  // 正しく変更されればOKのレスポンスがある
  String input = LTE_M_shieldUART.readString();
  CONSOLE.print(F("modem setBaud: "));
  CONSOLE.println(input);

  // BG96が変更できたら改めてArduino UNO側ソフトウェアシリアルを変更
  LTE_M_shieldUART.begin(BAUDRATE);

  // 調整用、入れた方がいいかも
  delay(1000);

  // 以降、ATコマンドで通信
  :

いろいろ試したころ、57600bpsが最高だった。115200bpsでもOKのレスポンスはあるがそれ以降の通信がうまくいかなかった。 念のためMAIN_TX,MAIN_RX端子の波形を観察し、実際に変更されているか確認したところ、確かに変更されていた。115200bpsはSoftwareSerialにジッタや割り込み処理遅延などがあるせいか?原因はよくわからなかった。もしかしたら、ESP32などを使えばもっと115200まで行けるかも?後で試してみたい。

とはいえ、とりあえずデフォルトの6倍までは上げられたのでひとまず良しとする。



まとめと今後の課題


しそを育てる(3) --- 成長の様子を動画にまとめる ---

概要

しそを種まきしてから約2か月間の成長記録をまとめた。



背景と目的

しその種まきを行ってから約2か月が経った。その間、自作の成長記録用カメラで撮影した画像がたまったので、ここまでの成長の様子をまとめておく。



詳細

毎日1回撮影した画像をつなげて動画にしてみた。

※前半はスマホで手動撮影、7/5からは自作の成長記録用カメラ


www.youtube.com

所感

  • 毎日、着実に成長して7月中旬に初収穫できた。香りはまあまあ悪くない。それ以降、ちょっとずつ収穫して麺類の薬味に使えているので、食えるものを育てるという目標はクリア。
  • ときどき、葉が黒くなって枯れていくものもあるようだが、全体としてはちゃんと成長しているので問題なさそう。
  • カメラがあると、成長スピードを感覚的にではなく客観的な記録として残せるので非常によい。今後、他の物を育てるときもどんどん活用したい。



まとめと今後の課題

目標とした、食べられる状態のものを育てることができた。次はしそ以外のものにチャレンジしたい。