Raspberry Piで温度センサーモジュールADT7410からデータ取得

# 必要なもの

- Raspberry Pi
    - Raspberry Pi 3 model B+を使用しています
- 温度センサーモジュール ADT7410
    - 秋月電子で購入可能 http://akizukidenshi.com/catalog/g/gM-06675/
- ブレッドボードおよびジャンパーワイヤ
- はんだとはんだこて

# 温度センサーモジュール ADT7410について

- アナログ・デバイセズ社の温度を取得できるモジュール
- 動作/測定温度は-55〜120℃
- I<sup>2</sup>Cバスに測定温度データを出力
- 詳しい情報はデータシートを参照
    - 英語： https://www.analog.com/media/en/technical-documentation/data-sheets/ADT7410.pdf
    - 日本語: https://www.analog.com/media/jp/technical-documentation/data-sheets/ADT7420_jp.pdf

# Raspberry Piの準備

使用しているRaspberry PiのOSバージョンは以下の通りです。

```bash
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster
```

I<sup>2</sup>Cを有効化します。

```
$ sudo raspi-config
-> 5 Interfacing Options
--> P5 I2C
```

上記のようにCUIでconfigrationからI<sup>2</sup>Cを有効化します。
GUIで有効化する方法もあります。知りたい方は調べてください。

必要なパッケージをインストールします。

```bash
$ sudo apt-get install i2c-tools libi2c-dev python-smbus
```

# 温度センサーモジュールの準備とRaspberry Piとの接続

購入した温度センサーモジュールADT7410はピンが付けられていない状態なので、はんだ付けします。

![写真 2019-09-27 13 11 15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120476/752baad7-34ab-d1c5-756c-0db2a377f469.jpeg)
![写真 2019-09-27 13 14 05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120476/a2ee753c-4357-3f13-b769-5d3530ae94e2.jpeg)


ブレッドボードを使用して以下のようにGPIOとモジュールを接続します。
接続する際には、Raspberry Piの電源は切りましょう。

- ADT7410(VDD) ⇔ GPIO2(3.3V)
- ADT7410(SCL) ⇔ GPIO5(SCL)
- ADT7410(SDA) ⇔ GPIO3(SDA)
- ADT7410(GND) ⇔ GPIO6(Ground)

（Raspberry PiのGPIOピン配置は https://pinout.xyz/ などを参照）

![写真 2019-09-30 9 47 47.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120476/499abe06-ba22-a006-ae8e-2975c1dbb10e.jpeg)

fritzingで配線図を書いてみました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120476/e4aaa0ae-13fa-87ee-6f1c-6ad055e58d03.jpeg" width=50%>

配線できたらRaspberry Piを起動して接続確認をします。

```bash
$ 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: -- -- -- -- -- -- -- -- 
```

このように「48」が見えていたら接続は問題ありません。

なお、アドレスを48から変更したい場合はADT7410のA0、A1をはんだでショートさせると変えることができます。
0がオープン、１をショートした状態とすると、

- A1-A0: 0-0 (0x48) 今回の状態
- A1-A0: 0-1 (0x49)
- A1-A0: 1-0 (0x4A)
- A1-A0: 1-1 (0x4B)

となります。
複数個使う場合はアドレスを変更して使いましょう。

では接続ができましたので、温度を取得しましょう。

```bash
$ i2cget -y 1 0x48 0x00 w
0xd00c
```

0xd00cが温度です、と言っても意味がわかりませんよね。
計算方法は、

- 0xd00cの2バイト前後を入れ替えて0x0cd0
- 0x0cd0(0b110011010000)を3ビット右シフトして0b110011010
- 0b110011010をを16で割って10進数で表すと25.625

で求まり、25.625℃が温度です。

Pythonでプログラムすると以下のようになります。

```python:adt7410_13bit.py
# -*- coding: utf-8 -*-
import smbus

bus = smbus.SMBus(1)
address_adt7410 = 0x48
register_adt7410 = 0x00
configration_adt7410 = 0x03

# 13bitに設定して読み出し
bus.write_word_data(address_adt7410, configration_adt7410, 0x00)
word_data = bus.read_word_data(address_adt7410, register_adt7410)

# ２バイトの入れ替え
data = (word_data & 0xff00) >> 8 | (word_data & 0xff) << 8

# 3ビットの右シフト
data = data >> 3

# 16で割って温度に
print(data/16.)
```

16ビットで読み出すにはレジスターのコンフィギュレーションアドレス0x03に0x80を書き込みます。

```python:adt7410_16bit.py
# -*- coding: utf-8 -*-
import smbus

bus = smbus.SMBus(1)
address_adt7410 = 0x48
register_adt7410 = 0x00
configration_adt7410 = 0x03

# 1６bitに設定して読み出し
bus.write_word_data(address_adt7410, configration_adt7410, 0x80)
word_data = bus.read_word_data(address_adt7410, register_adt7410)

# 2バイトの入れ替え
data = (word_data & 0xff00) >> 8 | (word_data & 0xff) << 8

# 128で割って温度に
print(data/128.)
```

それぞれ実行してやると温度を取得できます。

```bash
$ python adt7410_13bit.py
27.125
$ python adt7410_16bit.py
26.7109375
```

数値上は13bitだと0.0625℃、16bitだと0.0078℃のresolutionがあるということですが、そもそもの精度がそんなにあるとは思わないので、個人的には13bitで十分だと思います。