NB-IoTを利用したMQTTデータ送受信実験
追記
Arduinoの標準のMQTTライブラリーであるPubSubclient libraryの標準はkeep aliveが15秒となっているが、Alibaba Cloud IoT plat formは30秒より短いKeep aliveを許容しない。以前別のタイプのボード触っていて気づき、自分の環境は修正済みだったので気づかずに記載漏れしていました。
Arduino IDEからマクロ定義する方法を知らないので、とりあえずヘッダーファイルを直接修正してMQTT_KEEPALIVEの値をデフォルトの15から30に変える必要あり。
#ifndef MQTT_KEEPALIVE
#define MQTT_KEEPALIVE 30
#endif
NB-IoTの現状
2019/2/17現在、NB-IoT SIMを提供しているのはSoftBankのみで、SoftBankの法人契約としてのみNB-IoTが利用できるSIMを購入することができる。
本件では「Wio LTE M1/NB1(BG96) SoftBank Edition」というハードウエアを使うが、これはSeeed社が製造したSoftBankのNB-IoTの検証を目的とする非売品であるようだ。
Wio LTE M1/NB1(BG96) SoftBank Edition
https://www.softbank.jp/biz/set/data/iot/partner-program/device/shared/spec_iot_644.pdf
準備
Arduino SDK
以下を参考に必要なソフトウエア、ドライバーをインストールする。
https://github.com/SeeedJP/Wiki/blob/master/Wio_cell_lib_for_Arduino/setup-ja.md
MQTTのパラメータ
本件ではAlibaba Cloud IoT Platformを利用するが、基本的にはmosqittoなどの他のMQTT Brokerでも利用できると思われる。ちなみにMQTT over TLSはまだ成功していない。。。。
以下のMQTTパラメータを準備する。
1. Broker Address
2. Client ID(TLSを使わないバージョンで作成)
3. UserName
4. Password
5. TOPIC
以下のURL参照
https://qiita.com/makotaka/items/388fa1ee0eb1f0237012
また、SoftBankのネットワークへ接続するためにSoftBankのSIMに紐づいた下記情報も必要になる
- APN
- Username
- Password
Source code
#include <WioCellLibforArduino.h>
#include <WioCellularClient.h>
#include <PubSubClient.h> // https://github.com/SeeedJP/pubsubclient
#include <stdio.h>
#define APN "***" //SoftBankのSIMのAPN
#define USERNAME "***" //SoftBankのSIMのuser
#define PASSWORD "***" //SoftBankのSIMのpassword
#define MQTT_SERVER_HOST "***" //MQTTのBroker Address
#define MQTT_SERVER_PORT (1883)
#define ID "***" //MQTTのClientID
#define OUT_TOPIC "***" //MQTTのTOPIC(publish用)
#define IN_TOPIC "***" //MQTTのTOPIC(subscribe用)
#define MQUSER "***" //MQTTのUsername
#define MQPASS "***" //MQTTのPassword
#define INTERVAL (60000)
WioCellular Wio;
WioCellularClient WioClient(&Wio);
PubSubClient MqttClient;
void callback(char* topic, byte* payload, unsigned int length) {
SerialUSB.print("Subscribe:");
for (int i = 0; i < (int)length; i++) SerialUSB.print((char)payload[i]);
SerialUSB.println("");
}
void setup() {
delay(200);
SerialUSB.begin(115200);
SerialUSB.println("");
SerialUSB.println("--- START ---------------------------------------------------");
SerialUSB.println("### I/O Initialize.");
Wio.Init();
SerialUSB.println("### Power supply ON.");
Wio.PowerSupplyCellular(true);
delay(500);
SerialUSB.println("### Turn on or reset.");
#ifdef ARDUINO_WIO_LTE_M1NB1_BG96
Wio.SetAccessTechnology(WioCellular::ACCESS_TECHNOLOGY_LTE_NB1);
Wio.SetSelectNetwork(WioCellular::SELECT_NETWORK_MODE_MANUAL_IMSI);
#endif
if (!Wio.TurnOnOrReset()) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Connecting to \"" APN "\".");
if (!Wio.Activate(APN, USERNAME, PASSWORD)) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Connecting to MQTT server \"" MQTT_SERVER_HOST "\"");
MqttClient.setServer(MQTT_SERVER_HOST, MQTT_SERVER_PORT);
MqttClient.setCallback(callback);
MqttClient.setClient(WioClient);
if (!MqttClient.connect(ID,MQUSER,MQPASS)) {
SerialUSB.println("### ERROR! ###");
SerialUSB.println(MqttClient.state());
return;
}
MqttClient.subscribe(IN_TOPIC);
SerialUSB.println("### Setup completed.");
}
void loop() {
char data[100];
sprintf(data, "{\"uptime\":%lu}", millis() / 1000);
SerialUSB.print("Publish:");
SerialUSB.print(data);
SerialUSB.println("");
MqttClient.publish(OUT_TOPIC, data);
unsigned long next = millis();
while (millis() < next + INTERVAL)
{
MqttClient.loop();
}
}
テスト
先ほどSubscribeしたTopicにAlibaba Cloud IoT Platformのコンソールから"pub test"とpublishしてみる。
シリアルコンソールで"pub test"と表示され、正しく動いていることを確認
ATコマンド
このハードウエアはQuectelのBG96を利用していて、"SerialModule"というオブジェクト経由でATコマンド使えるようだ。ATコマンドを利用する参考コードを書いたけど、さすがにもう少しスマートなツールがある気がする。
#include <WioCellLibforArduino.h>
WioCellular Wio;
void setup() {
delay(200);
SerialUSB.begin(115200);
SerialUSB.println("");
SerialUSB.println("--- START ---------------------------------------------------");
SerialUSB.println("### I/O Initialize.");
Wio.Init();
SerialUSB.println("### Power supply ON.");
Wio.PowerSupplyCellular(true);
delay(500);
SerialUSB.println("### Turn on or reset.");
#ifdef ARDUINO_WIO_LTE_M1NB1_BG96
Wio.SetAccessTechnology(WioCellular::ACCESS_TECHNOLOGY_LTE_M1);
Wio.SetSelectNetwork(WioCellular::SELECT_NETWORK_MODE_MANUAL_IMSI);
#endif
if (!Wio.TurnOnOrReset()) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println(F(">> Waiting for AT command"));
}
void loop() {
if (SerialModule.available()) {
SerialUSB.write(SerialModule.read());
}
if (SerialUSB.available()) {
SerialModule.write(SerialUSB.read());
}
}
ATコマンドにてネットワークやハードウエアの情報を直接取得できる。
最後に
これは私の趣味の世界です。所属する団体の考え方は全く反映していません。
Author And Source
この問題について(NB-IoTを利用したMQTTデータ送受信実験), 我々は、より多くの情報をここで見つけました https://qiita.com/makotaka/items/5eb1d0d0dd1361e84e19著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .