目次
温湿度機能の実装
必要なモジュール
今回は、DHT22という温湿度センサのモジュールを使用する。
サンプル配線
今回の温湿度計モジュールは3V電源、GND、信号ラインの3本を接続する必要がある。
今回は信号線を4pin(GP2)に接続して使用する。

サンプルコード
まずは、Thonny上で温湿度を出力するサンプルコードで動作を確認する。
import machine
import dht
import time
# DHT22を接続するピンを指定(例: GP2)
dht_pin = machine.Pin(5)
sensor = dht.DHT22(dht_pin)
while True:
try:
sensor.measure() # 測定を実行
temperature = sensor.temperature() # 温度を取得(摂氏)
humidity = sensor.humidity() # 湿度を取得
print(f"Temperature: {temperature:.1f}°C, Humidity: {humidity:.1f}%")
except OSError as e:
print("Failed to read sensor.", e)
time.sleep(2) # 2秒ごとに測定
上記のサンプルコードで実行すると、温湿度が2秒おきに出力される。

LCDと温湿度計の併用
このままでは、温湿度の確認に必ずPCが必要となる。今回は、PCなしで表示までできるようにしていく。
そのためにラズパイPicoにLCDモジュールを接続する。
使用するLCD
今回使用するのは、以下のLCD。セットアップの詳細は以前の記事を参照。
LCDモジュールで使用しているヘッダーピン
LCDモジュールと温湿度モジュールを併用する上で、まず考えないといけないのが、LCDモジュールがラズパイPicoのヘッダーピンのどのピンを実際に使用しているのかの確認である。
LCDモジュールは40pinヘッダーソケットを介して、ラズパイPicoと接続される。
しかしながら、実際のところ40pinすべてを使用しているわけではない。
下記の製品ページを見ると、4,5,11,12,14,15,16,17,20,21,22,24,26,39のピンと、どこか一か所のGNDが接続されていれば良い模様。


ヘッダーピンの改造
LCDモジュールで使用しない部分のピンをL字に曲げる。
今回は、pin7(GP5)と、pin8(GND)と、pin36(3V電源ライン)を温湿度計用に使用する。

その後、折り曲げたヘッダーピン以外の部分に、ヘッダーソケットを一段追加。


LCDモジュール+温湿度計モジュールとの接続
温湿度計モジュールとの接続としては以下のイメージ。
その他のピンはLCDモジュールと接続されている。

サンプルコード
from machine import Pin, SPI, PWM
import framebuf
import dht
import time
# 定数の設定(LCDのピン番号)
BL = 13
DC = 8
RST = 12
MOSI = 11
SCK = 10
CS = 9
DHT_PIN = 5 #DHT22のデータピン
class LCD_1inch14(framebuf.FrameBuffer):
def __init__(self):
# LCDの解像度
self.width = 240
self.height = 135
# ピンの初期化
self.cs = Pin(CS, Pin.OUT)
self.rst = Pin(RST, Pin.OUT)
# SPI通信の初期化
self.cs(1)
self.spi = SPI(1)
self.spi = SPI(1,1000_000)
self.spi = SPI(1,10000_000,polarity=0, phase=0,sck=Pin(SCK),mosi=Pin(MOSI),miso=None)
self.dc = Pin(DC,Pin.OUT)
self.dc(1)
# フレームバッファの作成
self.buffer = bytearray(self.height * self.width * 2)
super().__init__(self.buffer, self.width, self.height, framebuf.RGB565)
# LCDの初期化
self.init_display()
# カラー定義
self.red = 0x07E0
self.green = 0x001f
self.blue = 0xf800
self.white = 0xffff
def write_cmd(self, cmd):
"""LCDにコマンドを送信"""
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
"""LCDにデータを送信"""
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(bytearray([buf]))
self.cs(1)
def init_display(self):
"""LCDの初期設定"""
self.rst(1)
self.rst(0)
self.rst(1)
self.write_cmd(0x36)
self.write_data(0x70)
self.write_cmd(0x3A)
self.write_data(0x05)
self.write_cmd(0xB2)
self.write_data(0x0C)
self.write_data(0x0C)
self.write_data(0x00)
self.write_data(0x33)
self.write_data(0x33)
self.write_cmd(0xB7)
self.write_data(0x35)
self.write_cmd(0xBB)
self.write_data(0x19)
self.write_cmd(0xC0)
self.write_data(0x2C)
self.write_cmd(0xC2)
self.write_data(0x01)
self.write_cmd(0xC3)
self.write_data(0x12)
self.write_cmd(0xC4)
self.write_data(0x20)
self.write_cmd(0xC6)
self.write_data(0x0F)
self.write_cmd(0xD0)
self.write_data(0xA4)
self.write_data(0xA1)
self.write_cmd(0xE0)
self.write_data(0xD0)
self.write_data(0x04)
self.write_data(0x0D)
self.write_data(0x11)
self.write_data(0x13)
self.write_data(0x2B)
self.write_data(0x3F)
self.write_data(0x54)
self.write_data(0x4C)
self.write_data(0x18)
self.write_data(0x0D)
self.write_data(0x0B)
self.write_data(0x1F)
self.write_data(0x23)
self.write_cmd(0xE1)
self.write_data(0xD0)
self.write_data(0x04)
self.write_data(0x0C)
self.write_data(0x11)
self.write_data(0x13)
self.write_data(0x2C)
self.write_data(0x3F)
self.write_data(0x44)
self.write_data(0x51)
self.write_data(0x2F)
self.write_data(0x1F)
self.write_data(0x1F)
self.write_data(0x20)
self.write_data(0x23)
self.write_cmd(0x21)
self.write_cmd(0x11)
self.write_cmd(0x29)
def show(self):
"""LCDにバッファの内容を描画"""
self.write_cmd(0x2A)
self.write_data(0x00)
self.write_data(0x28)
self.write_data(0x01)
self.write_data(0x17)
self.write_cmd(0x2B)
self.write_data(0x00)
self.write_data(0x35)
self.write_data(0x00)
self.write_data(0xBB)
self.write_cmd(0x2C)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(self.buffer)
self.cs(1)
def text_scaled(self, text, x, y, color, scale=1):
"""拡大表示するテキスト描画関数"""
# 一時的なフレームバッファを作成(文字描画用)
temp_fb = framebuf.FrameBuffer(bytearray(8 * len(text) * 8), 8 * len(text), 8, framebuf.MONO_HLSB)
temp_fb.fill(0) # 背景をクリア
temp_fb.text(text, 0, 0, 1) # 文字を描画
# 各ピクセルを拡大して描画
for yy in range(8):
for xx in range(8 * len(text)):
if temp_fb.pixel(xx, yy): # 文字のピクセルがある場合
self.fill_rect(x + xx * scale, y + yy * scale, scale, scale, color)
if __name__ == '__main__':
# LCDのバックライト設定
pwm = PWM(Pin(BL))
pwm.freq(1000)
pwm.duty_u16(32768) # 最大値65535の半分
# LCDの初期化
LCD = LCD_1inch14()
# DHT22の初期化
sensor = dht.DHT22(Pin(DHT_PIN))
while True:
try:
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
# 画面クリア
LCD.fill(LCD.white)
# 温度・湿度を表示
LCD.text_scaled("Temp", 10, 10, LCD.blue, scale=2)
LCD.text_scaled(f"{temp:.1f}C", 30, 30, LCD.blue, scale=4)
LCD.text_scaled("Hum", 10, 70, LCD.green, scale=2)
LCD.text_scaled(f"{hum:.1f}%", 30, 90, LCD.green, scale=4)
# 画面更新
LCD.show()
time.sleep(2)
except Exception as e:
print("DHT22 Error:", e)
以上のコードを実行すると、下図のように温湿度がLCD画面に表示され、2秒ごとに更新される。

これで、PCなしでも温湿度を確認することが可能となった。