e-DIY
センサー

温湿度センサーで取得した値をLCDに表示する

温湿度をLCDに表示

これまでに、温湿度センサーを使って温度と湿度を取得したり、LCDに文字や数字を表示させたりしてきました。

これらの2つのプログラムを組み合わせて、温湿度センサーで取得した値をLCDに表示させてみたいと思います。

Pythonコード

コードはこのようにしました。

import smbus
import time
import RPi.GPIO as GPIO
import dht11

# パラメータ設定
I2C_ADDR  = 0x27       # PCF8574のアドレス
LCD_WIDTH = 16         # 1行に表示する文字数の上限
LCD_CMD = 0x00         # コマンド送信モード
LCD_CHR = 0x01         # データ送信モード
LCD_LINE_1 = 0x80      # 1行目のRAMアドレス
LCD_LINE_2 = 0xC0      # 2行目のRAMアドレス
LCD_BACKLIGHT  = 0x08  # バックライトOFF


bus = smbus.SMBus(1)   # SMBusの引数に1を指定する。ラズパイのI2Cバスの番号

# initialize GPIO
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)

# read data using pin 17
instance = dht11.DHT11(pin=17) # GPIO14を使用

def lcd_init():
  lcd_byte(0x33,LCD_CMD,0.005,0.0001)  # 初期化(0011を2回)
  lcd_byte(0x32,LCD_CMD,0.0001,0.0001) # 初期化(0011、0010で4bitモードに設定)
  lcd_byte(0x06,LCD_CMD,0.0001,0.0001) # データ書き込み時にカーソルを右にシフト
  lcd_byte(0x0C,LCD_CMD,0.0001,0.0001) # ディスプレイ・オン、カーソル&BLINK・オフ
  lcd_byte(0x28,LCD_CMD,0.0001,0.0001) # 2列 5x7ドット
  lcd_byte(0x28,LCD_CMD,0.0001,0.0001) 
  lcd_byte(0x01,LCD_CMD,0.0001,0.002)  # 全表示クリア、カーソルをホーム位置に戻す
  time.sleep(0.0005)
  
def lcd_byte(bits, mode, tw1, tw2):
  upper_bits = mode | (bits & 0xF0) | LCD_BACKLIGHT         # 上位4bit(下位4bitを0にする)
  lower_bits = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT    # 下位4bit(4bitシフトさせてから下位4bitを0にする)
  bus.write_byte(I2C_ADDR, upper_bits)                      # 上位4bitを書き込み
  lcd_toggle_enable(upper_bits, tw1, tw2)
  bus.write_byte(I2C_ADDR, lower_bits)                      # 下位4bitを書き込み
  lcd_toggle_enable(lower_bits, tw1, tw2)

# E(Enable)信号をトグル(LOW→HIGH→LOW)
def lcd_toggle_enable(bits, tw1, tw2):
  time.sleep(0.0005)
  bus.write_byte(I2C_ADDR, (bits | 0b00000100))
  time.sleep(tw1)
  bus.write_byte(I2C_ADDR,(bits & 0b11111011))
  time.sleep(tw2)

def cgram_write(): #「°」をCGRAMに書き込む
  lcd_byte(0b01000000,LCD_CMD,0.001,0.0001)  #CGRAMアドレス指定
  lcd_byte(0x07,LCD_CHR,0.001,0.0001)        #1行目のデータ送信
  lcd_byte(0x05,LCD_CHR,0.001,0.0001)        #2行目のデータ送信
  lcd_byte(0x07,LCD_CHR,0.001,0.0001)        #3行目のデータ送信
  lcd_byte(0x00,LCD_CHR,0.001,0.0001)        #4行目のデータ送信
  lcd_byte(0x00,LCD_CHR,0.001,0.0001)        #5行目のデータ送信
  lcd_byte(0x00,LCD_CHR,0.001,0.0001)        #6行目のデータ送信
  lcd_byte(0x00,LCD_CHR,0.001,0.0001)        #7行目のデータ送信
  lcd_byte(0x00,LCD_CHR,0.001,0.0001)        #8行目のデータ送信

def lcd_string(message,line):
  message = message.ljust(LCD_WIDTH," ")
  lcd_byte(line,LCD_CMD,0.0001,0.0001)
  for i in range(LCD_WIDTH):
    if ord(message[i]) > 0x7D:
        lcd_byte(0x00,LCD_CHR,0.0001,0.0001)
    else:
        lcd_byte(ord(message[i]),LCD_CHR,0.0001,0.0001) # 文字のunicodeを送信

def main():
    lcd_init()
    cgram_write()
    while True:
        result = instance.read()
        if result.is_valid(): # データを正常に取得できたら
            lcd_string("TEMP %-3.1f °C" % result.temperature, LCD_LINE_1) # 1行目に表示する文字
            lcd_string("HUM  %-3.1f %%" % result.humidity, LCD_LINE_2)     # 2行目に表示する文字
            
        time.sleep(3) # データ取得間隔

if __name__ == '__main__':
  try:        
    main()
  except KeyboardInterrupt:
    pass
  finally:
    LCD_BACKLIGHT = 0x00                 # バックライトOFF
    lcd_byte(0x01,LCD_CMD,0.0001,0.0001) # LCDの表示内容をクリア
    GPIO.cleanup()

詳細は過去の2つの記事をご覧ください。

自分で作った記号を登録する

摂氏温度の単位記号「℃」はLCD1602のデフォルトの文字に登録されていません。
「゜」と「C」を組み合わせればできそうですが、「゜」が左寄りになっているため、ちょっと違和感があります。

℃を表示

そこで、右寄りの「°」を自分で作って登録してみたいと思います。

CGRAMとは

CGRAMとは、Character Generator RAMの略で、ユーザーが自由に文字を作って登録するためのメモリです。
RAMは読み書きができるメモリですが、電源を切ると書き込んだ内容が消えてしまうので、毎回書き込む必要があります。

今回使ったLCD1602モジュールでは、8つの文字や記号などを登録することができます。

CGRAMに記号を登録

CGRAMは、000~111までの8つのアドレス(CGRAM ADDRESS)を選んで記号を登録することができます。
そして、白色に表示させたい部分を「1」としてCGRAM DATAを決めます。

CGRAM DATA

先程のプログラムの52~60行目が該当します。

今回は「°」しか使わないので、ちょっと雑ですがord関数の値が0x7D(「→」の記号)より大きければ「°」を表示し、それ以外はord関数で変換した値を送信します。

先程のプログラムの66~69行目が該当します。

温湿度の表示結果

「℃」の表示が見やすくなりました!

CGRAMで℃を表示

関連キーワード

フリーワード検索