室内温度の測定(ADT7410使用モジュールとPHP)~ ラズベリーパイ研究室

今回は温度センサモジュールを使って、Raspberry Pi で室内温度を測定してみようと思います。

温度センサモジュールは ADT7410キット を使用しました。16bit の温度センサで -55℃~+150℃まで計測できるようです。殆どの部品は既にハンダ付け済みですが、接続用の端子について4箇所のハンダ付けが必要になるでしょう。

おススメ!記事
Raspberry Pi 用「HAL」で、
カップラーメン・タイマーを作ってみよう!
ラズパイDIYの決定版! ソケットサーバー「HAL」をご紹介します。

※誠に申し訳ありませんがこちらの電子工作のコンテンツは弊社の実験制作例となっております。十分な安全が保障されているわけではないため、参照や実施は自己責任となってしまいますのでご注意ください。

室内温度の測定(ADT7410使用モジュールとPHP)

今回は温度センサモジュールを使って、Raspberry Pi で室内温度を測定してみようと思います。

温度センサモジュールは ADT7410キット を使用しました。16bit の温度センサで -55℃~+150℃まで計測できるようです。殆どの部品は既にハンダ付け済みですが、接続用の端子について4箇所のハンダ付けが必要になるでしょう。

ADT7410使用 高精度・高分解能 I2C・16Bit 温度センサモジュール(秋月電子通商)

ADT7410使用 高精度・高分解能 I2C・16Bit 温度センサモジュール

I2C の有効化

Raspbian Jessie の場合は、X window で I2C の有効化が出来るようです。(恐らく今までどおり、raspi-config でも出来るでしょう)

sudo startx

Raspberry Pi の設定

Menu > 設定 > Raspberry Pi の設定 で設定画面が開くので、そこのインターフェイスタブで I2C を「有効」にしてください。OK をクリックすると再起動を促されます。

  インターフェイス設定画面

再起動すると、I2C 通信が行えるようになっていると思います。

I2C ライブラリの導入

I2C 通信を簡単に行うには i2c-dev を有効にして下さい。(これは既に有効になっているかもしれません。また Raspbian のバージョンにより他のモジュールも必要かもしれません)

sudo vi /etc/modules

以下の行があるか確認し、なければ追加して下さい。(行頭に#がある場合はコメントになっていますので、#を削除してください)

i2c-dev

また、/boot/config.txt についても、「dtparam=i2c_arm=on」をアンコメントまたは追記して下さい。

sudo vi /boot/config.txt
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

変更があった場合は、再起動するとこれらが有効になります。

あとは、i2c-tools をインストールします。

sudo apt-get install i2c-tools

温度センサモジュールの接続

温度センサモジュールには4つの端子があり、それぞれ VDD、SCL、SDA、GND となっています。どの端子がどれかは基盤に書いてありますが、かなり細かい文字です。老眼が始まっている私には結構きついので、ヘッドマウントルーペを利用しています。

ヘッドルーペ

デザインがあんまりよくありませんので、目が悪い人でもっとカッコいいものが良い人は Amazon などで購入するのも良いでしょう。倍率もさまざまなものがあります。

なお、温度センサモジュールには当然仕様書もついていて、端子の順番はそれではっきりと分かります。

温度センサモジュール仕様書

ADT7410 は 2.7V~5.5V の電圧で動作するそうですので、VDD には 3.3V でも 5V でも良さそうです。であれば、Raspberry Pi の GPIO の耐圧である 3.3V を繋いだほうが良さそうですね。私は 1 番ピンに繋ぎました。

SDA は Raspberry Pi では 3 番ピン、SCL は 5 番ピンです。GND は沢山ありますが、他のピンに一番近い 6 番ピンが良さそうです。

デバイスが利用できるか確認

温度センサモジュールを接続したら、Raspberry Pi で認識できるかテストしてみましょう。

sudo i2cdetect -y 1

正常に利用できれば、次のようなレスポンスが返るはずです。

pi@raspberrypi:~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

i2cdetect -y 1 の最後の 1 ですが、Raspberry Pi でI2C: 温度センサーを使う|猫ぱーんち! さんのところによると、Raspberry Pi のリビジョンによって 0 や 1 になるようです。ここのところは私にはちょっと良くわかりませんでしたが、私の Pi3 では 1 でした。(0 と 1 両方試してエラーが出ない方が正解、といった内容のページは見つかりましたが、さらっと探しただけでは対応表は見つかりませんでした。すみません)

ADT 7410キットの仕様書を見るとわかりますが、デフォルトでは I2C バスアドレスとして 0x48 を利用します。

※なお、これはハンダ付けで回路をショートさせる事により、0x49、0x4A、0x4Bに変更することが可能のようです。

さて、上記のように 0x48 で認識していることを確認したら

sudo i2cget -y 1 0x48 0x00 w

で、温度が取得できます。

上記コマンドの i2cget の説明ですが、Rasberry PIのI2Cコマンド詳解|かないノート さんの記事によると、0x48 にまず、0x00 を書き込み、その後で 0x48 から読み出しを行うということのようです。w は恐らく word モードということだと思うのですが、I2C 通信についてはよく知らないので、Raspberry Pi でI2C: 温度センサーを使う|猫ぱーんち! さんのところをそのまま参考にしました。

とにかく、上記を実行すると

0x780c

こんな感じの 2 バイトのデータが返されます。これが温度なのですが少々ややこしく、まず 16 進数な事はお分かりになると思います。冒頭で述べたとおり、ADT7410 は-55℃~+150℃まで計測 可能なので、温度は signed(符号付き)です。

そして、この値はリトルエンディアンとなっており、上記の場合2バイトの前後を入れ替えて、計測温度は 0x0c78 を 10 進数にした値から得られます。

参考)エンディアン

この ADT7410 キットは 16 bit モードで動作しているようで、こうして得られた値を 128 で割ると測定した温度が分かる、ということのようです。

参考)I2C温度センサADT7410を使う(2)|wsnakのブログ

上記では負数の場合、65536を減算した値を 128 で除算 していますが、PHP では hexdec() というメソッドがあり、16 進数を表す文字列をそのまま渡すだけで符号付きの整数が得られます。

つまり、こうなります。

<?php

$read = system("sudo i2cget -y 1 0x48 0x00 w");
$r1 = substr($read, 2, 2);
$r2 = substr($read, 4, 2);
$swap = "0x{$r2}{$r1}";
echo hexdec($swap) / 128;

system() メソッドでは、OS コマンドを実行して得られた標準出力を取得できます。

substr() は第 1 引数で与えた文字列の第 2 引数の位置から第 3 引数文字分切り出します。これは ASCII 文字として扱われるので、日本語のような多バイト文字列を利用する時は mb_substr() を使う必要がありますが、今回は16進数文字列ですので substr() で構いません。開始位置は 0 オリジン(0から始まる)ですので、2 文字目からと 4 文字目からそれぞれ 2 文字を取得してひっくり返しています。

このようにすると、先ほどの計測で得られた 0x780c は、24.9375℃であった事がわかります。

なお、小数点以下4桁も精度があってもあまり意味ない場合が多いので、

echo number_format(hexdec($swap) / 128, 1);

とすると、四捨五入された小数点以下1桁の数値にフォーマットできます。(戻り値は string 型なので注意しましょう)

まとめ

以上のように、ADT7410使用 高精度・高分解能 I2C・16Bit 温度センサモジュール(秋月電子通商)さえあれば、とても簡単に室温の計測が出来ることがわかります。

ちなみに、system() コマンドは比較的遅いのでどの程度の時間がかかるのか調べようと思い、以下の様な呪文を唱えてみました。(2016/08/02 コードの中盤が欠落していたので修正しました)

sudo php -r '$time_start = microtime(true);$read = system("sudo i2cget -y 1 0x48 0x00 w");$r1 = substr($read, 2, 2);$r2 = substr($read, 4, 2);$swap = "0x0x{$r2}{$r1}";$temp = (float)number_format(intval(hexdec($swap)) / 128, 1);echo "\n";echo microtime(true) - $time_start;'

php に -r オプションを付けると PHP コマンドを直接実行できるので、マイクロ秒単位で実行時間を計測しています。結果、

0.036367893218994(単位は秒)

全然気にしなくて良さそうな速度ですね。

記事を書き終わってネット検索していたら wiringPi を使った通信を紹介しているサイトもありました。

参考)Raspberry Piで湿度を測ってみる |ず

I2C ライブラリが使えなかった場合は、こういう方法もありそうです。

この記事へのコメント

※現在コメントはMarkdown記法が強制です。>>Markdown の書き方


この記事に返信

このコメントに返信