記事の概要
通信モジュールEC21-J Mini PCIeとSORACOM IoT Simを用いて、Google Cloud Platform(以下、「GCP」と略)に構築したGoogle IoT CoreでMQTT接続による通信を行ってみました。
そこに至るまでの全過程、モジュールの購入から最後のMQTT接続を実行するまでの記録を公開します。
記事の内容に疑問点があれば、お気軽にコメント欄、ツイッターなどにお問い合わせください。
また記事内容に間違いなどがあれば、ご指摘いただけると助かります。
参照
-
LTE Cat.1 対応モデム「EC21-J Mini PCIe」の GNSS 搭載モデルを販売開始
- 開発ボードのセッティングからGNSS動作を確認するところまで解説しています。
-
Arduino で SORACOM SIM を使ってなるべく安く通信する方法
- EC21-J Mini PCIeでSORACOM Harvest にデータを送る方法を解説しています。
- SORACOM Beam を使用して Google IoT Core と MQTT 接続する
1. ハードウェアの準備
EC21-J Mini PCIeの準備
以下のQuectel社製の通信モジュールEC21-J Mini PCIeを使用します。
(Quectel社へのリンクはユーザー登録しないと見れません。登録は無料になります。)
これはEC21-JモジュールにPCIeソケットやアンテナ端子を取りつけたLTE Cat.1 通信モジュールです。
末尾のJはJapanのことで、日本用の技適を取得済みを意味します。
末尾にJがつかないEC21は、日本での使用が違法になるのでご注意ください。
今回はGNSS機能付きのEC21-J Mini PCIeを使用します。
GNSSはグローバル衛星測位システムのことで、GPSもその1種です。
EC21-J Mini PCIeはSORACOMのIoTストアもしくはSORACOM ユーザーコンソールから購入できます。
他にもGNSS機能のないEC21-J Mini PCIeや、UC20-G Mini PCIe、BG96 MiniPCIeも販売しています。
開発ボード Mini PCIe EVBKITの準備
Mini PCIe EVBKITはPCIeソケットを備えた開発ボードです。
PCIeソケットにQuectel社のPCIe端子付きの通信モジュールを取り付けることで、簡単にPCによる制御が行えます。
今回はEC21-J Mini PCIeを取り付けます。
こちらもSORACOMのIoTストアもしくはSORACOM ユーザーコンソールから購入できます。
PCIeソケットなどの部品を購入して、治具を自作することも可能と思いますが、制作に要する時間(部品選定、販売店検索、発注、制作、動作試験、修正)を時給換算で見積もると、開発ボードを購入した方が安上がりでした。
手作りを楽しみたい場合や、時間に余裕がある場合は、自作してもいいと思います。
UART通信方法
後述するEC21-Jの操作を行う為に、EC21-JとUART通信を行わないといけません。
開発ボードを用いれば、PCからEC21-JとUART通信を行えます。
ドライバーは開発ボード付属のCDもしくはQuectelのサイトの「Download」の「USB Drivers」からダウンロード済みとします。
複数のドライバーがありますが、私は以下のフォルダのexeファイルを実行しました。(必須ではないものも実行しているかもしれません。)
Quectel_LTE_Windows_USB_Driver_V1.0.0
EC21&EC25_WinCE6.0_USB_DriverV1.0
Quectel_BG96_Windows_USB_Driver_V1.0
次に付属のUSB-RS232ケーブルを用いて、開発ボードとPCを接続します。
秋月電子などで販売しているUSB-RS232ケーブルでも問題ないと思います。
FT232 USBシリアル変換ケーブル VE488
USBシリアル変換アダプタ
USBとシリアルケーブルをPCに接続し、開発ボードの電源ONにして、デバイスマネージャーで確認すると、以下のようにUSBポートが3つ、シリアルポートが1つ表示されます。
TeraTermなどのターミナルソフトを開いて、COM Port(私の場合はCOM9)を選択し、通信設定を115200bpsにすればPCからUART通信できます。
アンテナの取り付け
GNSSアンテナをモジュールのアンテナ端子の真ん中GNSSに取り付けます。
2本のアンテナは両端のアンテナ端子MAINとDIVに取り付けます。
SORACOM IoT SIMの準備
SORACOM IoT SIMを用いるとIoTに適したSORACOMのネットワークサービスを安価に利用できます。
3G/LTE に対応したデータ通信、データ転送、データ管理、データの可視化と共有など様々なサービスがあります。
以下のチュートリアル通りに行えば簡単に利用開始できます。
SORACOMのIoTストアもしくはSORACOM ユーザーコンソールから購入できます。
今回は特定地域向け IoT SIM (plan-D)標準サイズを使用します。
SIMはスイッチサイエンスなどでも購入できます。
https://www.switch-science.com/catalog/3960/
https://www.switch-science.com/catalog/5884/
SIMの登録
SORACOMにはアカウント登録済みとして以下の話を進めます。
開発ボード一式およびSIMをSORACOMから購入した場合は、ユーザーコンソールの「Menu」→「発注」から注文品のステータスの「受け取り確認」をクリックするだけでSIMが登録されます。
以下のマニュアルに従ってグループ作成します。
SIM のグループ管理
対象の先頭セルのボックスにチェックを入れて、操作から利用開始を選択すれば、通信ができるようになります。
課金も開始されますので、まだ利用する予定のない方はご注意ください。
もっとも、基本料金は10円/1日と安く、開発ボードの無料クーポン分でしばらくは課金されないので、あまり気にすることもないと思います。
2. EC21-Jの動作確認
EC21-Jは、UART通信でATコマンドを送信することで操作できます。
今回はPCから操作しますが、いずれマイコンからのUART通信で制御したいと思います。
EC21-JのUART通信確認
EC21-Jが動作しているかを確認します。先述した方法でターミナルでシリアルポートを開いてください。
まずは、自分の入力したコマンドが分かりやすいように入力エコーを有効にします。
エコーとは、送信した文字を、そのまま送り返してもらって受信することです。
ATE1
と入力してENTERを押せば、以降は自分の入力した文字も表示されます。
(エコーが無効ならば、入力しても画面には何も表示されません。)
次に、製品識別情報表示コマンド
ATI
を入力してください。
社名、製品名、Revisionの3行が表示されれば、EC21-Jと正常に通信できています。
GNSSの動作確認
GNSSの動作を確認します。まずは電源ONに、開発ボードのNRT_STATUS LEDが点灯後に、以下のコマンドを入力してGNSSを起動します。
AT+QGPS=1
GNSSの取得データは、TeraTermを新規に開いて、「Quectel USB NMEA Port」から確認してください。通信速度は4800bpsに設定します。
シリアル通信でも以下のコマンドでGNSSの位置情報を取得できます。
AT+QGPSLOC?
GNSSは以下のコマンドで停止できます、
AT+QGPS=0
もしくは
AT+QGPSEND
3. 通信試験
EC21-JとSIMを用いて、ネットワークに接続し、データ通信できるかを確認します。
以下の通信試験は、bearminiさんの記事「Arduino で SORACOM SIM を使ってなるべく安く通信する方法」を参照しました。
AT+QCFG="roamservice"[,<roammode>[,<effect>]]
ローミングを有効にします。
初期状態で有効かもしれませんが一応設定しておきます。
roammodeを2に設定すると「ローミング有効化」、effectを1に設定すると「即座に有効化」になります。
effectを省力すると、自動で「即座に有効化」の設定になります。
AT+QCFG="roamservice",2,1
AT+COPS=<mode>[,<format>[,<oper >[,<Act>]]]
登録可能なオペレータ一覧を以下のコマンドで確認します。
AT+COPS=?
また、現在登録されているオペレーターは以下のコマンドで確認します。
AT+COPS?
私の場合は、既にオペレーターが登録済みだったので、設定は省略します。
もしAT+COPS?で何も表示されない場合は、手動で設定します。
AT+COPS=? で検索した登録可能なオペレータ一覧から選択して、以下のコマンドを実行します。
modeは1の手動選択に設定し、formatは2のGSM location area識別番号に設定し、operは各位の環境に合わせて選択ください。
AT+COPS=1,2,"44010"
設定後は、正常にオペレーターが登録されているか確認しておきます。
AT+COPS?
AT+QICSGP=<contextID>[,<context_type>,<APN>[,<username>,<password>)[,<authentication>]]]
APN, username, password TCP/IP contextパラメータの設定を行います。
contextIDは1から16の任意の番号を設定し、context_typeは1のプロトコルタイプ:IPV4 に設定し、APNは"soracom.io"に設定し、usernameとpasswordは"sora"に設定し、authenticationは0の認証なしに設定します。
AT+QICSGP=1,1,"soracom.io","sora","sora",0
AT+QIACT=<contextID>
PDP認証を行います。
AT+QICSGPで設定したcontextIDを指定することで、設定を有効化できます。
AT+QIACT=1
設定前後にAT+QIACT?を実行すると、設定実行後に有効化されていることが分かります。
ここまでの設定を行うと、SORACOMのユーザーコンソールにおいて、セッション状態がオンラインになってます。
SORACOM Harvestの設定
データ送信のテストを行う為にSORACOM Harvestを設定します。
SIMの所属するグループを選択し、SORACOM Harvest Data設定をONにして保存します。
1SIMあたり5円/1日の課金が発生するので、通信試験完了後はOFFに戻して保存するのを忘れないようにご注意ください。
AT+QIOPEN=<contextID>,<connectID >,<service_type>,<IP_address>/<domain_name>,<remote_port>[,<local_port>[,<access_mode>]]
SORACOM Harvestを開きます。
AT+QIOPEN=1,0,"TCP","harvest.soracom.io",8514
AT+QISEND=<connectID>
AT+QIOPENで設定したconnectIDを指定してデータを送信します。
AT+QISEND=0
上記コマンド実行後、送信したいデータを入力してから、Ctrl+Zを入力するとデータが送信されます。
データが送信されているかを確認してみます。
使用したSIMにチェック入れてから、「操作」→「データを確認」を選択します。
ネットワークと接続して通信できることが確認できました。
AT+QICLOSE=<connectID>
AT+QIOPENで設定したconnectIDを指定して接続を閉じます。
AT+QICLOSE=0
SORACOM Harvest Data設定をOFFに戻して保存し、通信試験を完了します。
4. Google IoT Core
##GCP側の設定
ここではGCPにアカウント登録済みとして、Google IoT Coreの作成します。
SORACOM Beam を使用して Google IoT Core と MQTT 接続するの説明に従って作業します。
2: レジストリID、リージョン、Cloud Pub/Subトピックの作成
トピックIDを入力すれば、自動で適切なフォルダ内にトピックが作成されます。
3: 「詳細設定を表示」から「プロトコル」をMQTTのみにする
4: 「作成」をクリック
公開鍵・秘密鍵の作成
GCPでターミナルを開いて公開鍵と秘密鍵を作成します。
openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem
公開鍵・秘密鍵のデータをコピーしたい場合は、「エディタを開く」から選択すると便利です。
デバイスの作成
「SORACOM Beam を使用して Google IoT Core と MQTT 接続する」の「公開鍵を登録してデバイスを作成する」を参照してください。
SORACOM側の設定
「SORACOM Beam を使用して Google IoT Core と MQTT 接続する」の「ステップ 2: SORACOM Beam を設定する」を参照してください。
プロジェクトID、リージョン、レジストリID、デバイスID
プロジェクトID、リージョン、レジストリID、デバイスIDの4つはMQTT接続時に入力を求められることがあります。
GCPではこれらを以下により確認できます。
プロジェクトIDはGCPでプロジェクト作成時に割り当てられたIDです。
リージョンとレジストリIDはレジストリ作成時に設定した名前と地域を使用します。
5. MQTT接続
SORACOM Beamを使用する利便性
SORACOM Beamを使用する利便性は色々とありますが、私が特に便利に思ったのは、暗号化の手間が省けることです。
Google Cloud IoT Core においてMQTT接続を行うためには、TLS(Transport Layer Security)による暗号化が必要になります。
暗号化方法については、以下のMQTTサーバ認証手続きのマニュアルにあります。
Publishing over the MQTT bridge#Downloading MQTT server certificates
これを見るとパスワードとしてJWT(JSON Web Token)の作成が求められます。
Googleが公開している組み込み用のサンプルプログラムを見れば、毎アクセス時にAPI関数 iotc_create_iotcore_jwt()を用いて、pemファイルやその他変数を代入し、JWTを作成しているのが分かります
PCのターミナルからATコマンド送信する場合は、上記サンプルサイトのPythonコードをPC上で走らせてJWTを生成し、コマンドに挿入するといいと思います。(実際に試していないので、できるかどうかは分かっていません)
「GCP Cloud IoT CoreにGolangでMQTT接続する」の記事を見ると、JWTの生成には以下のパラメータが必要なようです。
- username: "unused"
- password: jwtを使って生成
- iat: 現在時刻のUnixTime,
- exp: 現在時刻+60分のUnixTime : 有効期限。期限を過ぎると接続が解除されるので、都度接続確認を行なう。
- aud: projectID
- Signin Method: SigningMethodRS256
- SigningKey: 添付のpem
添付のpemというのは先に生成したprivate keyのことだと思います。
RAMの少ないマイコンにpemデータの領域を確保するのは、少し厄介なことです。
暗号生成の計算はマイコンの低性能CPUには負担でもあります。
そこでSORACOM Beamを使うと、以下の記事のように、この暗号化処理が省略できます。
新機能:SORACOM が Google Cloud Platform と連携出来るようになりました!
- 認証情報をSIMと紐付ければSORACOMがJWTを生成・署名 → デバイス側のProvisioningを行うことなくGCPに接続可
以降は実際にEC21-JからATコマンドを送信してMQTT接続を行います。
その際にはQuectelのサイトの「Download」の「Documents」からダウンロードできるアプリケーションノート「Quectel_EC2x&EG9x&EM05_MQTT_Application_Note_V1.1」の「5.1 Example of MQTT Operation without SSL」を参照しています。
ここではSSLなしを参照している理由は、以下の図のようにSORACOMのサーバにSSLなしのMQTTで通信すれば、MQTTS通信に変換してくれるからです。
今回はPCのターミナルを使用していますが、マイコンに実装する時も、UART通信でATコマンドを送信するだけでいいので、とても簡単になります。
(補足)root.pem
SORACOM Beamを使用するならば必要ないと思いますが、mqtt.googleapis.comのroot CA certification package (128 KB)は以下からダウンロードできます。
PDP認証
通信試験と同様にPDP認証を行います。
AT+QICSGP=1,1,"soracom.io","sora","sora",0
AT+QIACT=1
AT+QIACT?
AT+QMTCFG="recv/mode",<client_idx>,<msg_recv_mode>[,<msg_len_enable>]
AT+QMTCFGはAT+QMTOPENを実行する前に行います。
サーバからのデータ受信設定を決めます。
msg_recv_modeを0に設定します。サーバーから受信したMQTTメッセージがURCに含まれるようになります。
msg_len_enableを1に設定します。サーバーから受信したMQTT長さメッセージがURCに含まれるようになります。
AT+QMTCFG="recv/mode",0,0,1
AT+QMTOPEN=<client_idx>,"<host_name>",<port>
SORACOM Beamのサーバーを開きます。
client_idxは0から5のどれかの値を設定します。
SORACOM Beamのhost_nameとportは以下になります。
- host_name
- beam.soracom.io
- port
- 1883
AT+QMTOPEN=0,"beam.soracom.io",1883
設定が有効になっているかを以下のコマンドで確認します。
AT+QMTOPEN?
AT+QMTCONN=<client_idx>,"<clientID>"[,"<username>"[,"<password>"]
SORACOM Beamのサーバーと接続します。
client_idxはAT+QMTOPENで設定したのと同じ値を使用します。
clientIDは以下になります。プロジェクトIDなどを各位の環境に合わせて設定してください。
"projects/[プロジェクトID]/locations/[リージョン]/registries/[レジストリID]/devices/[デバイスID]"
AT+QMTCONN=0,"projects/vigilant-router-xxxxxx/locations/us-central1/registries/test/devices/MatsuiEC21J"
AT+QMTSUB=<client_idx>,<msgID >,"<topic1>",<qos1>[,"<topic2>",<qos2>…]
クラウドからEC21-Jへデータを送信します。
データ受信時には"/devices/<デバイスID>/commands/#" というtopicへ Subscribeするように設定します。
client_idxはAT+QMTOPENで設定したのと同じ値を使用します。
msgID は1から65535のどれかの値を設定します。
qosはレベル0に設定します。 QoS0は送信成功か否かに関わらず、1回だけメッセージを発行します。
(参照「QoSとは?MQTTにおける通信の種類!」)
AT+QMTSUB=0,1,"/devices/MatsuiEC21J/commands/#",0
実際にデータを受信できるか確認してみます。
IoT Coreからデバイスを選択します。
「コマンドを送信」をクリックします。
メッセージを入力して「コマンドを送信」をクリックします。
ターミナルに受信データが表示されるのが確認できます。
AT+QMTPUBEX=<client_idx>,<msgID >,<qos>,<retain>,"<topic>",<msg_length>
EC21-Jからクラウドへデータを送信します。
データ送信時には/devices/<デバイスID>/events というtopicへ Publishするように設定します。
client_idxはAT+QMTOPENで設定したのと同じ値を使用します。
msgID は1から65535のどれかの値を設定します。
ただし、qos=0の場合は、0に設定しないといけません。
qosはレベル0に設定します。
retainは0に設定します。送信に対してサーバーは応答を返しません。
msg_lengthは送信データの最大長さを設定します。
AT+QMTPUBEX=0,0,0,0,"/devices/MatsuiEC21J/events",10
最大でmsg_lengthで指定した長さのデータを送信できます。
もしくは以下のコマンドでもPublishできます。
AT+QMTPUB=0,0,0,0,"/devices/MatsuiEC21J/events"
AT+QMTPUBEX=<client_idx>,<msgID >,<topic>/config,<qos>
あらかじめ設定したデータ、Configurationの読み出しが行えます。
データを読み出す場合にはsubscribeコマンドと類似した以下のコマンドを用います。
AT+QMTSUB=0,1,"/devices/MatsuiEC21J/config",0
このコマンドを実行すると、例えば以下のように設定したデータTestConfiguration,01234567890
が受信できます。
AT+QMTSUB=0,1,"/devices/MatsuiEC21J/config",0
OK
+QMTSUB: 0,1,0,0
+QMTRECV: 0,0,"/devices/MatsuiEC21J/config","TestConfiguration,01234567890"
一度データを受信すると、コマンドを再送信してもデータ受信できないのでご注意ください。
Configurationのデータに更新があるか、一度サーバと切断して、再接続すると、コマンド送信によりデータを再受信できるようになります。
GCPのConfiguration設定は、IoT Coreでデバイスの「レジストリ詳細」を開き、「構成を編集」からデータ入力画面に進むことができます
AT+QMTDISC
以下のコマンドで終了します。
AT+QMTDISC=0
6.次にすること
これでMQTTに接続できていることは確認できました。本記事はここで終了とさせていただきます。
実際の応用、複数のデバイスからデータを収集し、サーバからデバイスを制御するなどは、今後試して記事にする予定です。
また、IoTは小さなデバイスに集約してこそ使い道があると思います。
今回のようにPCで制御するのではなく、EC21-Jをマイコンと接続して、UART通信で制御できるようにする予定です。
より安く、より小さく、より高機能なデバイスを作ることを目標としています。
これも実験結果を記事にする予定です。
参考
-
【作業メモ】GPSロガーの作成
- 本記事の続きとしてGPSロガーを作成しました。
-
SORACOM BeamによるGCPとのMQTT通信のプラットフォームバージョン「201912」対応についての覚書
- プラットフォームバージョン「201912」対応について、MQTTバージョンを3.11 に設定する方法を解説しています
-
【作業メモ】Quectel社のLTE通信モジュールEC21の使用方法
- LTE通信モジュールのATコマンドやGCPの設定について解説しています。
追記メモ
- 2021/07/19
- GCPでConfigurationに設定したデータを受信する方法を追加
- [AT+QMTPUBEX=<client_idx>,<msgID >,<topic>/config,<qos>](## AT+QMTPUBEX=<client_idx>,<msgID >,<topic>/config,<qos>)