ラズパイによる温度計測とLCD(AQM0802)・WEB(Flask)表示   
                        LCD(AQM1602)とWEB(WebIOPi)へ  CCS-C学習のTOPへ
[ はじめに ]
              A/Dを読んでLCD(ACM1602)にレベルバーで表示へ
 私の部屋には温度計がありません。それでデジタル表示する温度計がほしいというのが製作の動機です。さらに、その温度を遠くからでも知りたいというのがWEBアップ機能の追加の動機になっています。温度計測センサーは色々ありますが、温度をデジタル表示するのに I2Cインターフェイスの LCD(AQM0802A)を使いますから同じく I2C で動作するセンサが都合が良いのでそのようなデバイス(STTS751)を選びます。インテリアとして置いておいても良いくらいの物にする前に、とにかくバラックで組み立てて動かしてみることにします。

[ 使用する物 ]
・ Raspberry Pi Zero (WiFi なしの古いもの、WEBに接続するために USBの LANアダプタを付ける)
・ I2C接続小型キャラクタLCD 8 x 2 行 [AQM0802A-RN-GBW]
・ 高精度 12ビット I2C接続デジタル温度センサ STTS751
基本的にはこれだけですが、LCD はデバイス本体だけでは使いにくいので以前に製作していた
小基板に実装されているものを使います。また、センサはフラットパッケージ(SOT-23-6)で、これまたそのままでは使いにくいので秋月電子通商さんのSOT23変換基板を使ってブレッドボードに挿せるようにします。


【 1 】リモートディスクトップ
 リモートディスクトップは構築されている方が良いです。特に、Raspberry Pi Zero はキーボード・マウス・ディスプレイを接続するために色んな追加のパーツが必要となるので、もしまだでしたら、こちらなどを参照されて設定してください。下図が Windows 10 パソコンから起動した画面です。本体にディスプレイ・キーボード・マウスを付けなくとも操作できるのは快適です。ラズパイとパソコン間のファイルのやり取りには、WinSCPなどの FTPツールなどもあり、私もインストールしていますが、今はほとんどこのディスクトップで実行しています。



ディスクトップの画面に「シャットダウン」「再起動」「SD Card Copyier」のショートカットが配置されています。これは、リモートデスクトップのメニューからは、これらのコマンドを実行できないので、同様の動作をするショートカットを作っています。このショートカットの作成手順については、ここを 御参照ください。このリンク内に詳しく解説されています。解説は「シャットダウン」だけですが、「再起動」も、コマンドを「sudo reboot」とし、「アイコン」を変更すれば対応できますし、バックアップのための SD Card Copyier もコマンドを「env SUDO_ASKPASS=/usr/bin/pwdpic.sh sudo -AE dbus-launch piclone」 とすることで起動できます。

【 2 】回路図と組み立て図
 回路図は下図です。破線で囲っている部分は、LCD小基板です。右下のコネクタ(CN-RPI)は、ラスパイの GPIOコネクタの初めの 16Pin に相当します。ラズパイとの間には、+3.3V, GND, SDA, SCL の 4本が接続されることになります。GNDは GPIOの 6Pin だけにつながっていれば良いです。


ブレッドボードには、余分なものも付いていますが、無視してください。すでに動作している状態です。




【 3 】ファームウェアとファイルの配置
 温度をブラウザに表示させるためのサーバーには Flask を使用します。私のラズパイでは、初めからインストールされていましたが、もし入っていない場合は、
こちらを参照してインストールして下さい。また、I2C をインストールされていない場合は、こちらなどを参照されてイントールしましょう。これまで、ラズパイのサーバーとしては、WebIOPi を使ってまいりました。これは素晴らしいサーバーです。しかし、html, css, javascript, python の4つのファイルを準備し、さらに /etc/webiopi/config ファイルを編集し、最後に WebIOPi を起動するコマンドを発行しなければなりません。初めて Flask を使用した時は衝撃でした。単に python と html を準備し、python ファイルを起動するだけでサーバーが立ち上がるのですから ・・・

それでまず、その起動する Python ファイルを準備します。この中に、センサーからの温度の読み取り、LCDへの表示、サーバーの起動のすべてが含まれています。

app.py


このコードをマウスをドラッグさせてすべて選択して右クリックでコピーしてエディタに貼り付け、とりあえず任意の場所に、「名前を付けて保存」で名前を app.py としてください。その app.py ファイルの場所に、「templates」 という名前のホルダを作ってください。
注意!:文字コードは UTF-8 で保存しなければラズパイで動かす時にエラーとなります。
     ラズパイ側のテキストファイルは UTF-8 でなければなりません。

次は、html ファイルの作成です。下のリストを前と同様の手順で、先に作った「templates」の中に、index.html と名前を付けて保存してください。

index.html


 さて、これらのファイルをラズパイのどこに置くかは自由ですが、ここでは 「/home/pi/work/flask」 に入れたいと思います。つまり、 「/home/pi/work/flask」 の中に app.py を、 「/home/pi/work/flask/templates」 の中に index.html を入れてください。これで、ファームウェアの準備は完了です。


【 4 】起動と動作確認
 回路図通りの接続がしてあれば、リモートディスクトップのターミナルから、次のコマンドを打ってファームウェアを走らせてください。

cd /home/pi/work/flask
・・・これで flask ホルダにはいりました。次に・・・
python app.py
・・・これでサーバーが立ち上がります。驚きです、これだけでサーバーが動作するのですね。index.html と app.py を用意して python ファイルを走らせるだけで、それ以外の設定は何もしなくて良いのですから・・・

パソコンからブラウザを立ち上げ http://192.168.
xx.xx:3000/ にアクセスして下さい。ローカルアドレスの xx.xx の部分は、テストしているラズパイのアドレスです。アドレスを固定化していない場合は、ラズパイのターミナルから・・・
ip address show
・・・との コマンドを打ってアドレスを確認してください。

ここでポートは 3000 でアクセスしました。それは、app.py の中で Flask を起動する時に・・・
app.run(host='0.0.0.0', port=3000, threaded=True, debug=True)
・・・としてポート番号を指定しているからです。

 図のような表示が出れば成功です。最新のデータに更新するには、[ reload ] を押してください。実は、Flask において reload しなくても常に最新のデータがブラウザに表示できないか色々とネットを検索しましたが、現在までのところ簡単な方法は発見できていません。私の理解力を超える解説を英語でしているところはありましたが、かなり複雑なことをしているようで利用できませんでした。あまりスマートでは無いのですが、測定値を自動で更新する方法は別にあります。それは、[ reload ] ボタンを押す操作と同じことを自動で行わせることです。下のリストのように index.html を変更すると、2秒に一回 更新することはできます。

index.html



【 5 】ファームウェアの簡単な説明
 app.py の中に、I2C を使ったセンサ(STTS751)の読み取りとデータ処理、それに同様に I2C による LCDへの制御などが入っています。 app.py のほとんどの部分がそれらの I2C の処理のコードです。Flask に対する処理は、最後の 26行ほどです。I2C デバイスは、それぞれが固有のアドレスを持っています。そのアドレスをターミナルから、下のコマンドを打って調べて見ましょう。
sudo i2cdetect -y 1
検出されたデバイスのアドレスが下図のように表示されます。0x39 が 温度センサ(STTS751) のアドレスで、0x3e が LCD(AQM0802) のアドレスです、16進数で表示されます。コードのトップでそれぞれのアドレスを、adr_tmp、adr_lcd として定義しています。コードではその後、最初に 6個の I2C制御の基本関数を定義しています。さらに続いて、5個の便利に使える関数を定義しています。

init_tmp()  # STTS751(温度センサー)の初期化
init_lcd()   # AQMシリーズ(LCD)の初期化
・・・このデバイスの初期化の部分から、これまでに定義した 11個の関数を使って、具体的に I2C の処理を実行する部分に入って行きます。
これらの 11個の関数は、ここで全て使っているわけではありませんが、LCD の AQMシリーズを今後使うことがあれば有用だと思います。たとえば、上の動作中の写真(ブレッドボード)で LCDに、12.8℃と表示されていましたが、この '°'は LCD の CGRAM にキャラクタをユーザー定義したものです。これは一文字の定義をしましたが、このようにユーザーキャラクタの登録などのコードも含まれています。あと何文字くらいユーザー定義ができるかはデバイスにより異なりますので、マニュアルをご参照ください。

区切りマーク「
#========== 以下は、Flask の処理 ==========」の行で、I2Cアプリケーションの処理と Flask の処理がきれいに分かれていますので分かりやすいと思います。
Flask を起動するときに、temp = read_stts751() で温度を読み取りブラウザにレンダリングされます。

ブラウザに表示されている温度は「reload」しなければ更新されませんが、LCD の表示は現在の温度を常に表示したいです。以下の部分は、LCDに最新の温度を表示更新するために、自動で計測・表示を繰り返している部分です。

# 繰り返される関数
def getTempLoop():
 while True:
  global temp
  try:
   temp = read_stts751()
  except IOError:
   pass
 time.sleep(1)

t = threading.Thread(target=getTempLoop)
t.start()

これら一連の処理をラズパイの立ち上げ時に自動起動にするには・・・
sudo nano /etc/rc.local
・・・で rc.local ファイルを開いてください。
開いたファイルの最後に、次の文を記入してください。
python /home/pi/work/flask/app.py

Flask は、軽量な使いやすいサーバーですね、驚きました。 WebIOPi の場合は、表示している計測値の更新が Reload しなくても比較的容易にできますが、それができないのは残念です。しかし、私が知らないだけで実はその方法があるのかも知れません。Flask において「 reload 以外で表示値を更新」する簡単な方法をご存知の方が居られましたら、ぜひ教えていただけないでしょうか。

    ラズパイによる温度計測とLCD(AQM1602)・WEB(WebIOPi)表示   
                                           
 続けて、LCD を AQM1602 に変更し、サーバーを WebIOPi に変えてテストしました。上で Flask サーバーを使って簡単にブラウザに計測した温度を表示できることを試しましたが、既に WebIOPi を使って遠隔操作しているものが他にもあるので、WebIOPi でもテストして置きたかったのです。
WebIOPi の温度表示については、金丸隆志氏の「最新 Raspberry Pi で学ぶ電子工作」の第9章に詳しく解説されていますので、それをほぼそのまま使用させていただきます。
実は、このテストをしている時に大失敗をしてしまいました。もともと AQM0802 と AQM1602 は共に PICマイコンで同じライブラリで動作させており、当然、ラズパイでも同じように動かせると思い込んでおりました。それが AQM0802 については上のように動かせたのですが、AQM1602 では同じ様に配線しコントロールしても全く動作しないのです。ブレッドボードに挿している LCDをAQM0802 にしたり AQM1602 に替えたりを繰り返している時に、ラズパイの +3.3Vと GNDをショートさせてしまったのです。これで Raspberry Pi 3 B+ が昇天してしまいました。ショートは、ほんの一瞬でしたが簡単に壊れるもんなんですね。ポリスイッチなどで保護はされていないようです。ネットで調べると、これで壊された方はたくさん居られるようですね。皆様もご注意ください。それはさておき、何で AQM1602 は AQM0802 のように動かないのか色々調べている内に、秋月電子通商さんの「Q&A」で次の記述を見つけました。それを以下に引用します。
;-----------------
【質問】
I2C液晶をラズパイに接続しても表示されません。どのようにすればいいでしょうか?
【回答】
Raspberry Pi 全シリーズに共通する仕様の制約から、AQMシリーズの液晶を接続する場合にはバッファを介して接続してください。
I2CバスはRaspberry Pi(マスターデバイス、GPIO 2, GPIO 3)の基板内で
1.8kΩの抵抗によって固定的にプルアップされています。 3.3Vに1.8kΩでプルアップされたバスラインをスレーブデバイスがLレベル(0.3Vdd=0.99V以下)にするためには、最低でも1.28mA以上の電流引き込み能力を必要とします[3.3V-0.00128A×1800Ω≒0.99V]。
AQMシリーズ液晶は低消費電流(1mA)設計のため、[SDA(データ)]ラインで過大な電流を引き込むことができず、通信エラーを起こす場合があります。 これを回避するためには[SDA(データ)]ラインに双方向バッファ(リピーター)を介在させ、正常なデータ通信を確保する必要があります。
簡単な方法として、I2Cバスリピーター(PCA9515D)を使用した例をご紹介いたしますので、ご参照ください。
;-----------------
う〜ん、これが分かっていたならば、ラズパイを壊すこともなかったかもしれない(グチ・笑い)、しかし理由が分かりました。AQM0802 はたまたま動いていたのでしょうか。しかし、この AQM0802 は、他のAQM0802 に差し替えても動くので、AQM1602 より電流引き込みが強いのかもしれません。
このような訳で、使用する部品としては、上の AQM0802テストで使ったもの以外に、紹介されている「I2Cバスリピーター(PCA9515D)」を加えることが必要になります。


【 1 】回路図と組み立て図
 回路図は下図です。破線で囲っている部分は、LCD小基板です。左下のコネクタ(CN-RASP)は、ラスパイの GPIOコネクタの初めの 16Pin に相当します。ラズパイとの間には、+3.3V, GND, SDA0, SCL0 の 4本が接続されることになります。GNDは GPIOの 6Pin だけにつながっていれば良いです。SDA0, SCL0 は I2Cバスリピータ経由で SDA1, SCL1 に接続され、双方とも結果的に 10kΩのプルアップに変わります。結局、
ラズパイ内蔵のプルアップ 1.8kΩから、10kΩのプルアップに入れ替わったことになります。


温度センサ(STTS751)は、先に使った物を使用し、バスリピータ(PCA9515D)は、8ピンSOPなのでそのままでは付けられないので、秋月電子通商さんの
DIP化基板を使っています。ブレッドボードには、余分なものも付いていますが、無視してください。写真はすでに動作している状態です。





【 2 】ファームウェアとファイルの配置
 I2C をインストールされていない場合は、ここらなどを参照されてイントールしてください。また、温度をブラウザに表示させるためのサーバーには WebIOPi を使用しますので、これも
こちらなどを参照してインストールしておいてください。WebIOPi は、先の Flask とは異なり、script.py、index.html、styles.css、javascript.js の4のファイルを準備します。初めに書きましたように、これには、金丸隆志氏の「最新 Raspberry Pi で学ぶ電子工作」の第9章を使わせていただいておりますので、主に変更するのは、I2C を使った温度センサの読み取りと LCD表示の部分で、それは script.py に記述しています。下のリストに、script.py と、index.html、style.css、 javascript.js を記述します。WebIOPi のインストールについては、上記の書籍のP222にも詳しく説明されています。また、温度をブラウザに表示する方法とファイルの展開方法については、P242ページに詳しく解説されています。この書籍と大きく違っているのは、温度センサの種類が違うことと、温度表示をブラウザにすると同時にLCDにも行っていることです
まず、 Python ファイルを準備します。この中に、センサーからの温度の読み取り、LCDへの表示、javascript.js から呼ばれるマクロの定義などが含まれています。

script.py


このコードをマウスをドラッグさせてすべて選択して右クリックでコピーしてメモ帳などのエディタに貼り付け、とりあえず任意の場所に、「名前を付けて保存」で名前を script.py としてください。
次は、html ファイル の作成です。下のリストを前と同様の手順で、同じ場所に index.html と名前を付けて保存してください。

index.html


style.css は、3行です。これを同様に style.css と名前を付けて保存してください。
style.css


さらに、以下のリストを javascript.js と名前を付けて保存してください。
javascript.js


 さて、これらの4つファイルをラズパイのどこに置くかですが、「最新 Raspberry Pi で学ぶ電子工作」の第9章の通りにしたいと思います。つまりラズパイの・・・
/usr/share/webiopi/htdocs/bb/02
・・・に置くことにします。ホルダが無い場合は作ってその中に、この4つのファイルを入れてください。
もう一つこれ以外に、index.html に、<script src="js/require.js"></script> と書いてあるように、require.js が必要です。これは記述が圧縮されたファイルですので、ここからダウンロードして解凍してください。このファイルは・・・
/usr/share/webiopi/htdocs/bb/02/js
・・・ つまり、先の4つのファイルの場所に js ホルダを作り、その中に入れてください。以上で、必要なすべてのファイルの配置はできたことになります。
  (参考) /usr/share/webiopi/htdocs ホルダの所有者を変更します。
      sudo chown -R pi /usr/share/webiopi/htdocs この場合、所有者が pi に変わる
      これを実行しておけば、エクスプローラでホルダの作成などが実行できます。

【 3 】起動と動作確認
 上記で、ファイルの配置はできましたが、まだ WebIOPi を起動するには準備が必要です。以下のコマンドでファイルを開いてください。
sudo nano /etc/webiopi/config
このファイルの中の [SCRIPT] セクションに以下の1行を追加します。
myscript = /usr/share/webiopi/htdocs/bb/02/script.py
これで、WebIOPi と script.py が関連付けられることとなり、このPythonファイルが起動されます。
また、[HTTP]セクションの port を・・・
port = 5000
・・・としてください。これは単に、ここでのテストのポートとして 5000 番を使っているからで、ディフォールトの 8000 番でも構いませんが、その場合はブラウザを起動する時にそのポート番号を指定するようにしてください。
さて、やっと WebIOPi の起動です。以下のコマンドを実行します。
sudo systemctl start webiopi
これで、WebIOPi が活動を開始します。停止する場合は、sudo systemctl stop webiopi です。

パソコンからブラウザを立ち上げ http://192.168.
xx.xx:5000/bb/02 にアクセスして下さい。ローカルアドレスの xx.xx の部分は、テストしているラズパイのアドレスです。アドレスを固定化していない場合は、ラズパイのターミナルから・・・
ip address show
・・・との コマンドを打って確認してください。そのアドレスで実行してください。下図のような表示が出ましたでしょうか、出れば成功です。


【 4 】ファームウェアの簡単な説明
 何度も述べていますが、このコードは、ほぼ 「最新 Raspberry Pi で学ぶ電子工作」の第9章の通りです。違うところは、I2C を使ったセンサ(STTS751)の読み取りとデータ処理、それに I2C による LCDへの制御などです。それらは、script.py に記述されています。このファイルの大部分は、上で Flaskで実行した時の app.py の中身と同じです。 I2C デバイスは、それぞれが固有のアドレスを持っていますが、そのアドレスをターミナルから、下のコマンドを打って調べて見ましょう。
sudo i2cdetect -y 1

検出されたデバイスのアドレスが図のように表示されます。0x48 が 温度センサ(STTS751) のアドレスで、0x3e が LCD(AQM1602) のアドレスです、16進数で表示されます。script.py のコードのトップでそれぞれのアドレスを、adr_tmp、adr_lcd として定義しています。コードではその後、最初に 6個の I2C制御の基本関数を定義しています。さらに続いて、5個の便利に使える関数を定義しています。

init_tmp()  # STTS751(温度センサー)の初期化
init_lcd()   # AQMシリーズ(LCD)の初期化
・・・このデバイスの初期化の部分から、これまでに定義した 11個の関数を使って、具体的に I2Cの処理を実行する部分になります。
これらの 11個の関数は、ここで全て使っているわけではありませんが、LCD の AQMシリーズを今後使うことがあれば有用だと思います。たとえば、上の動作中の写真(ブレッドボード)で LCDに、20.25℃と表示されていましたが、この '°'は LCD の CGRAM にキャラクタをユーザー定義したものです。これは一文字の定義をしましたが、このようにユーザーキャラクタの登録などのコードも含まれています。あと何文字くらいユーザー定義ができるかはデバイスにより異なりますので、マニュアルをご参照ください。

STTS751のアドレスは、先にした演習では、0x39でしたが今回は0x48 です。これは、STTS751 の1番ピンがアドレス設定になっており、前回はGNDに落としていましたが、今回は +3.3Vに接続しています。このピンを何kΩでプルアップするかで、4種類のアドレスを選択できるようになっており、GNDと+3.3Vは、その両端のアドレスを選択したのと同じになります。表はSTTS751のマニュアルの一部です。今回使っているデバイスは、STTS751-0WB3Fですから、表の上段に該当します。GNDに接続すると33K±5% を選択したのと同じになり、+3.3Vに接続すると、7.5K±5% 選択したのと同じ設定になります。

なお、前回の LCDの AQM0802 と大きく異る部分は、コントラストを指定する値が異なっています。
CONTRAST = 0x28   # AQM0802:0x18, AQM1602:0x28
これ以外は、LCD に関する I2Cのコマンドは全く同じですので双方とも基本的に同じライブラリを使用します。

ここでは、サーバーとして WebIOPi を使いました。Flask と比べると、かなり複雑ですが、電子工作をするにはとても便利な機能が盛りだくさん用意されているという印象を持っています。初めは、script.py、index.html、styles.css、javascript.js という多くのファイルと言語が登場してきて戸惑いますが、これも慣れることではないかと思います。

Reported by TokioYamada@ADK
汎用製品通販のページへ        ラズパイのハードウェアWDTの製作へ         USB-IOのページへ