I2C通信の温度センサ(ADT7410)で気温測定。

2024年8月25日

【 当サイトには広告リンクが含まれています。 】


ラズパイPicoW(Raspberry Pi Pico W)に温度センサ(ADT7410)と液晶ディスプレイ(LCD)を接続し、I2C通信を使ってLCDに温度センサで測定した気温を表示させます。



実験準備

実験に必要な環境や部品を準備します。

機器とプログラム

「I2C通信で液晶ディスプレイ(LCD)に文字表示。」の回路に温度センサ(ADT7410)を追加し、プログラムを改造して実験します。


部品

温度センサ(ADT7410)及び液晶ディスプレイ(LCD)、I2CシリアルI/Fモジュールなど実験に使う部品を準備します。(「I2C通信で液晶ディスプレイ(LCD)に文字表示。」と一部、重複しています。)

部 品 名規 格数 量取扱い店(参考)
ADT7410 温度センサモジュール
(ピンヘッダ 要半田付け)
AE-ADT74101秋月電子通商
液晶ディスプレイ(LCD)LCD 1602A1Amazon (セット)
I2CシリアルI/FモジュールLCM1602
ブレッドボードBB-1021秋月電子通商
ジャンパーワイヤオス-メス
(約20cm)
1電子工作ステーション
ジャンパーワイヤオス-オス
(約20cm)
1電子工作ステーション



配線

準備した機器と部品をつなぎ、MicroPythonでプログラミングを行って、温度センサで測定した気温を、液晶ディスプレイ(LCD)に表示させます。

配線リスト

温度センサ、液晶ディスプレイ(LCD)は、I2C通信の同じチャンネルにジャンパーワイヤで接続します。

液晶ディスプレイ(LCD)は5Vで動作しますので、VBUS (5V)に接続し、温度センサ(ADT7410)は2.7V~5.5Vで動作しますので、同様にVBUS (5V)に接続します。


ラズパイPicoW温度センサ(ADT7410液晶ディスプレイ(LCD備 考
GP16SDASDA
GP17SCLSCL
VBUS (5V)VDDVCC
GNDGNDGND


配線図



液晶ディスプレイ(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)


項 目説 明
0I2Cのチャンネル番号(ラズパイ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 00000x1C90
−50°C1 1100 1110 00000x1CE0
−25°C1 1110 0111 00000x1E70
−0.0625°C1 1111 1111 11110x1FFF
0°C0 0000 0000 00000x000
+0.0625°C0 0000 0000 00010x001
+25°C0 0001 1001 00000x190
+50°C0 0011 0010 00000x320
+125°C0 0111 1101 00000x7D0
+150°C0 1001 0110 00000x960


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)を使った、温度測定の計算原理を学びました。