1. はじめに
Pico Bot を開発中です。Pico Botは、PukiWikiのページに書かれたスクリプトを定期的に読み、そのスクリプトを実行し、実行結果をPukiWikiに書き戻す、Raspberry Pi Pico W (Pico W)で作られたBotです。今回、Pico Bot で気温を計測し、その値をPukiWikiページに書き込むIoTシステムを作成しました。
2. 概要
Raspberry Pi Pico Wに温度計測のためのセンサ、AE-BME280、をI2Cで接続し、Pico Botのプログラムに、BME280のデータを読み込むためのモジュールを組み込み、Pico Bot が動作するWi-Fi環境のSSIDとパスフレーズ、Pico Bot が読み書きするPukiWikiページのURLなどを設定して、Pico Wに書き込みます。
この状態で Pico Bot を起動することにより、Pico BotがPukiWiki の指定されたページに書かれたスクリプトに従い、温度計測を行い、このページに計測結果を書き込みます。計測結果をグラフ表示するための、JavaScript も作成しました。
3. 動作環境例
例として、以下のような環境で動作させることにします。WikiサーバとPico WはローカルネットワークのWiFiに接続します。Wiki サーバをインターネットの上に置いて、Pico Botのプログラムに書き込むIPアドレスまたはFQDN等をそれに従って設定し直しても動きます。
4. エッジ(Pico Bot)の温度計測ハードウェア
秋月のボード、AE-BME280、のJ3を半田でブリッジ(ジャンプ?)し、I2Cの動作モードにします。
AE-BME280とPico Wをブレッドボードとジャンプワイヤを使って以下のように接続します。
上の図を描くために作ったAE-BME280のfritzingの部品:
AE-BME280.fzpz
5. エッジ(Pico Bot)のソフトウェア
Pico Bot のプログラムに、I2CでBME280 を利用するためのモジュールを加えたソースプログラム(main.py)を用意しました。
以下の手順に従って、Pico Botを4.で作成したハードウェアのPico Wに書き込みます。
5.1 Pico Wの開発環境の準備
ここでは、パソコン(PC)に、Visual Studio Code (VSCode)をインストールし、VSCodeの拡張機能として、MicroPico を導入したものを利用することを想定しています。また、4.のハードウェアで利用するPico Wには、すでにMicroPythonを実行するためのファームウェアが書き込まれていることを想定しています。VSCode, MicroPico, ファームウェアの書き込みについては、
IoT演習第2回、マイクロコントローラ
等を参考にしてください。
5.2 ソースプログラムのコピー
MicroPico が利用できるVSCodeがインストールされたPCを用意し、VSCodeの上でこのソースプログラムをmain.pyと名前をつけて保存します。
(2024 12/1, ntpを使って時間を得る部分に問題があったので修正しました)
5.3 ソースプログラムの修正
このソースプログラムの先頭近くにある以下の行は、3. の実行環境で動くように書いています。これを、実際に実行する環境に合わせて書き換えます。ここでinit_pageは、3. の図の Wiki Page URLです。init_pageは、3.の図のPageです。
init_url="http://192.168.8.237/pukiwiki/pico_wiki/"
init_page="bme280-01"
ssid="GL-SFT1200-8f4"
password="goodlife"
このプログラムの中でntpを使って現在の時間を得る部分があります。
上の、password=の次の行に、ntpサーバを指定している行があり、以下のようになっています。
ntp_host="ntp.nict.jp"
必要に応じてntp_host=の右辺を書き換えてください。
5.4 Pico Wの接続
USBケーブルでPC(VSCodeとその拡張機能としてMicroPico が利用できるもの)と、Pico Wを接続します。接続が成功したら、VSCodeの下の行に、接続されていなかった時の、Pico Disconnectedの表示が、Pico Connected に変わります。
5.5 Wiki ページの作成
順番が前後しますが、「6. Wikiページのスクリプト」に示す手順に従って、Pico Botが実行するスクリプトが書かれたWikiページを作成します。
5.6 テスト
5.3 が終わった時点で、編集したmain.py が選ばれている状態になっていると思います。この状態で、画面の下に表示されている、Run ボタンをクリックすると、main.py のPico Botのプログラムが実行されます。実行の経過がMicroPythonのREPのターミナルに表示されます。また、Wikiページに実行結果が書き込まれます。これらを見て、Pico Botの不具合があれば、それを修正します。なお、メモリー不足のエラーが発生した場合、一度、Pico Wを接続するUSBケーブルをPico Wから外し、もう一度接続するとメモリー不足のエラーが解消する場合があります。
5.7 Pico Wへ upload
VSCode の上のメニューの[View]>[Command Palette]>を選び、そこで表示されるプロンプトで、MicroPico:Upload current file to Pico (選択肢が補完されて表示されるので、それを選択)を入力し、実行します。
5.8 起動時の自動実行の設定
VSCode の上のメニューの[View]>[Command Palette]>を選び、そこで表示されるプロンプトで、MicroPico:Run current file on Pico (選択肢が補完されて表示されるので、それを選択)を入力し、実行します。
5.9 Pico Bot の起動
Pico WのUSBケーブルを抜き差しすることで、書き込んだPico Botのプログラムの実行が行われますが、その前に、次の6. Wikiページのスクリプトを用意しておきます。
6. Wikiページのスクリプト
「5.3 ソースプログラムの修正」で行った、URLにあるWikiページに、Pico Botが読み書きするためのスクリプトなどを記述します。3. の環境で動作させる場合、次の図のように記述します。
Pico Botが読み込むスクリプトと実行結果等は、PukiWiki のページの、(最初の)書式なしテキスト(pre defined)の領域で、薄い青色の背景で表されています。ソースエディタで、行の左端に半角の空白を入れることでこの領域を記述します。
以下をコピペして書き換えても良いです。
object_page http://192.168.8.237/pukiwiki/pico_wiki/?bme280-01 or http://192.168.8.237/pukiwiki/pico_wiki/?bme280-01
device yamaRasPiDp9_1 or yamaRasPiDp9_2 start after no write for 10 min.
command: set read_interval=300000
command: set exec_interval=0
command: set report_length=20
command: py test
py: #
py: from machine import Pin, I2C
py: import time
py: i2c= I2C(0, sda=Pin(0), scl=Pin(1), freq = 40000)
py: bme=BME280(i2c=i2c)
py: v=bme.values[0]
py: line="device=temp, Date="+self.Pico_Time.get_now()+", v="+v
py: self.write_line(line)
py: self.send_result()
command: end test
command: run test
result:
current_device="yama_pico_0000_0000_0000_0001". Date=2024/04/03 06:35:50
上の記述の中で、
object_page <URI-1> or <URI-2>
は、Pico Botが読み込むページ(このページ)のURI(URI-1)と、このページが障害発生などで使えない時の代替ページのURI(URI-2)を表しています。代替ページがない場合、同じURIを書きます。
device <device-1> or <device-2> start after no write for 10 min.
は、このページはの Pico Botが読み書きしますが、それが障害などで動かなくなった場合(結果を書かなくなった場合)、10分後に、のPico Botが読み書きを開始することを表します。しかしながら、現在、この機能は動いていません。
command: set read_interval=300000
は、Pico Botがこのページを読む間隔を5分(300000msec)にすることを表します。
command: set exec_interval=0
は、Pico Botがこのページを読んだ直後、一回、記述されたスクリプトを実行することを表します。0でない場合は、ページを読んだ後、ここに記述された間隔(単位はmsec)でスクリプトを繰り返し実行することを表します。
command: set report_length=20
は、resurt: の行より後に書かれた実行結果の行数の最大を20行にすることを表します。
command: py test
と
command: end test
は、
この間にある、py: で始まる行が MicroPythonのプログラムで、そのプログラムに、test という名前をつけていることを表しています。
command: run test
は、test という名前がついたプログラムを実行することを表しています。
result:
は、この行の後ろの行から、結果が書き込まれることを表します。
current_device="<device>". Date=<date-time>
は、このページに最後に書き込んだPico Botのidがで、その時間がであることを表しています。
MicroPython のプログラムの部分について、
py: from machine import Pin, I2C
py: import time
は、Raspberry Pi Pico のMicroPythonの標準モジュール, machine のなかの、Pin クラスとI2Cクラスを利用することと、標準クラス time を利用することを表しています。
py: i2c= I2C(0, sda=Pin(0), scl=Pin(1), freq = 40000)
は、変数i2cにI2Cクラスのインスタンスを生成し、代入することを表しています。ここで、コンストラクタI2Cの最初の引数 0 は、Pico の0番目のi2cインターフェースを利用することを表しています。
i2c通信のsda信号は0番ピンを利用し、i2c通信のscl信号は1番ピンを利用しています。freqはi2cインターフェースの最大周波数を表しています。
py: bme=BME280(i2c=i2c)
は、温度・湿度・気圧センサ、BME280のインスタンスを生成し、前の行で作成したi2cをi2cインターフェースとして利用するよう初期化して、変数bmeに代入することを表しています。
py: v=bme.values[0]
は、BME280で計測した温度(values[0])の値(文字列)を取り出して、変数vに代入しています。
py: line="device=temp, Date="+self.Pico_Time.get_now()+", v="+v
は、変数 line に、実行結果を表す行、"device=temp, Date=, v=<温度>"を代入しています。
py: self.write_line(line)
は、変数lineの値(実行結果を表す行)をWikiの実行結果の列を表すバッファに追加しています。
py: self.send_result()
は、バッファをWikiページに書き込みます。
8. 実行結果の例
Wikiページの"result:"の行の後から実行結果が書き加えられます。6. の例では"set report length="の行で、最大行数が20となっているので、最大20行の結果が書き加えられます。20行を超え当た部分は前の方にある古いデータから削除されます。
device=temp, Date=2024/04/03 05:00:43, v=21.2C
device=temp, Date=2024/04/03 05:05:43, v=21.3C
device=temp, Date=2024/04/03 05:10:43, v=21.2C
device=temp, Date=2024/04/03 05:15:43, v=21.09C
device=temp, Date=2024/04/03 05:20:44, v=20.98C
device=temp, Date=2024/04/03 05:25:43, v=21.08C
device=temp, Date=2024/04/03 05:30:43, v=21.1C
device=temp, Date=2024/04/03 05:35:43, v=21.12C
device=temp, Date=2024/04/03 05:40:43, v=21.05C
device=temp, Date=2024/04/03 05:45:43, v=21.07C
device=temp, Date=2024/04/03 05:50:43, v=21.04C
device=temp, Date=2024/04/03 05:55:44, v=20.94C
device=temp, Date=2024/04/03 06:00:43, v=20.88C
device=temp, Date=2024/04/03 06:05:44, v=21.8C
device=temp, Date=2024/04/03 06:10:44, v=21.76C
device=temp, Date=2024/04/03 06:15:44, v=21.75C
device=temp, Date=2024/04/03 06:20:44, v=21.97C
device=temp, Date=2024/04/03 06:25:44, v=22.1C
device=temp, Date=2024/04/03 06:30:44, v=22.19C
device=temp, Date=2024/04/03 06:35:44, v=22.26C
各行の実行結果は、Pythonのプログラムの以下の部分で書き加えられています。
py: v=bme.values[0]
py: line="device=temp, Date="+self.Pico_Time.get_now()+", v="+v
py: self.write_line(line)
py: self.send_result()
8. JavaScript でグラフ描画
Pico Botの実行結果である温度の変化をグラフで表示するためのJava Scriptを用意しています。6.のPukiWikiのページのスクリーンショットの、スクリプトの記述の前に書かれたURIのリンクが示すページ、http://192.168.8.237/pukiwiki/pico_wiki/sensors-graph-01.html に、以下のソースのhtmlページを置くと、このリンクをクリックすることで、以下のようなグラフが表示されます。
9. 終わりに
Pico Botで温度を計測し、それをWikiページに書き込むことができたことについて紹介しました。現在、PukiWikiのページに記述するMicroPythonのプログラムが使用するモジュールは、あらかじめ、Pico Bot のソースプログラムに組み込んでいますが、Thony のMicroPython用に登録されたライブラリを検索し、マイコンボードのファイルシステムに組み込む機能のようなものが VSCodeのMicroPicoで使うことができれば、それを使いたいと思っています。
9. 謝辞
以下のページを含む様々なページを参考にさせていただきました。感謝します。