LTEルーターとさくらのセキュアモバイルコネクトSIMを利用してIoT用の通信確認やってみました

## LTEルーターとさくらのセキュアモバイルコネクトSIMを利用してIoT用の通信確認やってみました

## 概要
さくらのセキュアモバイルコネクトとLTEルーターを介してESP32でMQTTの接続確認を行いました。その際の実際の手順とtipsを書いていきます。（今回試したのはESP32ですが少し手を加えればM5stackでも使えると思います）  
## 背景
弊社では農業用の環境モニタリングに取り組んでいます。実際に環境モニタリングを行っており、現在はWi-Fiを利用して通信を行っています。  
さらに利便性を増すためにLTEを利用することを検討しています。
そのために安価に安定した通信を行えなるLTEを探しています。  
その候補の一つとしてさくらのセキュアモバイルコネクトを選択して通信テストを行なってみました。  
実際の手順とtipsを共有します。

## 使用した機材

[LTEルーター　UD-LT1/EX](https://www.iodata.jp/product/lan/appliance/ud-lt1ex/index.htm)  
[PoEハブ　TP-Link TL-SG1005LP PoE switch](https://www.tp-link.com/jp/business-networking/unmanaged-switch/tl-sg1005lp/)  
[さくらセキュアモバイルコネクトSIM](https://iot.sakura.ad.jp/sim/flow/)  
自社作成基板　([Arduino](https://www.amazon.co.jp/Arduino-Rev3-ATmega328-%E3%83%9E%E3%82%A4%E3%82%B3%E3%83%B3%E3%83%9C%E3%83%BC%E3%83%89-A000066/dp/B008GRTSV6/ref=asc_df_B008GRTSV6/?tag=jpgo-22&linkCode=df0&hvadid=266655852239&hvpos=&hvnetw=g&hvrand=6060706888519499689&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009727&hvtargid=pla-457497319401&psc=1)、[w5500](https://www.wiznet.io/product-item/w5500/)の組みあわせで代用できます)  
([M5stack](https://www.switch-science.com/catalog/3647/)、[w5500スタックボード](https://www.switch-science.com/catalog/7589/)の組みあわせで代用可能です。慣れてない方はこちらの方が無難です。)  
※PoE搭載モデルはおすすめしません
LANケーブル    
ラズベリーパイ（入手しずらいのでwindows+wsl、docker+debianで代用可能）    
開発用PC(ArduinoIDE)  
	

## セキュアモバイルコネクトSIMについて
現在お試し[キャンペーン](https://iot.sakura.ad.jp/request_sim_trial/)もやっていますので、無料で試すことができます。（個人以外での会員IDが必要になります。2022/09/17現在）  

## 実際の手順
### SIMの登録
SIMの登録とモバイルゲートウェイの有効化をします。手順については公式のわかりやすいドキュメントがあります。
[こちら](https://manual.sakura.ad.jp/cloud/manual-mobile-connect.html?_gl=1*16670ab*_gcl_aw*R0NMLjE2NjM0MjA0ODcuQ2p3S0NBanc0SldaQmhBcEVpd0F0SlVOMEZXb2luQnFBNGZ4WFNzaWJGdUMxNVhCNEM1b0tTaG1aTmFfZEN5NGVIc2tjWnlTb3lSdl9Cb0NOVTBRQXZEX0J3RQ..*_ga*MTY5NDk5MzMuMTY1MzY1MjUzOA..*_ga_9JHRGQJ1CX*MTY2MzQyMjU3Mi40Mi4wLjE2NjM0MjI1NzIuNjAuMC4w*_ga_M3MLBH78ML*MTY2MzQyMjU3Mi40OC4wLjE2NjM0MjI1NzIuNjAuMC4w&_ga=2.48141735.1452586760.1663058025-16949933.1653652538&_gac=1.125903359.1663420487.CjwKCAjw4JWZBhApEiwAtJUN0FWoinBqA4fxXSsibFuC15XB4C5oKShmZNa_dCy4eHskcZySoyRv_BoCNU0QAvD_BwE)を参考にSIMの登録をしてモバイルゲートウェイを有効にします。  
モバイルゲートウェイがテストで使用するには若干高額ですので、上記のキャンペーンを利用します。

### LTEルーターの設定
LTEルーターの設定をしていきます。SIMカードスロットにSIMを挿入します。SIMの大きさが合わないときは[SIM変換アダプタを](https://www.monotaro.com/p/7703/5815/?utm_id=g_pla&utm_medium=cpc&utm_source=google&utm_campaign=246-833-4061_6466659573_shopping&utm_content=96539050923&utm_term=_419857551521_x_pla-879931900515&gclid=Cj0KCQjwvZCZBhCiARIsAPXbajvaHhhXR9VzX6FmO0ZetUTj9yWGkxbigTsWPOK7Eui2aIyNoNGwCwAaAmIXEALw_wcB)使用すると便利です  
電源を入れて設定をしていきます。設定を行う際にはLTEルーターと設定用のPCを直接接続する必要が有ります。今回は有線LANで接続しました。  
ルーターの電源を入れてPCのブラウザから設定ページに入っていきます。　　
設定ページでは4G//3Gのネットワーク設定を行います。具体的にはAPNやパスワードの設定をする必要があります。  
今回はさくらのセキュアモバイルコネクトSIMを使用しますので、さくらのAPNを設定します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/5ce19db6-40c8-bbee-183c-1a4ec359294b.png)

APNはsakuraです。名前は適当につけます。この設定を保存するとモバイル回線を使用できるようになります。
### PCによる接続確認
ここまでの準備でLTE通信ができるようになったはずなので、実際に通信の確認を行います。  
有線接続しているPCのWi-Fiが接続されている場合は切断して、Ethernet接続のみにします。  
ブラウザを開いて好きなページにアクセスします。接続できたらLTEによるインターネット接続が確認できました。  
### MQTT bokerサーバーについて
mqtt brokerサーバーは実験用のサーバーを用意しました。  
自分でbrokerサーバーを立ててみたい人は[こちら](https://shin-naka.sakura.ne.jp/dgh34280/2018/11/02/environment1/)の記事を参考に試してみてください。  
そんなに時間がかけられないという人は外部サービスを利用してください。
(外部サイト例) [mqtt.uko.jp](https://mqtt.uko.jp/)  

### 通信用プログラムの作成
ESP32で接続を行うためのプログラム（以下スケッチ）をArduinoIDEを使用して作成します。  
Ethernet2 https://github.com/adafruit/Ethernet2 のライブラリとpubusubclient https://pubsubclient.knolleary.net/ ライブラリを使用します。 
ArduinoIDEのライブラリの管理を利用してインストールします。   
それぞれ、「ethernet2」、「pubsubclient」と検索するとでてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/dbe06364-0014-6582-348a-a498bd140847.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/a84c2cf3-25b4-5ce9-ca30-aa60a8d16252.png)


Ethernet2ライブラリについてはそのままではコンパイルできないので、ボードライブラリの中のserveer.hを修正する必要が有ります。  
自分の場合はここにありました。
C:\Users\user_name\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\cores\esp32\Server.h
ヘッダーファイルの中を確認します。
``` cpp
class Server: public Print
{
public: 
    virtual void begin(uint16_t port=0) =0;    
};
```
virtual void begin(uint16_t port=0) =0;をvirtual void begin() =0;に書き換えます。  
元のコードはコメントアウトで残しておくと便利です。  
書き換え例
```cpp
class Server: public Print
{
public:
    // add by nakamura 2022-09-15 https://github.com/arduino-libraries/Ethernet/issues/88 
    // virtual void begin(uint16_t port=0) =0;          // wifi
    virtual void begin() =0;                // ethernet
};
```
これでコンパイルができるようにりました。

実際に動かすスケッチ例です。
```cpp
/* ethernet2_Mqtt_Operation_Check.ino
 * 
 * イーサネットでMQTTの送受信ができるかどうか確認するためのテストプログラム
 * Macアドレスを適当に決め打ちにしているので実際に使用する際には注意が必要
 * @author S.Nakamura 2022-09-16
 * 
 * 参考情報
 * https://github.com/arduino-libraries/Ethernet/issues/88 
*/

#include <Ethernet2.h> 
#include <PubSubClient.h> 

// リセットピンの指定（使用する基板に合わせる。ここでは自社製基板に合わせている）
#define ETH_RESET 4
#define SPI_SS  15

// テスト用のダミー設定
byte mac[] = { 0x70, 0x69, 0x69, 0x2D, 0x30, 0x31 };    // 適当に指定している。使用する基板の指示にしたがってください
byte defip[] = {192,168,8,101};                         // ルーターのipアドレスと違うものを指定する 

// mqttの設定データ
const char *brokerserver = "your_mqtt_server";          // 会社のサーバー DNSでも使用可能
const int port = 1883;                                  // ポート番号(MQTT TCP接続)
char *pubTopic = "helloMqtt";                           // topicを指定する

EthernetClient ethClient;
PubSubClient mqttClient(ethClient);

void InitEther();                       // イーサネットを初期化してスタートする
void connectMqtt();                     // ブローカーサーバーに接続する
void MqttPublish(String pubMessage);    // mqttを送信する
String getMacAddr();                    // Macアドレスを文字列で取得する

void setup(){
	Serial.begin(115200);
	Serial.println("ether net start");
    InitEther();                        
    // Ethernet.begin(mac);             // DHCPを利用するとき
    Ethernet.begin(mac, defip);         // ipアドレスを指定するとき
    Serial.print("IP: ");               // 動作確認のための表示
    Serial.println(Ethernet.localIP());
    connectMqtt();                      // mqttサーバーに接続する
}

void loop(){
    mqttClient.loop();
    MqttPublish("hello ethernet");
    delay(1000);
}   // loop end


// イーサネットを初期化する
void InitEther(){
    pinMode(ETH_RESET, OUTPUT);
    digitalWrite(ETH_RESET, 0);
    delay(5);
    digitalWrite(ETH_RESET, 1);
    delay(50);
    Ethernet.init(SPI_SS);
}

// ブローカーサーバーに接続する
void connectMqtt(){
    String clientId;
    mqttClient.setServer(brokerserver, port);   // brokerサーバーを指定する
    Serial.println("Connecting to MQTT...");
    clientId = "ESP32-" +  getMacAddr();        // クライアントIDの作成
    Serial.print("clientID : "); 
    Serial.println(clientId.c_str()); 
    while (!mqttClient.connected()) {           // サーバーとの接続確認
        //if ( mqttClient.connect(clientId.c_str(),mqtt_username, mqtt_password) ) {  // ユーザー認証を利用するとき
        if (mqttClient.connect(clientId.c_str())) {                                   // ユーザー認証を利用しないとき
            Serial.println("Connected.");
        } else {                                // 接続に失敗したときは５秒後に再挑戦
            Serial.print("Failed. Error state=");   
            Serial.print(mqttClient.state());
            delay(5000);
        }
    }
}

// mqttを送信する
void MqttPublish(String pubMessage){
    mqttClient.publish(pubTopic, pubMessage.c_str());  // topic, payload
    Serial.println("published");
}

// Macアドレスを文字列で取得する
String getMacAddr(){
    char buf[50];
    sprintf(buf, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    return String(buf);
}

```
サンプルスケッチを利用する際は、リセットピンを確認して、ブローカーサーバーとipアドレスを指定すると動きます。  
ESP32用に書いていますので、M5stackで使用するとにはM5stackのヘッダーファイルをインクルードしてM5.begin()メソッドを呼び出す必要があります。

## 受信側の準備
### ラズベリーパイのセットアップ
続いてラズベリーパイのセットアップを行います。  
ラズベリーパイの初期設定についてはネット上に良記事がたくさんありますので、今回は触れません。  
接続確認にはNode-REDを使用すると何かと便利なことが多いので、Node-REDをインストールします。  
ラズベリーパイコンソール上で下記のコマンドを実行します。
```console
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
```
インストールが終わったら
```
node-red
```
コマンドを実行することでNode-REDを使用できるようになります。  
ブラウザからlocalhost:1880にアクセスすることでNode-REDのGUIが使用できるようになります。  
（リモート接続している場合は、ipadress:1880にアクセスします）
### 外部サーバーでのMQTTの受信準備
PCは別系統でインターネットに接続してMQTTの受信を行います。  
これもNode-REDを使用して受信の確認を行うのですが、外部サーバーを利用したほうがネットワークにつながっているという感じがするので、  
今回は[enebular](https://www.enebular.com/ja/)というSaaSを使用します。　　
簡単な登録をすることで、無料で試用することができます。
分かりにくい際は[こちら](https://qiita.com/shinfrom/items/2f350d789a89b7086df3#node-red%E7%92%B0%E5%A2%83%E3%81%AE%E6%BA%96%E5%82%99)を参考にしてください。  

### Node-REDのフローの作成
ここからはNode-REDでMQTTの受信の準備を行います。  
ラズベリーパイ上、enebular上での操作は基本的に同じものになります。  

左側の部品からmqttの受信ノードとデバッグノードをフローに配置します。
配置したら線で結びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/f2cf87be-25ed-90b3-2947-a96779bc1ccc.png)

mqttノードをダブルクリックします。設定画面が開きますので、サーバーの指定とトピックの指定をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/a352e058-e68b-c240-f8ee-aeb5e93083fa.png)

右上のデプロイボタンを押してデプロイを行います。
これでmqttの受信が行えるようになりました。

テストの準備ができましたので、実際にハードウェアを接続します。
接続イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/17bba737-8a68-ef43-c235-8b4bd4430cf4.png)

W5500とハブを接続して、ハブとLTEルーターを接続します。
ハブにはラズベリーパイを接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/a5910023-903f-af28-d572-0778a70dfedd.png)

この状態でルーターの電源を入れると、Node-REDでMQTTの受信を行なうことができます。
MQTTによる通信を確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/0a23b0d2-30ba-8526-81a5-f2e69e85c647.png)


## 結果と考察と感想
LTEルーターとハブを介して、ESP32からethernetでMQTTの送受信を行うことができました。
最初に少しだけ設定を行なえば、実際に通信を行なうことは難しくないです。
今後の展開として現場（農地）で使用する予定にしていますので、現地での動作確認についても続報を出していく予定です。

## 参考情報
Node-RED公式情報　https://nodered.jp/docs/getting-started/raspberrypi  
さくらセキュアモバイルコネクト　https://iot.sakura.ad.jp/sim/flow/  
MQTTについて調べたのでまとめました https://qiita.com/shinfrom/items/5d3a464bd10ad0db2b68
enebular https://www.enebular.com/ja/