M5StackCore2でSim通信を行うには、どのようにすれば通信ができるのか、正直このsim通信の初期設定を行うのにとてつもなく時間と労力を費やしたので、一つの知見として記事にしておこうかと思います。
アーキテクト
以下に通信を行うためのアーキテクトを図示します。
M5StackCore2でSim通信用のModuleを取り付ける
M5stackCore2そのものには、SIM通信を行うモジュールは、存在していないため、外部から取り付ける必要があります。sim通信用に、Soracomが販売してる3G拡張ボードがありますが、これは、M5stackCore2には対応していません。
下記の、M5Stack用 SIM7080G搭載 CAT-M/NB-IoT+GNSSユニット(アンテナつき)
を使用する必要があります。
これを使用するとき、さらに、買うとついてくるアンテナをつけて行うことをお勧めします。理由は電波強度の問題で、私はつけないでテストした所全く通信できず何度もやり直したり大変でした。
充電状態についてはいかに記述されています。
使用するSimカードについて
まず、通常のSimカードでは通信ができません。Iot通信が可能なsimカードを購入する必要があります。正確には、LTE Cat.M1
という通信ができるSimカードでないと通信ができません。
私は、Soracom
をお勧めします。実際に購入したのは、以下のSimカードです。
Soracomをお勧めする理由として、仮にsim通信を行った時に、仮に、データベースにIotデータを登録したいといった要件が出てきた時に、soracomのHarvestというデータベースを使用して、データを溜めることや、soracom funnelを使用して、AWSやGCPなどに送信することが可能であったりと、soracomの提供するサービスと連携することで開発を楽に進めることができます。
また、sim自体の管理についてもsoracomのconsoleから容易に確認することができます。
### 実装
sim通信を行うのにTinyGSM
というモジュールをInstallが必要になります。今回はplatformIOとC++を使用するのでplatformIOからinstallしてください。
#include <M5Core2.h>
#define TINY_GSM_MODEM_SIM7080 //7080を指定
#define GSM_AUTOBAUD_MIN 9600
#define GSM_AUTOBAUD_MAX 115200
#include <TinyGsmClient.h>
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
void initSim(){
delay(300);
M5.Lcd.println("modem.init()");
modem.restart();
M5.Lcd.println("modem.getModemInfo()");
String modemInfo = modem.getModemInfo();
M5.Lcd.println(modemInfo);
bool result;
do {
result = modem.setNetworkMode(2);//2 Automatic, 13 GSM only, 38 LTE only, 51 GSM and LTE only
delay(500);
} while (result != true);
M5.Lcd.println("modem.setNetworkMode(38)");
do {
result = modem.setPreferredMode(1);
delay(500);
} while (result != true);
M5.Lcd.println("modem.setPreferredMode(38)");
//ここでsoracomのAPNを登録する
while (!modem.gprsConnect("soracom.io", "sora", "sora")) {
M5.Lcd.println("NG.");
delay(1000);
M5.Lcd.println("retry");
break;
}
M5.Lcd.println("modem.gprsConnect");
M5.Lcd.println("OK.");
M5.Lcd.println(" success");
bool res = modem.isGprsConnected();
M5.Lcd.println(res);
//各種情報を出力
String ccid = modem.getSimCCID();
M5.Lcd.println("CCID: " + ccid);
String imei = modem.getIMEI();
M5.Lcd.println("IMEI: " + imei);
String cop = modem.getOperator();
M5.Lcd.println("Operator: " + cop);
IPAddress local = modem.localIP();
M5.Lcd.println("Local IP: ");
M5.Lcd.println(local);
int csq = modem.getSignalQuality();
M5.Lcd.println("Signal quality: ");
M5.Lcd.println(csq);
if (modem.isNetworkConnected()) {
M5.Lcd.println("Network connected");
}
SerialMon.println("Waiting for network...");
if (!modem.waitForNetwork()) {
M5.Lcd.println("fail");
delay(1000);
return;
}
if (modem.isNetworkConnected()) {
M5.Lcd.println("Network connected");
}
}
void setup(){
M5.begin();
initSim();
}
void loop(){
M5.update;
}
接続確認
接続確認すると以下の様にIPアドレスを得ることができる
まとめ
今回M5stackCore2でsim通信を実現しました。simの規格が違う、電波が悪いなどといった様々なエラーが出てこれを実装するのにかなり苦戦しました。
仮にM5stackでsim通信が使用できたとして、firebaseなどの他のmoduleをコードを使用する場合、他のmoduleではsim通信が可能なのかを調査する必要が出ると感じました。
また、soracomのsimの連携サービスについても深く知ることができました。Funnelを使用してデータをBigqueryやfirebaseに送信し、可視化するなどを試してみようと思います。