手元にRaspberryPiがあってローカルで「ファイルサーバーやWordPressのテストとしてWEBサーバー」としても使ってるのだけど、ラズパイの特徴でもある電子工作的な使い方してなかったので。管理人宅の部屋の温度をブログに表示させることにした。
こんな感じにブログのサイドバーに表示してます(スマートフォンだとプロフィールの下に表示)。
RaspberryPiは簡単に言うと名刺サイズの小型パソコンで本体の値段は4000~5000円ぐらいで買える(バージョンやお店によって違うけど)。これにケースやキーボードなど揃えて参考書も1冊としても1万円以内で買えます(モニタ別)。
ラズパイ詳細はWikipediaなどみてください。
ラズパイで温度センサから部屋の温度を読み取ってブログに表示させる機能を考案
何となくで特に理由は無いんだけど、丁度温度センサーも持ってたのでラズパイで部屋の温度をブログに表示させてみたいなと思ったので作ることにした。
ラズパイの参考書もあるし、あとは「どうやってブログに温度を表示させるか」と課題があるのだけど、これはFTPでサーバーに接続してアップロードすればいけるのでは?と解決した。
実際、作業に取り掛かってから色々と問題が出てくるんだけど順に書いていきます。
ブログに管理人宅の部屋の温度を表示させる機能の仕組み
温度センサで取得した数値をマイコンで温度に換算してそれをラズパイに送る。ラズパイで受け取った温度をJavaScriptで表示するように置きかえ。最後にFTPでサーバーにアップロード。
このように、ラズパイで作ったプログラムを「cron」で定期的に実行してます。
- AVRマイコンで温度を取得
- ラズパイからデータがマイコンに送られたらAVRから温度を送信
- ラズパイで取得した温度をJavaScriptで表示するファイルを作成
- ラズパイで作成したJSファイルをサーバーにアップロード
- ブログからJSファイルを読み込んで温度表示
一連の流れはこんな感じ。いきなり全部やっても上手く動作しないのと動かない時の原因が分からない為一つ一つ順を追って作業しました。
AVRマイコンで温度を取得
以前、電圧を読みとって4ケタの7セグLEDに表示する回路を作っていたのでこれを利用して温度センサの温度(電圧)を取得します。温度センサ5V動作なのでマイコンも5Vで動作させる。
AVRの使い方(プログラムの書き方)はニコニコ動画を参考。
ラズパイからデータがAVRマイコンに送られたらAVRから温度を送信
マイコンは5Vでラズパイは3.3V、このためマイコンからの送信信号をラズパイで受信すると壊れる可能性があります。なので最初は「AVR-PC(5V同士)」次に「AVR-PC(5V-3.3V)」、「PC-ラズパイ(3.3V同士)」、「PC-ラズパイ(5V-3.3V)」で確認で「AVR-ラズパイ」の通信を行いました。
パソコンから5V,3.3Vでシリアル通信するために秋月電子の『FT232RL USBシリアル変換モジュール』を使用。
5Vの信号を3.3Vにする時は分圧抵抗で[5V→3V]にしています。[3V→5V]は直結です。
PCはターミナルから確認して、ラズパイも最初はターミナルから確認。次にPythonでシリアル通信を行いますがここを参考に通信の確認をしました。
ラズパイで取得した温度をJavaScriptで表示するファイルを作成
シリアル通信でマイコンから取得した温度のデータをJSファイルに置き換えて作成。「document.write」で温度と日時を表示。
作成したJSが表示されているかローカル上でHTMLファイルを作りJS読み込んで確認。
ラズパイで作成したJSファイルをサーバーにアップロード
PythonでFTPでサーバーにファイルをアップロードするにはここを参考にした。
ドメインのホームディレクトリはサーバーによるのだろうけど、このブログの場合は「/ドメイン名/サブドメイン名/..」。このブログのURLはサブドメインが無いので「abc123」など別の名前になっている。
プログラムでのFTP接続は初めてだったので時間かかるだろうなと思ってたらあっという間。問題があったのがディレクトリパスとアカウント情報の間違いだけ。
順調に行ってるように思えるけど何度も躓いている
ハード(回路)的なこと
温度センサの関係からAVRマイコンは5Vで動かさないとい駄目なので3.3Vのラズパイと通信するには信号のレベル変換が必要になって来る。トランジスタ使う方法で考えて調べてたけど学生時代に抵抗で5V→3.3Vに信号電圧を分圧してたの思い出した(抵抗の計算が面倒だったので「10k・15k」で5V→3Vにした)。
ソフト(プログラム)的なこと
マイコンのA/D変換で温度の電圧は取得出来たけどそこから温度に置き換えてシリアル通信(UART)でデータを送る。マイコンからパソコンに”数字”で送ってたけどPCで文字化けするので”文字列”で送ることに。(I2CやSPIも考えたけどPCで確認ができないので諦めた)
3ケタの数字を1ケタずつ取り出して用意した[“0”-“9”]の配列に入れてラズパイに送信してる。switch文で数字[0-9]を文字列に置き換える方法も考えたけど配列の番号に入れるほうが簡単だったのでこれに落ち着いた。(3桁の数字例えば300は30.0度の意味)
ラズパイで小数点を付けるの面倒なのでマイコンから1文字ずつ送信するときに小数点も付け加えて送信。
ラズパイのシリアル通信でネットで調べた情報とシリアル通信の場所が違ってて「/dev/ttyAMA0」だった。ラズパイもいくつかの種類が出てるのでモデルにより違う場合がある。
プログラムは非効率
作ってるプログラムは自分でもわかるぐらいに非効率だと思う。各桁の数字を文字に変換した後にマイコンからラズパイに温度データを送信する際に
- 3ケタ目送信
- 2ケタ目送信
- 小数点「.]を送信
- 1ケタ目送信
と4回も送信。(while文あたりで繰り返しで出来そうだけどシリアル送信のプログラムを4回書いてる)
他にも、マイコンはラズパイからのデータを受信するまでループ待機してその間何もできない。まあ温度表示させるだけで他のことは何もしてないからこのままでいいんだけどね。(本当は効率よく書きたいけどそこまで頭が回らない)。
部屋の温度表示できるようになったけどキャッシュの問題が発生
部屋の温度を書いたJSファイルをFTPでアップロードしてブログに表示できたのは良いのだけどキャッシュが残ってて変わらないからJSのファイル名末尾にタイムスタンプを付けて解決した。
以前CSSのキャッシュが残る問題について書いた記事ですが、これをJavaScriptに応用。PHPでJSファイルのタイムスタンプを取得する時はドメインのパスではなくサーバーのルートパスが必要だった。
温度センサーの誤差が気になるので近くに温度計置いて確認した
温度センサの温度は23時45分で26.6度。
温度センサー「LM35」の誤差が気になるので温度計2台を近くに置いて確認してみたら誤差プラマイ1~2度はあるようです(写真左の時計に近い値)。まあ僕しか使うことが無いのでこのぐらい大雑把でも問題ありません。
ただ設置場所がラズパイ用のPCモニタのの下に置いてあるので電化製品の熱がこもってるのか窓用エアコンの冷気が届かないのか実際の部屋の温度よりは若干高めです。
あとがき
僕以外「誰得?」な機能をブログに付けました。これで外出中でも部屋の温度が分かりますわ。ちなみにラズパイと一緒に買った参考書は通信が「I2C」しか載って無かったのでピン配置の確認にしか使ってませんでした。
しかしまあ「部屋の温度をネット上から確認」、これも最近話題のIoTになるんですかねぇ。「管理人宅の部屋の温度は今こんなんです」って感じなので僕にしか役に立たない情報ですが…(^^ゞ