なりすまし・フィッシングメール・偽サイトにご注意ください

さくらのIoT

「さくらのIoT」のエンジニアが取り組んだ事例をご紹介します。LTEモジュールとさくらのクラウドを使って双方向の通信を行う開発サンプルです。WebブラウザからLTE回線を通して赤外線リモコンを操作したり、センサーデータをグラフ表示できます。例えばスマートホームなどでよく見かけるようになったアプリケーションを介して、その他の家電と連携するようなスマートリモコンを開発したいケースで参考にしていただければと思います。

赤外線リモコンを操作し
センサーデータをグラフ表示

具体的にはLTEモジュール(nRF9160)の開発やクラウドサーバとの意思疎通の方法を理解することでIoT機器の開発に応用することができます。LTEモジュールとサーバ間は「さくらのモノプラットフォーム」を利用しますので、ネットワークやLTE通信の仕組みを知らなくてもデータの送受信が行えます。

免責事項

試作品ですので、本内容をご利用に当たり以下の内容はご承知おき下さい。

  • いかなる場合も、当社は一切の損害賠償を支払わないものとします
  • 作成例ですので、この内容を製品化をすることはお止め下さい

また、当社の「本サイトご利用にあたって」も御覧ください。

動作環境

主に以下の環境で動作確認が取れておりますので、事前にご準備ください。

  • Windows10
  • Nordic nRF Connect SDK 1.7.1

概要図

ハードウェア

nRF9160を中心に、CO2センサー、照度センサー、学習赤外線リモコン、USB-UART変換基板、SWDコネクタ、電源が接続されています。回路図とガーバーファイルはGitHubで公開しており、コピー利用、配布、変更を加えたものの再配布、商用利用、有料販売など、どなたも自由にお使いいただくことができます。
Github monoplatform_nrf9160-ltem1rc

ブロック図

製作したプリント基板

PCB

回路図

LTEモジュール(nRF9160)

LTEモジュールは「開発キットお申し込み」より提供しています。nRF9160はNordic社のcat.M1及びNB-IoTのLTEカテゴリで通信できるLTEモジュールです。cat.M1は従来のLTEカテゴリのモジュールよりも通信速度は低速ですが低消費電力という特徴があります。nRF9160の最大の特徴は他の多くのLTEモジュールと異なり、内部のファームウェアを独自に開発することが前提になっているところです。逆にnRF9160はファームウェアの開発なしでは全く通信できないLTEモジュールといえます。
ほとんどのLTEモジュールがATコマンドベースでTCP/IPやその他のプロトコルで通信する機能を備えていますが、nRF9160はSDKとライブラリを利用してこれらの通信を行うファームウェアを独自に開発しなければなりません。Raspberry Pi等のリッチな動作環境からLTE通信だけを利用する用途には向いていない一方で、nRF9160とその周辺回路だけで完結できるハードウェアであれば大変安価に済ませることができます。「さくらのモノプラットフォーム」はnRF9160を使いとりあえず動かしてみることを目的としたサンプルファームウェアと、機能ごとに切り出したライブラリを「開発者向け情報」で公開していますので、いちから全てのプログラムを作成せずに開発を始めることができます。

電源

nRF9160の主電源は3.3V~5Vまで対応しています。主電源とは別にIO電源を入力する必要があり、こちらは1.8V~3.3Vまでとなっています。このLTE赤外線リモコンセンサーはnRF9160に主電源の5Vと、IO電源の3.3Vを供給しています。

CO2センサー

Sensirion社のCO2センサー(+温度・湿度)、SCD40のモジュール基板をI2Cバスで接続しています。
販売元:株式会社スイッチサイエンス Conta™ CO2センサ SCD40搭載
https://www.switch-science.com/products/7169/

照度センサー

AMS社の照度センサー、TSL25721のモジュール基板をI2Cバスで接続しています。
販売元:株式会社秋月電子通商 TSL25721使用 照度センサーモジュール
https://akizukidenshi.com/catalog/g/gK-15536/

学習赤外線リモコン

ビット・トレード・ワン社の学習赤外線リモコン基板をnRF9160のIOポートに6ch接続しています。学習赤外線リモコンはテレビや照明、エアコンの赤外線をパターンを学習して再現する機能があります。
販売元:株式会社ビット・トレード・ワン ラズベリー・パイ専用 学習リモコン基板
https://bit-trade-one.co.jp/product/module/adrsir/

USB-UART変換基板

nRF9160のデバッグ用にUSB-UART変換基板を接続してあります。
販売元:株式会社秋月電子通商 FT231X USBシリアル変換モジュール
https://akizukidenshi.com/catalog/g/gK-06894/

SWDインターフェース

nRF9160にファームウェアを書き込むにはJ-LINKが必要です。
SEGGER J-LINK
https://www.segger.com/products/debug-probes/j-link/

nRF9160のファームウェア開発

開発環境の準備(SDKのインストール)

nRF9160のファームウェア開発は専用のSDK(無償)を利用します。TCP/IPやHTTPといった通信プロトコル等のサンプルやコンパイラ一式が提供されています。LTE赤外線リモコンのファームウェアはさくらのモノプラットフォームのnRF9160サンプルファームウェアを改変して開発します。さくらのモノプラットフォームのnRF9160サンプルファームウェアはnRF Connect SDK v1.7.1に対応しています。
Github sipf-std-client_nrf9160
nRF9160のSDKを入手するため、Nordic社のnRF Connectをインストール後、Toolchain Managerをインストールし、nRF Connect SDKをインストールします。
nRF Connect for Desktop

nRF Connect for DesktopのToolchain Manger をインストールします。

次にToolchain MangerのnRF Connect SDK v1.7.1をインストールしますが、バージョンが古いため表示されません。SETTINGSタブのShow only 3 newest minor versionsのボタンを押して古いバージョンを表示させます。ソースコードがSDKのバージョンに依存しているところがあるため、モノプラのサンプルファームウェアはv1.7.1でコンパイルしてください。

SDK ENVIRONMENTSタブでnRF Connect SDK v1.7.1をインストールします。

Toolchain Mangerの通信がファイアウォールで弾かれないようにしてください。インストール中にネット接続が中断してもインストールが完了したことになる場合があります。インストール完了後のSDKのディレクトリはこのようになっていることを確認してください。

コマンドラインツールのインストール

コマンドラインからファームウェアの書き込みを行うため、コマンドラインツールをインストールします。パスを反映するためインストール後は必ず再起動してください。

モノプラサンプルファームウェアのコンパイル

nRF9160用のモノプラサンプルファームウェアをコンパイルするため、Toolchain MangerのnRF Connect SDK v1.7.1からOpen bashをクリックしてコンソールを立ち上げます。

Bash上でソースコードディレクトに移動して次のシェルスクリプトを実行します。

$ ./build.sh production

※ productionのオプションを外してしまうと通信できないので注意してください。通信先が見つからずUARTには通信エラーが出力されます。

コンパイルに成功すると最終行に

Generating zephyr/merged.hex

というメッセージが出ます。このmerged.hexファイルをnRF9160に書き込みます。merged.hexファイルをProgrammerで書き込むこともできます。

※ 生成されたフォルダ階層の例

C:\username\sipf-std-client_nrf9160-ltemrc\build\scm-ltemnrf_nrf9160ns\production\zephyr\merged.hex

コンパイル後にnRF9160への書き込みまで自動で行う場合は次のシェルスクリプトを実行します。コンパイル完了後にJ-LINKを通してnRF9160にファームウェアの書込が開始されます。

$ ./flash.sh production

モノプラサンプルファームウェアが想定通りにコンパイルできていることを確認してからソースコードの改変を行ってください。コンパイルに成功して書き込みも問題ない場合、UARTには次のようなブートメッセージが表示されます。

LTE赤外線リモコンのソースコード

LTE赤外線リモコンのソースコードはこちらです。
Github monoplatform_nrf9160-ltem1rc
モノプラットフォームサンプルコードとの違いは次の通りです。

  • IOピン設定の変更 【scm-ltem1nrf_nrf9160_common.dts】
    • I2Cデバイスドライバの有効設定 【scm-ltem1nrf_nrf9160ns_defconfig】
    • I2Cマスター制御用関数の追加 【main.c】
    • センサーデータの収集とLTE送信機能を追加【main.c】
  • LTE受信と赤外線リモコンの制御機能を追加【main.c】

IOピン設定の変更

nRF9160のIOピンやペリフェラルの割当はソースの以下階層に存在するdtsファイルで変更しています。

monoplatform_nrf9160-ltem1rc\boards\arm\scm-ltem1nrf_nrf9160\scm-ltem1nrf_nrf9160_common.dts

I2Cデバイスドライバの有効設定

ソースの以下階層に存在するコンフィグファイルを編集し、I2Cデバイスドライバが有効になるよう変更しています。

monoplatform_nrf9160-ltem1rc\boards\arm\scm-ltem1nrf_nrf9160\scm-ltem1nrf_nrf9160ns_defconfig
# Enable i2c driver
CONFIG_I2C=y

メイン関数に処理を追加

各関数や機能の追加

ソースの以下階層に存在するmain.cファイルを編集し、以下のコードを追加しています。

monoplatform_nrf9160-ltem1rc\src\main.c

CO2センサーと照度センサーからI2Cバスでデータを読み書きする関数と、それらのデータを送出するコードを追加します。モノプラのサーバにデータがあるかどうか問い合わせて、データがあった場合は受信して赤外線リモコンを制御するコードを追加します。

  • I2Cバス用の関数
  • CO2センサーセットアップ
  • 照度センサーセットアップ
  • センサー値の取り込み
  • サーバにデータ送信
  • 赤外線リモコンを制御

これにより、CO2センサーと照度センサーからI2Cパスでデータを読み書き/送出したり、モノプラに自身宛のデータがあるかを問い合わせ、データがあった場合は受信して赤外線リモコンを制御するようになっています。

SIMとモノプラットフォームの準備

LTEモジュールがLTE回線に接続し、モノプラットフォームと通信するためには三つの登録作業が必要になります。

  • モノプラットフォームにプロジェクトを追加する
  • サービスアダプタを追加する
  • セキュアモバイルコネクトにSIMを登録する

モノプラットフォームにプロジェクトを追加する

プロジェクトはデバイスをSIMの単位でまとめてモノプラットフォームに接続するための機能です。モノプラットフォームのプロジェクト画面から、右上の追加ボタンを押してプロジェクトを作成します。

仮に名前は開発用説明にリモコン基板サンプルとして右下の作成ボタンを押します。

作成が成功するとプロジェクト一覧に開発用というプロジェクトができます。

サービスアダプタを追加する

サービスアダプタはモノプラットフォームと外部のインターフェースを定義する機能です。先に作ったプロジェクト毎に作成します。モノプラットフォームのサービスアダプタ画面から、右上の追加ボタンを押してサービスアダプタを作成します。

名前は仮にwebsocketとします。プロジェクトのプルダウンメニューから先に作ったプロジェクトを選択します。サービスアダプタはwebsocketを選択して、右下の作成ボタンを押します。

作成に成功すると、websoketというサービスアダプタができます。

ICCIDとPASSCODEはLTEモジュールの裏面に貼ってあります。

接続先はモノプラットフォームを選択します。
プロジェクトは先に作った開発用を選択します。
名前は仮にリモコン基板用LTEモジュールとします。
右上の作成ボタンを押します。

SIMの一覧にリモコン基板用LTEモジュールが追加されたことを確認します。

クラウドサーバの準備

さくらのクラウドにサーバを用意して、Node-REDをインストールします。サーバを用意します。右上の追加ボタンを押します。

サーバプランはデフォルトの最小構成とします。

ディスクはアーカイブ選択からCentOS 7.9 (2009) 64bitを選択します。

ディスクの修正は複数箇所の設定が必要です。管理ユーザーのパスワードに十分な強度のパスワードを設定します。配置するスタートアップスクリプトはNode-REDを選択します。Node-REDのログインIDとパスワードを設定します。ポート番号は任意ですが80番以外を設定した場合はメモを取っておきます。デフォルトは1880です。

シンプル監視はデフォルトのままとします。サーバーの情報は、名前を仮にNode-RED用サーバとします。その他のオプション、作成数はデフォルトのままとします。最後に右下の作成ボタンを押してサーバの作成が開始されます。

サーバ一覧からIPアドレスをメモしておきます。

作成には5分程度時間が掛かります。Node-RED用サーバからコンソールタブを開き、localhost login: が表示されていれば準備完了です。

作成したサーバのIPアドレスに:1880を付けてWebブラウザからアクセスするとNode-REDのログイン画面が表示されます。

ログインすると次のような設計画面が表示されるはずです。

Node-REDのサンプルフロー

設計画面上でこのようにノードをつなげることでグラフの描画やボタンなどを配置することができます。Node-REDでモノプラットフォームと通信する方法を把握するためのサンプルを導入します。

サンプルフローの取り込み

右上のハンバーガーボタンから、パレットの管理を選択します。

Node-RED-dashboardを検察窓に入力。Node-RED-dashboardの"ノードを追加"を押してインストールします。

Node-RED-contrib-ui-artless-gaugeの"ノードを追加"を押してインストールします。

次にJSON形式のフローデータを読み込みます。画面右上のハンバーガーボタンより、読み込みをクリック。

Githubのリポジトリ内のflows.jsonファイルを読み込みます。

monoplatform_nrf9160-ltem1rc/tree/main/Node-RED/flows.json

読み込みが成功していれば、画面上に作成済みのノードが表示されます。

モノプラットフォームのサービスアダプタより、wss://から始まるWebSoketのURLをコピーします。

Node-REDの情報タブから、グローバル設定ノード↓ websocket-cliantのwss://から始まるノードをダブルクリックして、プロパティタブのURLに先ほどコピーしたwebsoketのURLを貼り付けて更新します。

モノプラットフォームのプロジェクトから、データを送受信するデバイスのIDをコピーします。例として31031。

Node-REDのswitchノードにデバイスIDを記入して完了します。

SW1~SW6の各ノードのpayloadにデバイスIDを置き換えて記入します。

{"device_id":"デバイスID","type":"object","payload":[{"type":"uint32","tag":"11","value":170}]}
{"device_id":"デバイスID","type":"object","payload":[{"type":"uint32","tag":"22","value":170}]}
{"device_id":"デバイスID","type":"object","payload":[{"type":"uint32","tag":"33","value":170}]}
{"device_id":"デバイスID","type":"object","payload":[{"type":"uint32","tag":"44","value":170}]}
{"device_id":"デバイスID","type":"object","payload":[{"type":"uint32","tag":"55","value":170}]}
{"device_id":"デバイスID","type":"object","payload":[{"type":"uint32","tag":"66","value":170}]}

Node-REDの設計画面右上のデプロイボタンを押して完成です。LTEモジュールからデータが届いていれば、画面右側のデバッグタブにwebsoketに入力された値が表示されます。

サーバのIPアドレスにuiを付けたURLにアクセスすると、ダッシュボード画面が表示されます。

http://サーバのIPアドレス/ui

Websocketから出力されるjson形式のデータ構造

nRF9160のサンプルプログラムは60秒に1回、センサーデータを送信しています。1度の送信で4つデータを送ります。

形式/タグ/値

32bit整数型/01/co2の値
32bit浮動小数型/02/温度の値
32bit浮動小数型/03/湿度の値
32bit浮動小数型/04/照度の値

nRF9160から送られてきたデータを、モノプラットフォームはwebsoketから次のようなjson形式の文字列で出力します。

{
    "id": "cdcce6df-41a1-4d9f-983b-91ff167927d4", //送受信毎のID
    "device_id": "31031", //デバイスID
    "timestamp_src": "1970-01-01T00:00:00.000Z", //デバイスのタイムスタンプ
    "timestamp_platform_from_src": "2022-10-28T06:04:39.416Z",
    //プラットフォームに到着した時点のタイムスタンプ
    "timestamp_platform_to_dst": "2022-10-28T06:04:39.552Z",
    //プラットフォームが出力する時点のタイムスタンプ
    "type": "object",
    "payload": [{ //以下ペイロード
        "type": "uint32",
        "tag": "01",
        "value": 678 //1個目のオブジェクト
    }, {
        "type": "float32",
        "tag": "02",
        "value": 22.529945 //2個目のオブジェクト
    }, {
        "type": "float32",
        "tag": "03",
        "value": 51.821163 //3個目のオブジェクト
    }, {
        "type": "float32",
        "tag": "04",
        "value": 37.68421 //4個目のオブジェクト
    }]
}

送信毎に付与されるID、LTEモジュール毎に付与されるデバイスID、タイムスタンプ、ペイロードとなります。ペイロードの内容ははnRF9160のサンプルプログラムで作成した値です。

Node-REDのフローについて

ダッシュボードにグラフを描画するフローは次のような順番でJSONデータを処理しています。緑のノードはデバッグ用で、有効にするとデバッグタブにそのノードが受信したメッセージを表示します。

  1. websoketのデータを受信 (websocket inノード)
  2. JSON文字列をObjectに変換 (string→Objectノード)
  3. 特定のデバイスIDのデータを抽出 (switchノード)
  4. ペイロードの順番毎にCO2/温度/湿度/明るさを抽出。(functionノード)
  5. 値を丸めて描画 (gaugeノード/chartノード)

赤外線リモコンの操作ボタンは、buttonノード内でjson形式の文字列を直接生成してwebsoket outノードに渡しています。

{"device_id":"デバイスID","type":"object","payload":[{"type":"型","tag":"タグ","value":数値}]}

Node-REDのセキュリティ

Node-REDのダッシュボードはパスワードが一切かかっていないため、サーバのIPアドレスが分かれば誰でもアクセスできてしまいます。簡易的にパスワードを設定するには、Node-REDの設定ファイルを編集する必要があります。

サーバにSSHでログイン

  • WindowsであればPowershellを起動
  • ssh root@***,***,***,***
    ←作成したNode-REDサーバのIPアドレスを入力
  • パスワードを入力してログインする

パスワードのハッシュ値を生成

  • [root@localhost ~]# node-red admin hash-pw
    <-実行
  • 設定したいパスワードを入力する
  • 生成されたハッシュ値をコピーする
    例:
    $2b$08$7oIrXCCGFbLOqILdiC74ce0QGr32RNmUts.7E7akxlkGS7IICv/zG,/

Node-REDのsetting.jsを編集する

[root@localhost ~]# vi /root/.sacloud-api/notes/root/settings.js
←setting.jsonファイルを開く。

次の2行のコメントアウトを解除して、"user"をログイン名、pass:"**********"を前項で作成したハッシュ値を貼り付けて保存します。

//httpNodeAuth: {user:"user",pass:"$2b$08$LyNdwvKd6MX5zcYOBOc.xO1Ury6vuQPzNfwCXaP9YavDi/KbiS/R6"},
//httpStaticAuth: {user:"user",pass:"$2b$08$LyNdwvKd6MX5zcYOBOc.xO1Ury6vuQPzNfwCXaP9YavDi/KbiS/R6"},
  ↓
httpNodeAuth: {user:"ユーザー名",pass:"hash-pwで生成された文字列"},
httpStaticAuth: {user:"ユーザー名",pass:"hash-pwで生成された文字列"},

保存後にサーバを再起動します。

http://サーバのIPアドレス/ui
にアクセスしてユーザー名とパスワードが要求されることを確認します。

パスワードはハッシュ値の生成に使用した文字列です。

動作確認

データの受信

Node-REDのダッシュボードにアクセスします。

http://サーバのIPアドレス/ui

データ受信前はグラフにはなにも表示されません。

データを受信することで、グラフの描画が始まります。また左側のゲージに現在の値が表示されます。

学習赤外線リモコンと照度センサーの動作確認

学習赤外線リモコンの使って室内の照明を入り切りする準備をします。制御対象はコイズミ照明 LEDシーリングライトAH51219です。

学習赤外線リモコンのスライドスイッチをLEARNに切り替えて、記憶させたいスイッチを押しながらリモコンを受光部に向けてボタンを押します。今回はSW1に照明OFF、SW6に照明ONを割り当ててあります。

ダッシュボード上の照明ON・照明OFFのボタンを押すことで明るさのパラメータが上下することを確認できます。

CO2センサーの動作確認

次に、ガスファンヒーターを動かすことでCO2濃度が変化することを確かめます。CO2濃度の上昇とともに気温が上昇し湿度は減少します。換気することでCO2濃度は大きく下がり、室温も湿度も元の水準まで戻ります。

まとめ

今回は、「さくらのモノプラットフォーム」開発キットに含まれるLTEモジュールと「さくらのクラウド」のサーバーを利用して、センサーデータのグラフ化と赤外線リモコンによる制御のサンプルを作成しました。LTEモジュールとサーバー間は「さくらのモノプラットフォーム」を介して行うため、「通信方式」「プロトコル」「データ形式」といった要素の組み合わせをイチから考えることなく開発を進めることができます。また、通信回線は「さくらのセキュアモバイルコネクト」と組み合わせることでインターネットに出ない安全な構成を実現できるため、未来の家電製品や様々なモノの通信に応用できるサービスになっています。IoTシステム構築をご検討の際にはぜひご覧いただければ幸いです。

2022年12月公開