Macと書籍と考えと Mac, Book, Thinking and more,,,

【技術メモ】Raspberry Pi 〜[02]電子ペーパー+Netatmoで温湿CO2計パネルを作成♪〜


 「Raspberry Pi」というものに興味があったのですが、敷居が高く、使い道もよく分からなかったのは事実。しかし「当ページの内容を作ってみたい!」と思ったのがきっかけで、Raspberry Piを購入しました。そういった記念すべき作品です。(2019/02/26更新)

■ 当ページの「はじめに」


 成果物は、「部屋の温度・湿度・CO2が表示できる電子ペーパー計!」です。
 正直、LED系の表示モノであれば安くていろいろと手に入ると思いますので、コスパは激悪です。
 ただし、アイディア次第で色々と他の用途にも使えますので、将来的には使い勝手を上げていきたいな、と。


■ 00. 目次


 01. 完成イメージ
 02. 必要なモノ
 03. 必要ライブラリのインストール、環境設定
 11. コーディング
 89. 今後の拡張
 91. 参考サイト
 96. つぶやき


■ 01. 完成イメージ


 目に優しい電子ペーパーをディスプレイとした、部屋の温度、湿度、CO2濃度を表示するパネル。
 この作品のポイントは「電子ペーパーを使う」という点で、LED系の時計とかとは違い、まぶしくなく、かつ見やすいです。
 「Netatmo」というウェザーステーションを使い、その情報を電子ペーパーに出力します。1年以上前からNetatmoを使っているのですが、閾値を超えると通知はこれど、イマイチ有効に使えていない感がありました。常時、数値が見える場所にあることで、計測が活かせるものと思います。

 (ものすごく無駄な構成。。。)

 <処理イメージ>
 

 <完成物>
 電子ペーパー+HATRaspberry Pi ZERO WH(ケース付)です。
 配線は、GPIOコネクタにガツンと装着することも可能です。個別の配線にした理由は、ヒートシンクと物理的に重なって接続できなかったため と、将来の拡張性を残すため(他のGPIOコネクタを使うため)、です。
 

 3Dプリンタで壁のレールにちょうどハマるように作りました。
 製作2時間(失敗込み)、印刷10時間(失敗込み)
 

 後ろの配線は、内緒だよ。(面倒なので適当)
 


■ 02. 必要なモノ


 自分としては手持ちのものを流用しつつ、でしたが、一から全てを揃えるのはしんどいかも。。
 手持ちの範囲で、お選びください。代替できるものはたくさんあります。例えば、Netatmoではなく、温湿度センサーにするとか。(当ページの内容とは変わってしまいますが。)

 ・Raspberry Pi ZERO WH
  Raspberry Piであればなんでもよいですが、ネットワーク接続必須です。
  ⇒ Amazon

 ・電子ペーパー
  自分はそれなりの大画面にしたかったので、Raspberry Piでも使えると謳っている WAVESHARE というメーカーの「3 7.5インチ E-Inkディスプレイ HAT(B)」を購入しました。
  白、黒、赤の3色表示です。ただし、ディスプレイサイズ、色数が増えると、書き換えにかかる時間が長くなります。(このモデルだと約30秒!かかります。時刻表示にはあまり向かないですね。)
  小さく、白黒のみでしたら、(使ったことないですが) 3秒、とかみたいです。
  ラズパイと接続できればなんでもよいと思いますが、以降のプログラムはWAVESHARE前提で進めますのでご了承ください。
  ⇒ Amazon / waveshare

 ・Netatmo
  おうちのウェザーステーション、という製品。これを買えば、スマホでも今回作るようなものが見れます。笑 というか、それが正しい。
  今回は、このNetatmoで集めた情報がNetatmoの自分のアカウントに貯まるので、公式APIをたたいてラズパイで情報を取得、その内容を表示する、という流れになります。
  ⇒ Amazon

 ・作品本体のケース
  なんでもOKなのですが、自分は3Dプリンタでデザインし、壁にかけられるようにしました。専用のケースは売っていないので、、、どうしましょうかね。。

■ 03. 必要ライブラリのインストール、環境設定


 適当に作ったのでイマイチなのですが、、、とりあえず、個人用に動くモノを作ることが優先。

 ・Netatmoから情報を取得するAPIをぶったたくライブラリ lnetatmo Python3
 ・電子ペーパー WAVESHARE SPIライブラリは Python2 ※Python3のライブラリもあります
 を使います。

 ・WAVESHARE の公式サイトに電子ペーパーを使うためのライブラリがありますので、そちらも取得します。Python用もあります。https://www.waveshare.com/wiki/File:7.5inch_e-paper_hat_b_code.7z
 

 # 公式コードの取得
 # Raspberry Pi Pythonコード以外にも多数含まれています
 # 利用する電子ペーパーにあったコードをダウンロードしてください(URLが異なります)
 # )
 wget https://www.waveshare.com/w/upload/0/01/7.5inch_e-paper_hat_b_code.7z

 # 7zが解凍できない場合はアプリをインストール
 sudo apt install p7zip

 # 解凍
 # 解凍後の /RaspberryPi/python2 が該当のサンプル
 7zr x 7.5inch_e-paper_hat_b_code.7z
 


 ・あと、NetatmoAPIを利用できるように、Netatmoのサイトで開発者登録し、認証コードを発行する必要があります。(無料)
  NETATMO connect( https://dev.netatmo.com/ )にログインし、CREATE YOUR APP > 必須事項を入力してSAVE > ここで作成した Client id Client secret が、自分のNetatmoPythonからアクセスするログインキーになります。

 ・その他、必要パッケージ等の準備
 

 # Python3関係の準備
 pip3 install lnetatmo
 


 

 # Python2関係の準備
 # 日本語フォントをインストール
 sudo apt install fonts-noto-cjk

 # PythonSPI通信をするためのライブラリ(電子ペーパーとのやりとりで必要)
 sudo apt install python-spidev

 # Pythonで画像処理をするためのライブラリ
 sudo apt install python-pil

 # Pythonでタイムゾーンを管理するためのライブラリ
 sudo apt install python-tz
 


 

 # Raspberry PiSPI通信を有効にする
 sudo raspi-config
 # Interfacing Options SPI はい
 # で設定
 


■ 11. コーディング


 全体の処理の流れは以下の通り。
 超適当につぎはぎで作りましたし、pathベタ打ちと最低のコーディング。。。
 肝となる処理のご参考にはなると思いますので記載します。
 

 ・Netatmo呼び出し(get_netatmo_co2.py) ※Python3
 

 # -*- coding: utf-8
 # lnetatmoを使用しNetatmoAPIをたたいて、返ってきたJSONの中身で必要なものだけを出力する、だけ。
 import lnetatmo
 from datetime import datetime
 
 def main():
  # 変数定義
  netatmo1 = "xxx" #狙ったステーションを選択
  netatmo1_co2 = "0"
  netatmo1_temp = "0"
  netatmo1_hum = "0"
  
  # tokenを取得
  # clientId clientSecret は、上述のNETATMO Connectで取得した値をセット
  # username password は、Netatmo にログインする自身のログイン情報
  authorization = lnetatmo.ClientAuth(
  clientId = "xxx",
  clientSecret = "xxx",
  username = "xxx",
  password = "xxx",
  scope = ""
  )
  
  # 天気情報の取得
  weather_station = lnetatmo.WeatherStationData(authorization)
  
  # 辞書型への格納
  mydict1 = weather_station.lastData()
  
  # 測定値を格納
  netatmo1_co2 = mydict1[netatmo1]["CO2"]
  netatmo1_temp = mydict1[netatmo1]["Temperature"]
  netatmo1_hum = mydict1[netatmo1]["Humidity"]
  
  # 測定値を表示(カンマ区切り) ※シェルに戻すために強引に出力。。
  print(str(netatmo1_temp) + "," + str(netatmo1_hum) + "," + str(netatmo1_co2))
  
 # 直接起動した場合に実行(importで呼んだ場合は起動しない)
 if __name__ == '__main__':
  main()
 


 ・電子ペーパーへの書き込み(main_show_jp.py) ※Python2
 

 # encoding: utf-8
 
 import sys
 import epd7in5b
 from PIL import Image, ImageDraw, ImageFont
 import pytz
 import datetime
 
 EPD_WIDTH = 640
 EPD_HEIGHT = 384
 
 def main():
  
  # 引数取得
  args = sys.argv
  str1 = args[1] #温度、湿度、CO2濃度
  spl1 = str1.split(',')
  
  str_temp = spl1[0]
  str_hum = spl1[1]
  str_co2 = spl1[2]
  
  
  # コメント設定エリア
  comment1 = u"Hallo World!"
  
  # 現在時刻取得
  jp_now = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
  
  epd = epd7in5b.EPD()
  epd.init()
  
  # For simplicity, the arguments are explicit numerical coordinates
  image_red = Image.new('1', (EPD_WIDTH, EPD_HEIGHT), 255) # 255: clear the frame
  draw_red = ImageDraw.Draw(image_red)
  image_black = Image.new('1', (EPD_WIDTH, EPD_HEIGHT), 255) # 255: clear the frame
  draw_black = ImageDraw.Draw(image_black)
  font30 = ImageFont.truetype('/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc', 30)
  font40 = ImageFont.truetype('/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc', 40)
  font45 = ImageFont.truetype('/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc', 45)
  font60 = ImageFont.truetype('/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc', 60)
  
  
  # 表示設定:コメント
  draw_red.text((15, 10), comment1, font = font60, fill = 0)
  
  
  # 表示設定:温度
  draw_black.text((100, 150), u"温度: ", font = font45, fill = 0)
  draw_black.text((260, 150), str_temp, font = font45, fill = 0)
  draw_black.text((380, 150), u"℃", font = font45, fill = 0)
  
  
  # 表示設定:湿度
  draw_black.text((100, 200), u"湿度: ", font = font45, fill = 0)
  if int(str_hum) < 40:
   draw_red.text((260, 200), str_hum, font = font45, fill = 0)
   draw_black.text((340, 200), u"", font = font45, fill = 0)
  else:
   draw_black.text((260, 200), str_hum, font = font45, fill = 0)
   draw_black.text((340, 200), u"", font = font45, fill = 0)
  
  
  # 表示設定:CO2表示
  draw_black.text((100, 250), u"CO2 ", font = font45, fill = 0)
  if int(str_co2) > 1000:
   draw_red.text((260, 250), str_co2, font = font45, fill = 0)
   draw_black.text((400, 250), u"PPM", font = font45, fill = 0)
  else:
   draw_black.text((260, 250), str_co2, font = font45, fill = 0)
   draw_black.text((360, 250), u"PPM", font = font45, fill = 0)
  draw_black.text((380, 320), jp_now.strftime('%m/%d %H:%M ') + u"表示", font = font30, fill = 0)
  
  
  # 電子ペーパーに内容変更命令
  epd.display_frame(epd.get_frame_buffer(image_black),epd.get_frame_buffer(image_red))
  
  
 if __name__ == '__main__':
  main()
 


 ・呼び出しシェル(run.sh)
 

 # cron呼び出しを考慮し、PATHを指定してPythonコードの配置ディレクトリに移動
 cd xxx
 
 co2=`python3 get_netatmo_co2.py`

 python main_show_jp.py $co2
 


 ・cron の設定
 

 # cronの編集
 crontab -e

 # 15分おきにシェルが起動するように設定
 */15 * * * * /xx/run.sh
 


■ 89. 今後の拡張


 ・湿度やCO2が閾値を超えていたら、LEDランプがつくようにしたい。
 ・閾値を超えた時に音を鳴らしても面白いかも。
 ・cronの定期実行以外にも、赤外線リモコンで情報再取得指示(リフレッシュ指示)が出せるようにしたい。
 ・天気情報を表示させたい。


■ 91. 参考サイト


 ほぼ全てについて、色々なサイトを参考にさせていただきました。多謝!

 ・こちらのサイトが電子ペーパーを操作するほぼベースになっています。
  試行錯誤な日々>Raspberry Pie-Paper(電子ペーパー)を動かして日本語を表示する方法


■ 96. つぶやき


 ・cron15分間隔で処理、2ヶ月ほど動かし続けておりますが、問題なく安定稼働しています。
 ・もっと大きな電子ペーパーが欲しくなります。。液晶系と違い、電子ペーパーは見やすくてよいですね。


********


■ 履歴


2019/02/24
新規作成
2019/02/26
3. 必要ライブラリのインストール、環境設定」「11. コーディング」を加筆

■ 【技術メモ】Raspberry Piシリーズ


 ・【技術メモ】Raspberry Pi [01]土台環境構築編〜
 ・【技術メモ】Raspberry Pi [02]電子ペーパー+Netatmoで温湿CO2計パネルを作成当ページ
 ・【技術メモ】Raspberry Pi [03]お帰りなさいカメラ〜作成中

■ 他の記事


>> Next
 ・Comming Soon..
<< Back
 ・【技術メモ】Raspberry Pi [01]土台環境構築編〜
 ・macOS Mojave(10.14)にバージョンアップ!ざっと稼働確認
 ・iPhone XS Maxへの移行!!大きいことはいいことだ(移行手順付き)
 ・Xperia Ear Duo(XEA20)がフリーズ?
 ・回転するバンカーリング?ダメだこりゃ・・・

Top 2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 2009
Mac 書籍と 考えと iPhone 障害対応と