マトリョーシカ的日常

ワクワクばらまく明日のブログ。

M5Stack 3GモジュールでUDP通信 〜ATを呼ぶもの〜

 m5stack + 3Gモジュール、とても良い。マイコン一つでデータをクラウドへ送信できるので非常に便利。でもさ、ちょっと通信量多すぎないか?


 12月は100回程度通信した時点ですでに500kiBほど使用していた。(写真は最近のデータも含む) 1回の送信で5KiB!? 多すぎ!!これはどういうことか。サポートへ問い合わせてみた。

当社では通信の秘密よりお客様の通信内容は確認できないのですが、500 KiB であれば極端に多いとは言えないかと存じます。(一部抜粋)


 毎度のことながら返答が早い。ありがとうございます。

 やはり通信プロトコルの影響が大きいのかもしれない。利用しているのはHTTPというもの。これはよくわかんないけど、送信するデータが多くなってしまうらしい。

 対してUDPというものがある。これはデータを送信しっぱなしなので、応答の確認はしないので信頼性は低い。しかし送るデータが軽量なので通信量が低く抑えられる。なるほど。追跡機能がついた宅急便か、ゆうメールかの違いというところか。

 あれ、でも今使っているTinyGSm はUDPには対応していないぞ。

 お問い合わせいただきありがとうございます。


 M5Stack 用 3G 拡張ボードが搭載する通信モジュール u-blox 社 SARA-U201 は UDP 通信に対応しておりますので、直接 AT コマンドを実行いただければ UDP もご利用いただけます。(おそらくご利用になっていると拝察する TinyGSM が UDP に対応しておりません。)


 詳細は AT コマンドのマニュアルをご参照くださいませ。具体的な実装方法などは当窓口からはご案内できませんが TinyGSM ライブラリの sendAT 関数を利用すると AT コマンドを実行いただけるようですのでご検討いただければと存じます。

u-blox cellular modules AT commands manual

https://www.u-blox.com/en/docs/UBX-13002752


ないならつくればいいじゃない!!

 そこでATコマンドの出番である。これはむかーしのモデムにも使われていた命令であり、送信などができる。じつは3Gモジュールの中に入っている sala u-bloxはこのATコマンドが実行できる。
 tinyGsmのコードをgithubから眺めるとそれらしいところがいくつかあった。

GitHub - vshymanskyy/TinyGSM: A small Arduino library for GSM modules, that just works

いでよATコマンド

プロトタイプ向けマイコンモジュール M5Stack と 3G 拡張ボードをセットアップする | Getting Started | SORACOM Users
まずはこのコードを実行する。m5stack 3gモジュールからsoracomハーベストへデータを送信する。10秒おきに。結構頻度が多いね。

ここでシリアルポートをのぞいてみよう。
....

ちょっとよくわからない。


というわけで、まずはATコマンドを見てみよう。いいのがあった。



C:\Users\ユーザ名\Documents\Arduino\libraries\TinyGSM\src\TinyGsmCommon.h

ここに入っているヘッダファイルを修正するらしい。

    void sendAT(Args... cmd) { \
    streamWrite("AT", cmd..., GSM_NL); \
    stream.flush(); \
    TINY_GSM_YIELD(); \
    /* DBG("### AT:", cmd...); */ \
  } \

 このコメントになっているのを表に出すらしい。

うわ、なんか出てきた!!! なんだこいつは。

貼り付けながら見てみよう

[751] ### AT: 
(中略)
[4044] ### AT: +CFUN=16
[7404] ### TinyGSM Version: 0.7.9
[7404] ### AT: 
(中略)
[9800] ### AT: E0
[9804] ### AT: +CMEE=2
[9811] ### AT: +CGMI
[9816] ### AT: +GMM
[9821] ### Modem: u-blox SARA-U201
[9822] ### AT: +CPIN?
[10829] ### AT: +CPIN?
[10836] ### AT: I
[15854] ### AT: +CGREG?
(中略)
[18405] ### AT: +CGREG?
[18413] ### AT: +UPSDA=0,4
[18422] ### AT: +CGATT=1
[18428] ### AT: +UPSD=0,1," soracom.io "
[18434] ### AT: +UPSD=0,2," sora "
[18439] ### AT: +UPSD=0,3," sora "
[18445] ### AT: +UPSD=0,7,"0.0.0.0"
[18449] ### AT: +UPSDA=0,3
[52031] ### AT: +UPSND=0,8
[52038] ### AT: +CGREG?
[52044] ### AT: +UPSND=0,0
[54088] ### AT: +USOCTL= 0 ,10
[54095] ### AT: +USOCR=6
[54101] ### AT: +USOSO= 0 ,6,1,1
[54106] ### AT: +USOCO= 0 ," beam.soracom.io ", 8888
connected.

なるほど。どうやら、

[起動後の時間] AT  

という流れらしい。

これとu-bloxのatコマンド一覧を眺めてみよう。

https://www.u-blox.com/sites/default/files/u-blox-CEL_ATCommands_%28UBX-13002752%29.pdf
呪文か。


以下のブログで紹介されているやりかたで、ATコマンドを打ちながら試していこう。
デバッグモードを使いながらやっていく

ATコマンドの紹介

AT: +CFUN=16

> Selects the level of functionality fun in the MT.
p45

なるほど。わからん。なにかのスイッチをリセットしているらしい。

AT: E0

全くの不明。

AT: +CGMI
AT: +GMM

製造社とモデルを表示してくれる。 p35

AT: +CMEE=2

これはエラーモードの設定。

 AT: +CPIN?
 AT: +CGREG?
 AT: I

 SIMにデバイスの保護がなされているかを確認。CGREGはGPRSネットワークの確認らしい。AT Iは製品情報が表示される。

よしよし。

AT: +UPSDA=0,4

指定されたPSDアクションを返すらしい。なんとことかわからない。

AT: +CGATT=1

GPRSへの接続をON-OFFしている。

AT: +UPSD=0,1," soracom.io "
AT: +UPSD=0,2," sora "
AT: +UPSD=0,3," sora "
AT: +UPSD=0,7,"0.0.0.0"

 パケットスイッチをなんか切り替えるらしい。パケット通信のなにかを設定しているのかな。

AT: +UPSDA=0,3

 パケットスイッチに関するアクションをしかけている。なんぞ。

AT: +UPSND=0,8
AT: +UPSND=0,0

 パケットスイッチに関する何かを確認している模様。

AT: +USOCTL= 0 ,10

通信を許可している。10はTCP通信の許可らしい。

AT: +USOCR=6

ソケットを作っている。6はTCP通信のソケット。

AT: +USOSO= 0 ,6,1,1

ソケットのオプションを設定している。

AT: +USOCO= 0 ," beam.soracom.io ", 8888

ソケットへ接続している。


UDP通信をするにはどうすればいいか

 というわけで、上のコマンドを行った後にpayloadをpostしてやればHTTPはできる。では、UDPはどうすればできるか。以下の通りだ。

AT +USOCR=17

AT +USOCO=1,"uni.soracom.io",23080

AT +USOST = 1,"uni.soracom.io",23080,1,"1"

UDPソケットをつくり、ポートを指定。そうしてバイトを送信する!!
こんなかんじ。そして、TinyGSMを使用しているなら、harvestへ送信したプログラムに以下のコードを追記すればATコマンドが送信できる。

modem.sendAT(GF("+USOCR=17"));
  delay(1000);
  modem.sendAT(GF("+USOCO="), 1, ",\"", host, "\",", port);
  delay(1000);
  modem.sendAT(GF("+USOST="), 1, ",\"", host, "\",", port, ",", 1);
  delay(1000);
  
  modem.stream.print("0");

やったね!


通信量の比較

 かなり下がった! 2月は800回ほどデータ送信をしたが、全体の通信量は130KiBくらい。一回あたり160Biくらいか。前の5KiBに比べたら約1/30になった。うれしいなぁ。

次回予告

 さて、なんとかUDP通信はできたのだが、バイナリの様子がどうもおかしい。バイナリパーサーを通じて観測すると、0だと思って送信したものが0じゃなかったのだ。

次回、「疑惑のバイナリ〜アスキーコードの行方〜」

お楽しみに!!



Photo by eberhard grossgasteiger on Unsplash