15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EC21-JとSORACOM IoT SIMによりGoogle IoT CoreでMQTT接続を行うまでの全過程の記録

Last updated at Posted at 2020-05-18

記事の概要

通信モジュールEC21-J Mini PCIeとSORACOM IoT Simを用いて、Google Cloud Platform(以下、「GCP」と略)に構築したGoogle IoT CoreでMQTT接続による通信を行ってみました。

そこに至るまでの全過程、モジュールの購入から最後の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つ表示されます。

デバイス確認.png

TeraTermなどのターミナルソフトを開いて、COM Port(私の場合はCOM9)を選択し、通信設定を115200bpsにすればPCからUART通信できます。

TeraTerm設定1.png TeraTerm設定2.png TeraTerm設定3.png

アンテナの取り付け

GNSSアンテナをモジュールのアンテナ端子の真ん中GNSSに取り付けます。
2本のアンテナは両端のアンテナ端子MAINとDIVに取り付けます。
開発ボード.jpg

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が登録されます。

SORACOM_SIM登録.png SORACOM_SIM登録2.png

以下のマニュアルに従ってグループ作成します。
SIM のグループ管理

SORACOM_SIM登録3.png

対象の先頭セルのボックスにチェックを入れて、操作から利用開始を選択すれば、通信ができるようになります。

課金も開始されますので、まだ利用する予定のない方はご注意ください。
もっとも、基本料金は10円/1日と安く、開発ボードの無料クーポン分でしばらくは課金されないので、あまり気にすることもないと思います。

SORACOM_SIM登録4.png SORACOM_SIM登録5.png

2. EC21-Jの動作確認

EC21-Jは、UART通信でATコマンドを送信することで操作できます。
今回はPCから操作しますが、いずれマイコンからのUART通信で制御したいと思います。

EC21-JのUART通信確認

EC21-Jが動作しているかを確認します。先述した方法でターミナルでシリアルポートを開いてください。

まずは、自分の入力したコマンドが分かりやすいように入力エコーを有効にします。
エコーとは、送信した文字を、そのまま送り返してもらって受信することです。

ATE1

と入力してENTERを押せば、以降は自分の入力した文字も表示されます。
(エコーが無効ならば、入力しても画面には何も表示されません。)

次に、製品識別情報表示コマンド

ATI

を入力してください。
社名、製品名、Revisionの3行が表示されれば、EC21-Jと正常に通信できています。
ATIコマンド試験1.png

GNSSの動作確認

GNSSの動作を確認します。まずは電源ONに、開発ボードのNRT_STATUS LEDが点灯後に、以下のコマンドを入力してGNSSを起動します。

 AT+QGPS=1

起動に成功すればOKが返ります。
GNSS試験1.png

GNSSの取得データは、TeraTermを新規に開いて、「Quectel USB NMEA Port」から確認してください。通信速度は4800bpsに設定します。
GNSS試験3.png

以下のようにGNSSからの情報が表示されます。
GNSS試験4.png

シリアル通信でも以下のコマンドでGNSSの位置情報を取得できます。

AT+QGPSLOC?
GNSS試験5.png

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? 
ATCOPS1.png

私の場合は、既にオペレーターが登録済みだったので、設定は省略します。

もし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?を実行すると、設定実行後に有効化されていることが分かります。

ATQIACT.png

ここまでの設定を行うと、SORACOMのユーザーコンソールにおいて、セッション状態がオンラインになってます。
ATQIACT2.png

SORACOM Harvestの設定

データ送信のテストを行う為にSORACOM Harvestを設定します。
SIMの所属するグループを選択し、SORACOM Harvest Data設定をONにして保存します。
1SIMあたり5円/1日の課金が発生するので、通信試験完了後はOFFに戻して保存するのを忘れないようにご注意ください。

Harvest1.png Harvest2.png

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を入力するとデータが送信されます。
Harvest4.png

データが送信されているかを確認してみます。
使用したSIMにチェック入れてから、「操作」→「データを確認」を選択します。
Harvest5.png

コマンド送信したのと同じデータが確認できます。
Harvest6.png

ネットワークと接続して通信できることが確認できました。

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 接続するの説明に従って作業します。

1: IoT Coreを開いてレジストリを作成
IotCore1.png

2: レジストリID、リージョン、Cloud Pub/Subトピックの作成
IotCore2.png
IotCore3.png

トピックIDを入力すれば、自動で適切なフォルダ内にトピックが作成されます。
IotCore3b.png

3: 「詳細設定を表示」から「プロトコル」をMQTTのみにする
IotCore4.png

IotCore5.png

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
pem.png

公開鍵・秘密鍵のデータをコピーしたい場合は、「エディタを開く」から選択すると便利です。

デバイスの作成

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です。
projectID.png

リージョンとレジストリIDはレジストリ作成時に設定した名前と地域を使用します。
REGISTRY_ID.png

デバイスIDはデバイス作成時に設定した名前を使用します。
DEVICE_ID.png

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通信に変換してくれるからです。

beam_cloud-iot-core.png

今回は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からデバイスを選択します。

SUB0b.png

「コマンドを送信」をクリックします。

SUB0.png

メッセージを入力して「コマンドを送信」をクリックします。

SUB1.png

ターミナルに受信データが表示されるのが確認できます。

SUB2.png

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で指定した長さのデータを送信できます。
PUBEX1.png

もしくは以下のコマンドでもPublishできます。

AT+QMTPUB=0,0,0,0,"/devices/MatsuiEC21J/events"

データを入力後、Ctrl-Zで送信されます。
PUB1.png

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.png

一度データを受信すると、コマンドを再送信してもデータ受信できないのでご注意ください。
Configurationのデータに更新があるか、一度サーバと切断して、再接続すると、コマンド送信によりデータを再受信できるようになります。

GCPのConfiguration設定は、IoT Coreでデバイスの「レジストリ詳細」を開き、「構成を編集」からデータ入力画面に進むことができます

デバイスの編集.png

AT+QMTDISC

以下のコマンドで終了します。

AT+QMTDISC=0 

6.次にすること

これでMQTTに接続できていることは確認できました。本記事はここで終了とさせていただきます。
実際の応用、複数のデバイスからデータを収集し、サーバからデバイスを制御するなどは、今後試して記事にする予定です。

また、IoTは小さなデバイスに集約してこそ使い道があると思います。
今回のようにPCで制御するのではなく、EC21-Jをマイコンと接続して、UART通信で制御できるようにする予定です。
より安く、より小さく、より高機能なデバイスを作ることを目標としています。
これも実験結果を記事にする予定です。

参考

追記メモ

  • 2021/07/19
    • GCPでConfigurationに設定したデータを受信する方法を追加
    • [AT+QMTPUBEX=<client_idx>,<msgID >,<topic>/config,<qos>](## AT+QMTPUBEX=<client_idx>,<msgID >,<topic>/config,<qos>)
15
11
0

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
15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?