ラズパイPicoW(Raspberry Pi Pico W)に温度センサ(ADT7410)と液晶ディスプレイ(LCD)を接続し、I2C通信を使ってLCDに温度センサで測定した気温を表示させます。
実験準備
実験に必要な環境や部品を準備します。
機器とプログラム
「I2C通信で液晶ディスプレイ(LCD)に文字表示。」の回路に温度センサ(ADT7410)を追加し、プログラムを改造して実験します。
部品
温度センサ(ADT7410)及び液晶ディスプレイ(LCD)、I2CシリアルI/Fモジュールなど実験に使う部品を準備します。(「I2C通信で液晶ディスプレイ(LCD)に文字表示。」と一部、重複しています。)
部 品 名 | 規 格 | 数 量 | 取扱い店(参考) |
ADT7410 温度センサモジュール (ピンヘッダ 要半田付け) | AE-ADT7410 | 1 | 秋月電子通商 |
液晶ディスプレイ(LCD) | LCD 1602A | 1 | Amazon (セット) |
I2CシリアルI/Fモジュール | LCM1602 | ||
ブレッドボード | BB-102 | 1 | 秋月電子通商 |
ジャンパーワイヤ | オス-メス (約20cm) | 1 | 電子工作ステーション |
ジャンパーワイヤ | オス-オス (約20cm) | 1 | 電子工作ステーション |
AE-ADT7410の概要は秋月電子通商さん提供のマニュアルを参考にしてください。
配線
準備した機器と部品をつなぎ、MicroPythonでプログラミングを行って、温度センサで測定した気温を、液晶ディスプレイ(LCD)に表示させます。
配線リスト
温度センサ、液晶ディスプレイ(LCD)は、I2C通信の同じチャンネルにジャンパーワイヤで接続します。
液晶ディスプレイ(LCD)は5Vで動作しますので、VBUS (5V)に接続し、温度センサ(ADT7410)は2.7V~5.5Vで動作しますので、同様にVBUS (5V)に接続します。
ラズパイPicoW | 温度センサ(ADT7410) | 液晶ディスプレイ(LCD) | 備 考 |
GP16 | SDA | SDA | |
GP17 | SCL | SCL | |
VBUS (5V) | VDD | VCC | |
GND | GND | GND |
配線図
液晶ディスプレイ(LCD)とI2CシリアルI/Fモジュールは、ブレッドボード内部の配線で接続します。
I2Cアドレスを確認
液晶ディスプレイ(LCD)の I2Cアドレスは、「I2C通信で液晶ディスプレイ(LCD)に文字表示。」で「0x27」と確認されていますので、温度センサ(ADT7410)の I2Cアドレスを確認します。
Raspi4BのThonnyを起動し、次のコードを「エディタ」に入力するか、リストをコピーしてペーストします。
#モジュールの読み込み(インポート)
from machine import Pin, I2C
#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)
#I2Cのアドレス確認(16進数)
for addr in i2c.scan():
print("I2C 16進法アドレス: ", hex(addr))
Thonnyの「F5」キーを押して、プログラムを実行します。
「I2C 16進法アドレス: 0x27」、「I2C 16進法アドレス: 0x48」がThonnyのシェルに表示されます。
温度センサ(ADT7410)の I2Cアドレスは「0x48」であることが確認できます。
確認後、Thonnyの「Ctrl + F2」キーを押して、停止します。
気温測定プログラム
温度センサ(ADT7410)は、測定した温度を、内臓のA/Dコンバータで、13ビットまたは16ビットのディジタルデータに変換し、I2C通信を使ってラズパイPicoWなどのコンピュータに提供します。
ラズパイPicoWは読み込んだディジタルデータを処理し、温度を摂氏として液晶ディスプレイ(LCD)に表示します。
Raspi4BのThonnyを起動し、次のコードを「エディタ」に入力するか、リストをコピーしてペーストします。
#モジュールの読み込み(インポート)
from machine import Pin, I2C
from pico_i2c_lcd import I2cLcd
from time import sleep
#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)
#温度センサ(ADT7410)のパラメータを設定
TMP_ADR = 0x48
#液晶ディスプレイ(LCD)のパラメータを設定
LCD_ADR = 0x27
LCD_ROW = 2
LCD_COL = 16
#LCDを利用するため、オブジェクト(lcd)を作成
lcd = I2cLcd(i2c, LCD_ADR, LCD_ROW, LCD_COL)
#メイン処理
#例外処理(「Ctrl + c」キーにより中断)を設定
try:
while True:
#********** 温度測定 **********
#ADT7410の温度データ(2バイト)を読込
raw = i2c.readfrom_mem(TMP_ADR, 0x00, 2)
#上位バイト
msb = raw[0]
#下位バイト
lsb = raw[1]
#バイト連結と13ビット読出しの補正
temp = ((msb << 8) | lsb) >> 3
#4096以上は8192を引いて負の値に変換
if(temp >= 4096):
temp = temp - 8192
#温度に変換
temp = temp / 16
#********** 液晶ディスプレイ(LCD)に温度を表示 **********
#表示位置を初期化
lcd.move_to(0, 0)
#LCDに小数点第一位までの温度を表示
lcd.putstr("TEMP:{:.1f}".format(temp))
#℃表示
ch=[
#°
bytearray([0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00]),
#C
bytearray([0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E, 0x00])
]
for i in range(len(ch)):
lcd.custom_char(i, ch[i])
lcd.putchar(chr(i))
#1秒待つ
sleep(1)
#「Ctrl + c」キーにより中断。
except KeyboardInterrupt:
# Turn off the display
print("「Ctrl + c」キーが押されました。")
#LCD消灯
lcd.backlight_off()
lcd.display_off()
Thonnyの「F5」キーを押して、文字表示プログラムを実行します。
気温測定プログラムは、温度センサ(ADT7410)の測定した温度を、小数点第一位までの数値として、液晶ディスプレイ(LCD)に表示します。
確認後、Thonnyの「Ctrl + c」キーを押すと、液晶ディスプレイ(LCD)が消灯し、処理が中断しますので、中断後、「Ctrl + F2」キーを押して、プログラムを終了させます。
任意のファイル名でラズパイPicoWに保存します。(ここでは「3_7i2ctmprtr.py」で保存しました。)
プログラムの仕組み
温度センサ(ADT7410)や液晶ディスプレイ(LCD)と、どのようにやり取りをするのか、プログラムの動きを簡単に見ていきます。
▶️モジュールの読み込み(インポート)
温度センサ(ADT7410)や液晶ディスプレイ(LCD)とI2C通信するために必要なモジュールを読み込みます。
液晶ディスプレイ(LCD)と通信をするために、GitHubユーザー(T-622)が開発したライブラリ、「 lcd_api.py」と「 pico_i2c_lcd.py」の2種類のモジュールを組み合わせて使います。
ライブラリが保存されていない場合は、こちらの手順で保存してください。
from machine import Pin, I2C
from pico_i2c_lcd import I2cLcd
from time import sleep
▶️I2Cを利用するため、オブジェクト(i2c)を作成
温度センサ(ADT7410)や液晶ディスプレイ(LCD)とI2C接続するGP16とGP17を初期化します。
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)
項 目 | 説 明 |
0 | I2Cのチャンネル番号(ラズパイPicoWの場合は0または1) |
sda=Pin(16) | SDA(シリアルデータ)として使うGPピン番号 |
scl=Pin(17) | SCL(シリアルクロック)として使うGPピン番号 |
freq=400000 | 通信速度(400000bps=400kbps) (温度センサ、液晶ディスプレイは400kbpsで通信が可能です。) |
▶️温度センサ(ADT7410)のパラメータを設定
温度センサ(ADT7410)のI2Cアドレス(0x48)を設定します。
TMP_ADR = 0x48
▶️LCDのパラメータを設定
液晶ディスプレイ(LCD)のI2Cアドレス(0x27)と表示範囲(2行16列)を設定します。
LCD_ADR = 0x27
LCD_ROW = 2
LCD_COL = 16
▶️LCDを利用するため、オブジェクト(lcd)を作成
液晶ディスプレイ(LCD)に文字を表示させるため、I2cLcd() 関数を使ってオブジェクト(lcd)を作成し、i2c オブジェクト、アドレス(ADR)、行数(ROW)と列数(COL)を引数として渡します。
lcd = I2cLcd(i2c, LCD_ADR, LCD_ROW, LCD_COL)
▶️例外処理(「Ctrl + c」キーにより中断)を設定
メイン処理は「while」文を使った無限ループの中で、1秒ごとに温度センサ(ADT7410)からデータを読み込み、計算した温度を摂氏として液晶ディスプレイ(LCD)に表示します。
「Ctrl + c」キーを押して、無限ループを抜けるために、KeyboardInterrupt例外「try … except KeyboardInterrupt: …」を利用します。
try:
while True:
#********** 温度測定 **********
・・・
・・・
#********** 液晶ディスプレイ(LCD)に温度を表示 **********
・・・
・・・
except KeyboardInterrupt:
・・・
▶️ADT7410の温度データ(2バイト)を読込
温度センサ(ADT7410)のデータは2バイト(16ビット)で構成されているため、指定のメモリーアドレス(0x00)から、i2cオブジェクトのreadfrom_mem()メソッドを使って、2バイト分を読み込みます
raw = i2c.readfrom_mem(TMP_ADR, 0x00, 2)
▶️上位バイト
上位バイトを設定します。
msb = raw[0]
▶️下位バイト
下位バイトを設定します。
lsb = raw[1]
▶️バイト連結と13ビット読出しの補正
温度センサ(ADT7410)は13ビットまたは16ビットのデータを提供しますが、初期状態は13ビットの提供になっていますので、読み込んだ2バイト(16ビット)のデータの内、下位3ビットが不要となります。
今回は初期状態の13ビットで処理を行うため、上位バイトを8ビット左へシフトさせ、下位バイトをつないで、2バイト(16ビット)のデータを作成します。
不要の下位3ビットを右へシフトさせることで、16ビット中、下位13ビットが有効データとなります。
temp = ((msb << 8) | lsb) >> 3
▶️4096以上は8192を引いて負の値に変換
有効データ13ビットの内、最上位ビットは符号ビットであるため、温度の値は12ビット(0~4096)で表現されます。
13ビットのデータで、−55°C~+150°Cの範囲の温度を、0.0625°C刻みで表わすことができます。
次の表は、温度とデータとの関連です。
温 度 | ディジタルデータ(2進数) | ディジタルデータ(16進数) |
-55℃ | 1 1100 1001 0000 | 0x1C90 |
−50°C | 1 1100 1110 0000 | 0x1CE0 |
−25°C | 1 1110 0111 0000 | 0x1E70 |
−0.0625°C | 1 1111 1111 1111 | 0x1FFF |
0°C | 0 0000 0000 0000 | 0x000 |
+0.0625°C | 0 0000 0000 0001 | 0x001 |
+25°C | 0 0001 1001 0000 | 0x190 |
+50°C | 0 0011 0010 0000 | 0x320 |
+125°C | 0 0111 1101 0000 | 0x7D0 |
+150°C | 0 1001 0110 0000 | 0x960 |
if(temp >= 4096):
temp = temp - 8192
▶️温度に変換
下位4ビットは小数点を表わすビットになっているため、16で除算し、最終的に13ビットのデータを、小数点第四位を含めた温度に変換します。
temp = temp / 16
次の図は、温度センサ(ADT7410)から、「0x00番地(msb)= 0x0b、0x01番地(lsb)= 0xa0」のデータを読み込んだ時の温度の算出過程です。
以下は温度を液晶ディスプレイ(LCD)に表示させるのプログラムです。詳しい表示方法については、「I2C通信で液晶ディスプレイ(LCD)に文字表示。」を参照してください。
▶️表示位置を初期化
文字を表示する位置の設定は、lcdオブジェクトのmove_to()関数を使い、列の位置(0~15)と、行の位置(0は上段、1は下段)を引数として渡します。
lcd.move_to(0, 0)
▶️LCDに小数点第一位までの温度を表示
温度データは小数点第四位まで出力されますが、lcd オブジェクトの putstr() 関数の引数として、温度データを渡し、formatメソッドで小数点第一位までの表示に整形します。
lcd.putstr("TEMP:{:.1f}".format(temp))
▶️℃表示
摂氏温度の単位(℃)を特殊文字として作成し、追加表示ます。
ch=[
#°
bytearray([0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00]),
#C
bytearray([0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E, 0x00])
]
for i in range(len(ch)):
lcd.custom_char(i, ch[i])
lcd.putchar(chr(i))
▶️1秒待つ
1秒ごとに、温度センサ(ADT7410)からデータを読み込み、計算した温度を摂氏として、液晶ディスプレイ(LCD)に表示します。
sleep(1)
▶️「Ctrl + c」キーにより中断。
「Ctrl + c」キーを押すと、「KeyboardInterrupt」例外が発生し、液晶ディスプレイ(LCD)消灯後、処理が中断します。
except KeyboardInterrupt:
# Turn off the display
print("「Ctrl + c」キーが押されました。")
#LCD消灯
lcd.backlight_off()
lcd.display_off()
まとめ
ラズパイPicoW(Raspberry Pi Pico W)に温度センサ(ADT7410)と液晶ディスプレイ(LCD)を接続し、I2C通信を使って、温度センサで測定した気温を、液晶ディスプレイ(LCD)に表示させました。
I2C通信の同じチャンネルに接続された、デバイスの制御方法を学びました。
温度センサ(ADT7410)を使った、温度測定の計算原理を学びました。