OLEDにセンサ情報を表示する
の続き。
OLED にセンサ情報を表示する
ここまでで、CO₂濃度や気温、湿度を一分毎にデータベースに記録して、グラフを作成する機能ができました。
こうなると、リアルタイムの表示も欲しくなります。
そんなとき、こんなページに辿り着きました。
4pinでブレッドボードに刺すだけで、I²Cで画面を表示することができます。欲しかったのはこれではないですか?
色は、白と青が選べるようです。
また、RGBで出力できる商品もあるようでした。
こちらは I²C ではなく SPI になるようです。画面も少し小さくなります。
今回は、カラーは不要と判断して単色のものにしました。
また部品一個だけで送料を払うのが嫌だったので、amazonで以下を購入しました。
結線
I²C の結線に必要なのは前回の BME280 でブレッドボードに接続済みなので、今回はブレッドボード内の配線のみです。
Pi | OLED |
---|---|
1(3.3v) | VCC |
3(SDA.1) | SDA |
5(SCL.1) | SCL |
6(0v) | GND |
が、OLED は同じ画面を表示し続けると焼き付きが起きると聞くのと、人がいないときにずっと画面を表示し続けるのももったいないので、スイッチを追加することにします。
とりあえず単なるプッシュスイッチを想定していますが、将来的には赤外線人感センサに変えたいと思います。
Pi | スイッチ | センサ |
---|---|---|
4(5v) | - | DC-Input |
7(GPIO.7) | 1 | Vout |
6(0v) | 2 | GND |
配線図
※ 結線、生きたままの状態でやるとすぐに I²C のエラーが出ます。ちゃんと電源を off にしてやった方が良さそうです。
I²C アドレス
接続した上で、i2cdetect
するとアドレスは 0x3c であることがわかりました。
% sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
秋月で買っていないですが、秋月の商品ページを見ると 0x78 または 0x7a と書いてあります。
調べたところ、I²Cのアドレスには 7bit 表記と 8bit 表記があるらしく、8bit 表記の 0x78 は 7bit 表記で 0x3c になるらしいです。
最上位ビットではなく最下位ビットに0を足すってなかなか珍しい気がします。
ちなみに、以下の抵抗を付け替えればアドレスが変えられるので、2台同時運用も可能ですが、こんな小さな抵抗を付け替えるスキルがありません。
GPIO
プッシュスイッチや赤外線センサの入力には GPIO を使います。
Raspberry Pi で GPIO を使うにはいろいろなパッケージやモジュールがあるようですが、今回は gpiozero を使うことにしました。
Raspbian に標準でインストールされているし、他のデーモン(gpiodとか)を動かす必要もないようです。
gpiozero で GPIO のポートを指定するには、gpio readll
で表示される BCM の番号を指定します。
Pin Numbering に詳しく書いてありますが、4 と書く代わりに "4", "GPIO4", "BCM4", "BOARD7", "WPI7" 等と書けるようです。
gpiozero は複数の Pin Factory から選択できるようなのですが、何も指定しないと RPi.GPIO になりました。
OLED
必要なモジュールは adafruit-circuitpython-ssd1306 と pillow。
日本語を描画するためには日本語フォントが、pillow をインストールするには libjpeg が必要です。
sudo apt install fonts-ipafont
suto apt install libjpeg9
実装
以下のポリシーで実装します。
- プッシュスイッチ(人感センサ)がonになったとき
- 画面表示フラグが False だったら画面を表示してフラグを True にする
- プッシュスイッチ(人感センサ)がoffになったとき
- 最終時刻を更新
- 1分に一度のデータ更新時
- 描画用 Image を更新
- 画面表示フラグが True で、スイッチoff時刻から30秒以上経っていたら画面を消し、フラグを False にする
- 画面表示フラグが True ならば画面を表示
- 前回 I²C のアドレスをハードコードしてしまったので、ini ファイルに追い出す
- BME280 の I²C アドレス
- OLED の I²C アドレス
- スイッチ/センサの pin 番号
- 各種センサの有無はコマンドラインオプションにしているけど、iniの方が使いやすいかな?
ソースは、https://github.com/false-git/power-consumption の 33fdb2... のあたり。ディスプレイ関連のコードは oled_ssd1306.py です。
最終的に以下のようになりました。
追記: Raspbian の font について
今回のソースでは参考にした記事に従って /usr/share/fonts/truetype/fonts-japanese-gothic.ttf
を指定したのですが、これは /etc/alternatives/fonts-japanese-gothic.ttf
へのシンボリックリンクになっています。
fonts-ipafont
だけをインストールした状態では、/etc/alternatives/fonts-japanese-gothic.ttf
は /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf
へのリンクになっていますが、もし fonts-takao
をインストールすると /usr/share/fonts/truetype/takao-gothic/TakaoPGothic.ttf
へのリンクに変わってしまいます。
そして、takao フォントは固定幅フォントではないので、期待した出力が得られなくなるかも知れません。
混乱しないためには、今回のような用途では直接 /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf
を指定した方が良かったかも。
この辺の仕組みについては、man update-alternatives
するとわかります。
続きはこちら
Discussion