1.全体構想と所要機能
開発するIoTゲートウェイ(以下は簡単にゲートウェイ)は、複数のブロードキャスターから計測データを受信して、それをホストに送信する仲介役を担うものです。最終的には複数のゲートウェイがホストと接続されて、多数のブロードキャスターからの計測データを受信し、利用しやすい形で記録することになります。概ね下図のようなシステムの構築を想定しています。
(1)ホストの所要機能
ホストとしてRaspberry Piを使用します。図ではPi3 Model B+になっていますが、Wi-Fiが動作すれば何を使っても問題ありません。MySQL(MariaDB)をインストールしてデータベースサーバーを構築しますが、これらについては次回以降のテーマになります。
複数センサー、複数デバイス、複数ステーション(ゲートウェイ)からのデータ収集を可能にするため、計測データはすべてデータベースに記録します。同時にホストの時計から日時を取得して、これを計測日時とします。データベースに記録することで、必要に応じて任意の条件でデータを抽出したりソートすることができるので、活用範囲が広がります。
なお、ゲートウェイからのクエリーを受信して内容の解析とデータベース登録を行うために、スクリプト言語としてPHP7を使用します。
(2)ゲートウェイの所要機能
すでに作成済みのBLEObserverに、ホスト通信のためのWi-Fi機能を追加します。データベースサーバーにWi-Fi接続する形態の、ベーシックなクライアントとして動作させます。
ブロードキャスターからの計測データ受信と連動してクエリーを組み立てて、ホスト宛にHTMLリクエストのGETメソッドで送信します。これと合わせて、ブロードキャスターをリセットした時にまれに発生する異常データに対応して、フィルタリング機能を持たせます。
(3)ブロードキャスター(センサーデバイス)の所要機能
作成済みのBLEBroadcasterをそのまま使用できるのですが、その後のテストで、ウォッチドッグタイマー(WDT)割り込みによるシステムリセットの発生が認められました。これを回避するために、テスト用に組み込んだ異常発生用プッシュボタン操作によるGPIOのアクセスを取りやめると共に、WDTのリセット処理を追加します。
2.システム構築の課題
課題というよりも「あらかじめ解決すべき事項」あるいは「問題点」と言った方が適切かも知れません。先に述べたブロードキャスターでまれに発生する異常データや、ウォッチドッグタイマーに端を発するシステムリセットの問題、さらにメモリー不足の発生など、解決しなければ前進できない問題と対策を整理しておきます。
①異常データの発生
繰り返しになりますが、ブロードキャスターリセット時にまれに発生する異常データの問題です。不意な電源のON/OFFによって発生するもので、次のような値のデータが発生します。
・シーケンス番号 0
・温度計測値 655.35
・湿度計測値 655.35
対策として、ゲートウェイで計測データを受信時に、次の条件でフィルタリングすることにします。
「シーケンス番号がゼロで、温度または湿度の計測値が100を超えていれば無効データとする」
②ウォッチドッグタイマーによるシステムリセットの発生
BLEObserverの受信データを精査すると、かなりの頻度でシーケンス番号がゼロにリセットされていることに気付きました。BLEBroadcasterのシリアルモニターを見ると、本来のディープスリープからの復帰である「DEEPSLEEP_RESET」割り込み以外に、「TG1WDT_SYS_RESET」割り込みが発生していることがわかります。
# Add following 4 lines for fixed ip_address setting. 2018/01/20 rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) <=== 通常の復帰 configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:1100 load:0x40078000,len:9232 load:0x40080400,len:6412 entry 0x400806a8 *** Seq-No. 12 *** Advertising started! ... in deep sleep! ets Jun 8 2016 00:22:57 rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) <=== ★これが問題! configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:1100 load:0x40078000,len:9232 load:0x40080400,len:6412 entry 0x400806a8 *** Seq-No. 0 *** <--- シーケンス番号がゼロにリセットされている Advertising started! ... in deep sleep! ets Jun 8 2016 00:22:57 rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) <=== 通常の復帰 configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:1100 load:0x40078000,len:9232 load:0x40080400,len:6412 entry 0x400806a8 *** Seq-No. 1 *** Advertising started! |
③メモリー不足の発生
BLEObserver.inoにヘッダーファイルWiFi.hのインクルードを追加し、簡単なロジックを記述してコンパイルすると、「スケッチが大きすぎます」エラーが発生しました。1,310,720bytesのプログラム用フラッシュメモリーに対して、コンパイル結果の所要メモリーが113%になっています。
対応方法を調べていたら、Asuki Konoさんのサイト『ESP32-WROOM032のプログラム領域が足りなくなった時に、パーティションの設定を変更して領域を増やす方法』に、大変参考になる情報が掲載されていました。
いくつかの方法が紹介されているのですが、PlatformIOという開発環境を導入すると独自のパーティション設定ができるのが魅力で、即、PlatformIOを導入することにしました。
また、PlatformIOを導入した後、強力なエディターVisual Studio Code (VSCode)があり、PlatformIOをプラグインサポートしていることをKERI's Lab『PlatformIOでESP32の開発をしよう』で知り、これも導入することにしました。VSCodeの雰囲気は電気通信大学のMedia Design Labサイトも参考にさせていただきました。
PlatformIOとVSCodeの組み合わせはとても良好で、これからの開発に欠かせない環境になりました。
3.開発環境PlatformIOの導入
PlatformIOは大変ユニークなソフトウェアです。Pythonで書かれていて(2019/05時点ではPython 2.7)、GCC(GNU Complile Collection)のコンパイル環境を、OSやボードに合わせて自動生成してくれます。550種類に上る組み込みボード、30種類以上の開発プラットフォームに対応すると謳っていて、WindowsでもMacでも、LinuxやFreeBSDでも利用できるという幅の広さです。
現時点ではPython 3をサポートしていないので、PlatformIOの導入に先立って、まずPython 2.7をインストールする必要があります。これに続く一連のインストールはPlatformIO Installationに詳しく説明されています。
Windows環境でのインストールは次の通りです。
・https://www.python.org/downloads/を開く。
・Python 2.7.~の[Download]リンクをクリックする。
・Filles一覧から「Windows x86-64 MSI installer」をクリックする(Windows 64bit機の場合)。
・ダウンロードされた「python-2.7.16.amd64.msi」を実行する。
ここではC:\ArduinoIDE\PlatformIOというディレクトリを作成してpython-2.7.16.amd64.msiを格納して
います。実行すると、同じディレクトリー内にget-platformio.pyが現れます。
・pythonでget-platformio.pyを実行する。
上図の「==> Installing PlatformIO and dependencies ...」に続く「Collecting platformio」の部分は表示を切り詰めていますが、実際はさらに多数のパッケージがダウンロード・インストールされます。
これでPlatformIOのインストールは完了し、引き続きVisual Studio Codeをインストールします。
4.Visual Studio Codeの導入
Visual Studio Code(VSCode)は、マイクロソフトによって開発されたソースコードエディターです。Windows、Linux、macOS上で軽快に動作します。
まず、次のリンクからダウンロードサイトを開きます。
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
続いてターゲットを選択します。ここでは、WindowsのUser Installer 64bitを選択しました。
ダウンロードされたVSCodeUserSetup-x64-1.33.1.exeを実行します。いくつもダイアログが表示されますが、すべてそのままで[次へ]ボタンをクリックします。インストールが完了すると「Visual Studio Code」画面が表示されます。
続いてPlatformIOを導入します。左に表示されている下から2番目の箱形アイコン(Extentions)をクリックして、検索ボックスにplatformioを入力します。直下に表示される候補一覧から、一番上の「PlatformIO IDE」をインストールします。緑色の[Install]ボタンをクリックすると即完了です。
5.ブロードキャスターの調整
インストールが完了してリロードすると、PlatformIOのメイン画面が表示されます。画面右の[+ New Project]ボタンをクリックしてプロジェクトを登録します。
まず、プロジェクト名を設定します。開発済みのBLEBroadcaster.inoを調整して仕上げるので、プロジェクト名はBLEBroadcasterとしました。
次に開発ボードを指定します。647種類もありますが、Board:のテキストボックスに「ESP32」と入力すると、リストボックスが開いてESP32ボードの一覧が表示されます。
対象のボードを選択すると、Framework:が「Arduino」に自動設定されます。Location:は、「Use default location」をチェックしたままにすると、プロジェクトはユーザーフォルダーの\ドキュメント\PlatformIO\Projects配下に作成されます。最後に[Finish]ボタンをクリックします。進行画面が表示されて、しばらくするとプロジェクトが完成します。
リロードすると、PlatformIOのメイン画面が表示されます。画面左の一番上のExplorerアイコンをクリックすると、アイコン右の「UNTITLED (WORKSPACE)」にBLEBroadcasterが表示されています。左端の三角マークをクリックして展開すると、BLEBroadcasterプロジェクトの構成要素が現れます。これは、先の\PlatformIO\Projects配下に作成されたフォルダーやファイルと対応していて、それらが簡単にハンドリングできるようになっています。
実にたくさんのフォルダーやファイルが作成されますが、開発に関係深いものをピックアップしておきましょう。
○include
プロジェクトのC/C++プログラムから#include "~.h"文でインクルードするファイルを格納。
○lib
プロジェクトで使用するライブラリーを格納。
○src
プロジェクトを構成するC/C++ソースプログラムを格納。あらかじめmain.cppが存在。
○platformio.ini
プロジェクト・コンフィギュレーション(構成)・ファイルです。
platform, board, frameworkなどが設定されていて、monitor_speedや使用するCOMポートなどを指定。
srcを展開するとmain.cppが現れて、それをフォーカスすると、右のエディター画面にmain.cppのコードが表示されます。Arduino IDEでおなじみのvoid setup()とvoid loop()のひな形ですが、先頭行に<Arduino.h>がインクルードされています。VSCodeでArduino IDEを使用する場合は、これが必要であることに注意してください。
次に、BLEBroadcasterプロジェクトの一番下にあるplatformio.iniにフォーカスしてみます。エディター画面で分かるように、これはプロジェクトコンフィギュレーションのファイルです。プラットフォーム、対象ボード、フレームワークなどがすでに設定されています。
プロジェクトごとにコンフィギュレーションを設定できるのはとても便利です。シリアルモニターとの通信速度、使用するCOMポートを設定しておきましょう。後でも述べますが、ここでCOMポートを設定しておくと、アップロード時にボード選択やボード側のボタン操作をしなくてもそのポートにアップされます。
次に、main.cppを編集しましょう。Arduino IDEやテキストエディターなどで開発済みのBLEBroadcaster.inoを開いて、コピー&ペーストでVSCodeのエディターに貼り付けます。下の画面では、#include <Arduino.h>の位置をコメントの下に移動しています。
左のEXPLORER欄のmain.cppが赤色に変わり、これをマウスでポイントすると「~~main.cpp・2 problems in the file」と表示され、コードの23行目に赤の波下線が見えます。
これは、DHTセンサー関係のライブラリーが設定されていないのが原因です。以前にダウンロードしたAdafruit_SensorとDHT-sensor-libraryの2つのフォルダーを、BLEBroadcasterプロジェクトのlibフォルダーにコピーします。
いよいよmain.cppの変更です。主目的は、データの計測タイミングのズレや脱落を防ぐために、BLEBroadcasterのロジックを徹底的にスリム化することです。当面は不要な異常発生の仕組みやモニター表示などを削除します。そして、ウォッチドッグタイマー割り込みを抑制するコードを追加します。変更点は以下の通りです。
①インクルードファイルの追加
Watchdog timerの制御のために、次のインクルードを追加します。
#include <esp_int_wdt.h>
②bool bAbnormalに初期値を設定
デバイスの状態が常時正常になるように初期値を設定します。
bool bAbnormal = false;
③デバイス異常判定ロジックの削除
これに関するすべてのコードを削除します。
④外部ウェイクアップ設定の削除
プッシュボタンによる割り込みが不要になることから、
esp_sleep_enable_ext0_wakeup(GPIO_NUM_32, 1); を削除します。
⑤Watchdog timerのリセット
外部ウェイクアップの直後に、ウォッチドッグタイマーのリセットコードを追加します。
esp_int_wdt_init();
delay(10);
⑥ファンクションのプロトタイプ定義
新しい開発環境ではC++のシンタックスチェックがより厳密になります。このため、25~27行に見るように、関数のプロトタイプ宣言を追加しています。
VSCodeでのコンパイルとアップロードは、画面下のタスクバーのアイコンで簡単に操作できます。②チェックマークでビルドを行い、③の矢印をクリックすればアップロードできます。④のプラグをクリックすると起動して、シリアルモニターにSerial.print()の内容を表示させながら実行状況を確認することができます。
なお、アップロードに際してボード上のスイッチ操作はまったく必要ありません。これは開発のストレスを軽減してくれるので嬉しいですね。
※ 改訂版BLEブロードキャスターは、ページ先頭の[Download]ボタンでダウンロードしてください。
6.ホストの準備
すでにOSをインストール済みであれば、「Raspberry Piへの追加インストール」までスキップしてください。
ここでは、Raspberry Piに最新のRaspbian Stretch(2019-04-08版)をインストールした状況を、自身のためのメモ程度に略記しておきます。このOSはほとんど説明が不要なほど簡単にインストールできるので、特に問題はないと思います。
①最新バージョンのデスクトップ・フルバージョンをダウンロードする。
・ダウンロードサイト
・Target: Raspbian Stretch with desktop and recommended software
[Download ZIP]
・Version: April 2019
・Release date: 2019-04-08
・Kernel version: 4.14
⇒ これで2019-04-08-raspbian-stretch-full.zip がダウンロードされる。
②SDカードへの焼き付け
2019-04-08-raspbian-stretch-full.zipを解凍してできる次のファイルをSDカードに焼き付ける。
2019-04-08-raspbian-stretch-full.img
③Raspberry Pi側でのインストール
Raspberry Pi 3 Model Bにキーボード、ディスプレイ、マウスをつないでSDカードをセット。
電源を入れる。
少し待つと〔Welcome to Raspverry Pi〕ダイアログが開いてセットアップ情報入力が始まる。
これが大変良くできていて、順序を追って入力することでOSインストールが完了する。
以下はダイアログでの入力情報の覚え書きです。
○Set Countryダイアログ
・Country: [Japan]を選択すると以下が決まる。
・Language: Japanese
・Timezone: Tokyo
○Change Passwordダイアログ
・Enter new password: ******
・Confirm new password: ******
○Set Up Screenダイアログ
The desktop should fill the entire screen.
Tick the box below if your screen has a black border at the edges.
□ The screen shows a black border around the desktop.
↑ (No check!)
○Select WiFi Networkダイアログ
Select your WiFi network from the list.
表示されたリストから該当するものを選択する。
○Enter WiFi Passwordダイアログ
・Password: *************
○Update Softwareダイアログ
The operation system and applications will now be cheked and updated if necessary.
This may invoke a large download.
-- please wait.
○Setup Completeダイアログ
[Restart] buttonをクリックする。
リスタート後に次のネット接続が完了している。
eth0: Configure 192.168.***.***/24
wlan0: Associated with ~~~
wlan0: Configure 192.168.***.***/24
○Windowsパソコンから Poderosaと VNC Viewerで接続できるようにする
[設定]-[Raspberry Piの設定]を選択し、「インターフェイス」タブを開いて
SSH
VNC
を 有効(Enable)にして[OK]をクリック。
[Shutdown...]-[Reboot]を選択する。
■Raspberry Piへの追加インストール
すでに掲載済みの『Raspberry Pi 3 Model Bに「Raspbian Stretch」をインストールしてみた(2018/02/26)』に沿って、
・Apach2、PHP7、php-mysql、MySQL/MariaDBと phpMyAdminをインストールします。
・続いて、FTPサーバーとSAMBAサーバーを構築します。
以上です。次回は、メモリーパティションを変更してゲートウェイプログラムを開発する予定です。
お楽しみに!