Raspberry で I2C シリアル OLED 液晶ディスプレイに表示

Raspberry PI と言えば、簡単にネットに接続できる為、見る機能はスマホで…が想像しやすいですが、全てを電子工作する…もちろん、そんな使い方もあります。今回は、温湿度を取得して、小さな液晶に表示したいと思います。


**今回の目標**
温湿度の取得は、[Raspberry で気温と湿度を監視しよう（DHT11）](https://qiita.com/MasahiroShouya/items/56e9fa9f1a2e7969b27a)を参考にします。取得した温湿度を、シリアルOLEDに表示します。
![OLED.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3878922/5d88ff3d-2b1c-0732-f4df-71d038204fa3.png)


**Raspberry の準備**
Raspberry Pi OS は Lite を利用します。
配線は、シリアルOLEDがI2Cを使うので、VCC（1番ピン3.3v）SDA（3番ピンSDA）SCL（5番ピンSCL）GND（9番ピン）で接続します。
DHT11は、vcc（2番ピン）data（8番ピン）と、GND（14番ピン）を接続します。
接続本数が多い時は、ブレッドボードを利用して、GND等はまとめたりしても良いです。
GNDに寒色配線、VCCに暖色配線等、こだわるのも粋な気がします。


**環境設定（初期設定と液晶の確認）**
sudo apt-get update　（お約束①）
sudo apt-get upgrade　（お約束②）
sudo mkdir /test　（作業用ディレクトリ）
sudo mkdir /test/OLED　（作業用ディレクトリの小分け）
sudo apt-get install fonts-ipafont　（日本語フォントの導入）
cd /test/OLED　（カレントディレクトリ移動）
sudo python3 -m venv venv　（仮想実装）
sudo chmod 777 -R /test　（使い易いように権限を落とします）
source /test/OLED/venv/bin/activate　（仮想起動）
sudo raspi-config　（設定画面を起動）
　　3 Interface Options　（インタフェースオプションを変更します）
　　I5 I2C　（YesでI2Cを有効化）
sudo apt-get install i2c-tools　（I2Cの正常稼働を確認します）
sudo i2cdetect -y 1　（I2Cのチェック）
I2Cのアドレスが表示されますが、「3C」という文字が表示されます。
sudo apt-get install pip　（デフォルトのpipを補填します）
pip install RPi.GPIO　（仮想環境にGPIOのパッケージを用意します）
pip install adafruit-circuitpython-ssd1306　（OLED用ライブラリ導入）
pip install adafruit-blinka　（OLED用ライブラリ導入）
pip install Pillow　（画像用ライブラリ導入）
ここまで準備が出来たら、まず、シリアルOLEDが動作するか、次のプログラムを実行して確認しましょう。

```diff_python:test1.py
import board
import busio
import adafruit_ssd1306
from PIL import Image, ImageDraw, ImageFont

i2c = busio.I2C(board.SCL, board.SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3C)

display.fill(0)
display.show()

text1 = "温度 ： "
text2 = "湿度 ： "
font = ImageFont.truetype("fonts-japanese-gothic.ttf", 16)
image = Image.new("1", (display.width, display.height))
draw = ImageDraw.Draw(image)
draw.text((0, 0), text1, font=font, fill=255)
draw.text((0, 16), text2, font=font, fill=255)
display.image(image)
display.show()
```
python test1.py　（実行してみましょう）
液晶に、それっぽい文字が表示されましたか？


**環境設定（DHT11）**
sudo apt-get install git　（Gitの利用の為インストール）
git clone https://github.com/szazo/DHT11_Python.git
（Gitに公開されているプログラムを利用させて頂きましょう）
cd DHT11_Python
python example.py　（実行してDHT11の正常稼働を確認）
温湿度が正常に表示されれば、DHT11も準備OKです。


**実装（２つを合体）**
cp example.py OLED.py　（コピーして修正します）
```diff_python:OLED.py
import RPi.GPIO as GPIO
import dht11
import time
import datetime
import board
import busio
import adafruit_ssd1306
from PIL import Image, ImageDraw, ImageFont

GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
instance = dht11.DHT11(pin=14)
i2c = busio.I2C(board.SCL, board.SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3C)
display.fill(0)
display.show()
font = ImageFont.truetype("fonts-japanese-gothic.ttf", 16)
image = Image.new("1", (display.width, display.height))
draw = ImageDraw.Draw(image)

try:
        while True:
            result = instance.read()
            if result.is_valid():
                print("Last valid input: " + str(datetime.datetime.now()))
                print("Temperature: %-3.1f C" % result.temperature)
                print("Humidity: %-3.1f %%" % result.humidity)
                draw.text((0, 0), "温度： %-3.1f C" % result.temperature, font=font, fill=255)
                draw.text((0, 16), "湿度： %-3.1f %%" % result.humidity, font=font, fill=255)
                display.image(image)
                display.show()

            time.sleep(6)
            display.fill(0)
            display.show()

except KeyboardInterrupt:
    print("Cleanup")
    GPIO.cleanup()
    display.fill(0)
    display.show()
```
python OLED.py　（実行します）
液晶に、温度と湿度が表示されたら終わりです。
お疲れ様でした～