Raspberry Pi Zero WHでBlynk経由、Python3を使って GPIO制御、BMP280測定値の読み取りをしてみる。

これまで、ESP8266や、ESP32を使って、スマホからBlynk経由で、温度・湿度・気圧などを確認してきたが、まずは、同じ事をRaspberry Piで試してみる。Raspberry Pi上のI2CにBMP280を接続して、SSHでつないだターミナル上に、温度・湿度・気圧をprintするところまでは、こちらで作成した。

Blynkでのアカウント作成等は、ネットに一杯情報があるので、ここでは省く。

新しいTokenを一つ取得する

スマホのBlynkアプリから、新しいデバイスを一つ登録する。残念ながらRaspberry Pi Zero Wは、ハードウエアの選択肢になかったので、Raspberry Pi 3Bをとりあえず選ぶ。これが正しいのかどうかわからないが、まずこれでやってみる。デバイス名は、”RaspberryPiZero001”としておく。作成すると、登録したメールアドレスにTokenが届くので、コピーしておく。

Auth Token : b738***********************2c1c

RaspberryにBlynkの環境をインストールして、Tokenを登録する。

Arduinoの時は、コンパイル済みのライブラリをIDEから読み込むだけで設定できたが、Raspberryの場合は、ソースからのコンパイルが必要らしい。

他の方の記事を参考にさせて頂き、

を実施してみたが、make の途中でエラーで終了。wiringpi関連のヘッダーが無いとか・・・。改めて、Makefileの中を見てみたら、ちゃんと書いてあるでは無いか。

との事なので、まずは、WiringPiをインストールする。念のために、dpkg –l で、wiringpiがインストールされていないことを確認してみた。確かに入っていなかった。($ gpio –v でも確かめられる)

指示されたホームページを見ると、gitを使ってインストールすることが推奨のようなので、gitが入っているか確認したら、入っていた($ git –version)。下記のコマンドでwiringPiを gitでダウンロードする

でビルド実行。正常に終了したっぽいので、再度Blynkのディレクトリに戻って、makeを実行。target=raspberryというのが重要。

このように、blynkという実行ファイルが出来たので、Makefileに書いてあった通り、先程取得したTokenを登録する。

正常っぽい。これで、Raspberry Pi Zeroが Blynkサーバーと接続できる環境が整った。sshでつないだ端末には、プロンプトが帰ってこないが、これはこのblynkプログラムを表のプロセスで起動したから。裏で起動することにする。

  • 追記:あとで考えたら、backgroundでの起動は駄目。makeされた結果のblynkというプログラムは、main.cppをコンパイルした結果だから、BLYNK_WRITEのprintfの書き出し先としてstdoutを使っており、backgroundで動かす事は前提としていない。このblynkはあくまでも一つのプログラムであり、Python などから呼べるライブラリでは無い。当たり前・・・・。
  • ESP32で書いていたようなCのコードを書けば、Raspberry Piでも同様の事ができることは明確だが、ここでは、何とかして、Pythonのコードから、Blynkを使えるように、色々調べてみることが目的。

スマホ側で、接続を確認する

次にスマホのBlynkアプリを立ち上げて、今接続したRaspberryPiが接続されているかどうかを確認する。正しく、先程設定した名前で登録されているのが確認できる。ただ、まだ何も送信していないので、この状態では何も出来ないのは当然。(他のESP01やESP32は、以前遊んでいて登録した物だが今は使っていないので、ずいぶん前からOfflineになっている)

image

スマホからRaspberry PiのGPIOピンをOn/Offする

スマホのBlynk画面から新しくボタンを作成してGPIO24ピンに設定する。

image

Blynkのホーム画面に戻って、▷ボタンを押して開始した後、表示されたボタン(GPIO-24)をクリックする毎に、Raspberry Pi ZeroのGPIO-24番(ヘッダの18番ピン)が、High/ Lowと変化するのが確認出来た。

ちなみに、TeratermのSSHで繋がっているシェルプロンプトから、GPIOを制御するためには、gpioコマンドを使う。現時点では何もSyncをさせていないので、gpioコマンドで High/Lowを変えても、Blynkのスマホ画面上のステータスが変化するわけでは無い。

次に、スマホのblynkアプリからRaspberry Piに何らかの数字を送ってみる。一旦、Blynkのアプリから「□」ボタンをクリックして接続を止め、新しくスライダーを追加してみる。スライダーを Virtual Pin 1 (V1)に設定して、0から1024までの値を送るように設定した。

image

←矢印で戻ったのち、▷で再開して、下記画面のスライダーを左右に動かして見ると、止める毎にRaspberryの繋がったSSHターミナルの標準出力に、main.cppの、BLYNK_WRITE(V1)関数で定義された通り、’Got a value ….’の表示がなされる。

image

ここまでは、サンプルで提供された main.cppの動作を確認しただけ。

PythonでBlynkへつなぎたい

Pythonから繋ぐためのライブラリがあった。

ネットでBlynkとRaspberryPi関連の情報を探したが、殆どが、C言語でコードを書くもので、また、シェルプログラムで処理する例もあったが、Pythonで制御するものは余り見つからなかった。無理かな?と思っていたら、次のページを見つけた。

このリンクに、Python2あるいは3からBlynkへ接続するためのライブラリが登録されていた。pip3でインストールしてみた。正常に 0.1.3 バージョンがインストールできた。

Pythonでのコーディングサンプルは、ここにある。

これを元に、一行目に #!/usr/bin/python3 を追加し、Authenticationのキーに、自分が今回取得したBlynkからのTokenの文字列を記入して、Raspberry Pi上に blynk,pyというファイルで保存した。 ファイルの実行権を chmod +x で追加した後、./blynk.py と起動すると、とりあえず、動作した。

スライダーによる、RaspberryへのV1ピン経由の数値送りは、問題なく動作したが、GPIO 24で設定した実ピンに対しての出力は、上記のように、Warningが出て、動作しなかった。この Pythonライブラリは、実ピンに対する処理はサポートされていないようだ。

実際のGPIOへ出力するためには、一旦Virtual Pinで値を受けてから、Pythonのプログラムの中で、物理GPIOピンへの出力処理をしてあげる必要があるようだ。下記のように、Virtual pin 0をアサインして、コードを追加したところ動作した

という事で、これでとりあえず、スマホのBlynkアプリから、Virtual Pin設定した値を、Raspberryに送り、Pythonのプログラムによって処理できることは確認出来た。

RaspberryのPythonプログラムからBlynkへデータを送る

Raspberryから、スマホのBlynkアプリへデータを送るには、VIRTUAL_READを使う必要がある。スマホのBlynkに、新たに “Value Display”を追加して、Virtual Pin 2 (V2)をアサインする。また、読み取り周期は5秒とする(READING RATE 5sec)

image

▷で作動させると、下記のように、Raspberryの ‘time’から、”time.ticks_ms() //1000 “の値が5秒毎に送られ、表示させるのが確認できる。(ちなみに、//の演算子は「切り捨て除算」)

image

Pythonを使ってBMP280から読んで補正した温度・湿度・気圧データを、Blynkへ送る

次は、Raspberryに接続されたBMP280をPythonで制御し、得られた測定データ(温度、湿度、気圧)をBlynk経由でスマホへ送って表示&記録する。

例えば、5秒毎に温度・湿度・気圧を測定して、それを3つのVirtual PinとしてBlynkに送るという事をやりたいが、普通にVirtual Readを使うと、スマホ側の読み出しトリガを基準に一つのチャンネルの読み出しトリガが発生して、一つのデータを送る・・・という事は問題なくできる。 ただ、一つのトリガで3つの測定データを3つのVirtual Pinに対して送る事が、今までのようなイベント型のトリガ方式で可能なのか疑問。

一定のタイマーをRaspberry側で測定して、その間隔毎に、Blynkにデータを送り続ける形にするのが望ましいと思う。それを実現するためには、今のコードの@blynk.VIRTUAL_READ(2)

def my_read_handler():….

のやり方では駄目と思われる。

@マークのデコレーターについて

上記の例に於ける、@blynk.VIRTUAL_READ()は、Pythonのデコレーターと呼ばれるもので、「ある関数を修飾するための関数」とその仕組みを指す。この仕組によって、既存関数の処理の前後に自分自身の処理を付け加えることができる。これにより、ライブラリとして提供されている関数を呼んだ時に、自動的に実行される処理を追加できるという事。関数にコードを足すこと無く、機能を追加することができる。

「デコレーターとは、”関数を引数に取り, 引き換えに新たな関数を返すcallable(*)”である」

今回の使い方では、予め定義されている blynk.VIRTUAL_READ()や VIRTUAL_WRITE()そのものには手を付けないで、そのWrapperのような形で、それらの関数を利用しているという事になるのかと思う。 便利だけど、何となくピンと来ない。

Raspberryからのデータ送信周期について

先程の例のように、スマホのBlynkアプリで、Virtual Readの周期が決まる場合、このアプリを起動していない場合は、データがBlynkに送られないのでは、と思われる(要調査)。

代わりに、Raspberry PiのPythonプログラムの中で、タイマーを設けて、そのタイマーが一定時間を経過する毎に、Virtual_Readを実行すれば、Blynkのサーバーに送られるように作りたい。(以前、ESPの時はそのように実施した。その時には、ESPに用意していある、blynk_timer.setInterval(5000L, sendUptime)を使って 5秒毎に ‘sendUptime’関数が呼ばれるようにした。

これと同様に事を実現するには、Raspberry Piの Pythonに用意されている、threadingを使うと良さそう。

この例のように、5秒毎に新しく threadを作り、それを実行するという処理で実現できる。関数内で定義したthreadは実行が終わると消滅するので、毎回作らなくてはいけない。関数の外にある threadの定義は、最初に一回目を実行するために必要。何となく、スッキリしないが、このページで少し説明されているので参考になる。(さらにこのページ

試行錯誤して、こんな感じで、5秒毎に温度、気圧、湿度をBMP280で測定して、Blynkへ送るPythonプログラムが、とりあえず出来て、所望の動作をしている。 SSHのターミナルへも、温度、気圧、湿度を出力している。

image

メインプログラム (blynk.py)

BMP280モジュール (bmp280.py)

とりあえず、これで、

「Raspberry Pi Zero WHにのGPIOの制御や、I2C接続したBMP280の温度・気圧・湿度のデータを、Blynkに5秒毎に送って表示する処理を Python3で実現する」

という、当初の目的は達成出来た。めでたし、めでたし。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする