ラズベリーパイこと始め３ -デジタル温度入力編-

# 始めに
[前回](https://qiita.com/twinoze/private/6b2d06c4ab5cbc23d62d)はラズパイにアナログ出力の温度センサーを接続しようとしたがGPIOにアナログIOがなかったため、やむなくLEDの点滅を行う回路を作成しました。
今度こそは温度を！
といっても、温度にそこまで言うほどのこだわりを持っているわけではないのですが、まあ一種意地です。(^^ゞ

# デジタル温度センサー
というわけで新たにデジタル温度センサーとして[AM2320](http://amzn.asia/3hESrdq)なるものを入手しました。
これは、実際には温湿度センサーで温度と湿度を同時に測定できる優れものです。
温度、湿度ともにデータ長は16ビットで温度は0.1℃、湿度は0.1％RHの分解能だそうです。
ラズベリーパイとのインターフェースにI2Cを使用できます。 
![CIMG5635A.png](https://qiita-image-store.s3.amazonaws.com/0/248779/701c8201-6afe-3995-e815-93bd65d63f8c.png)

# I2C
今回入手したAM2320はフィリップス社が開発したI2Cというシリアル通信を使用して外部とインターフェースします。I2CはIICあるいはI<sup>2</sup>Cとも表記するようです。この記事では記述しやすいI2Cとしています。
ラズベリーパイでもこのI2Cに対応しています。ですが使わないことも多いため、デフォルトでは無効になっている様です。まずはラズベリーパイのI2Cを有効化します。

### I2C有効化
コマンドラインからラズパイのコンフィグを起動します。
`$sudo raspi-config`
すると下の様にraspi-configのメニューが開きます。
![raspicondif_menu.png](https://qiita-image-store.s3.amazonaws.com/0/248779/84fe1f7d-6ec6-498b-d4cf-83efbd7761c8.png)

メニューから「5 Interfacing Options ...」を選択します。
インターフェースに関するメニューが開きます。
次にこのメニューから「P5 I2C」を選択します。
![raspicondif_interface.png](https://qiita-image-store.s3.amazonaws.com/0/248779/4aa3096f-dfe6-ac2c-561b-544adbedd0a0.png)

I2Cを有効化(to be enabled)するかを聞かれています。はいを選択して有効化します。
![raspicondif_i2c.png](https://qiita-image-store.s3.amazonaws.com/0/248779/d6568e67-1d55-e101-8b16-b5fb1c22e7be.png)

# 回路設計
AM2320のインターフェースはこの様になっています。
１：VDD	(電源 3.1V-5.5V)
２：SDA	(シリアルデータ)
３：GND	(接地)
４：SCL	(シリアルクロック入力ポート)

この情報をもとに回路を構築しました。
まずはブレッドボード図
![AM2320test_bread.png](https://qiita-image-store.s3.amazonaws.com/0/248779/8eed1394-adde-ca29-e5de-c39433232c98.png)
次に回路図
![AM2320test_circuit.png](https://qiita-image-store.s3.amazonaws.com/0/248779/75368774-e45c-b9d0-d414-998fd10e7a32.png)
そして実際の接続の様子です。
![raspi_am2320A.png](https://qiita-image-store.s3.amazonaws.com/0/248779/8b43a3d7-cbf0-0da1-4638-3bd7219353fc.png)

今回はセンサーの入力だけですので、前回のLEDテスト回路と比べてややシンプルです。

# I2C機能テスト
I2Cのテストツールをapt-getします。
![atptget_i2ctools.png](https://qiita-image-store.s3.amazonaws.com/0/248779/0475c8b4-1e08-3a2c-e28b-09774212b496.png)
私が使っているバージョンでは、デフォルトでインストールされていたようです。

コンソールからI2C経由でのセンサー接続を確認します。
`$i2cdetect -y 1`

と、ここでわたくし一度はまってしまいました。
アドレス5cが表示されるはずだったのですが、出てきません。
![i2cdetect_na.png](https://qiita-image-store.s3.amazonaws.com/0/248779/eed7f794-645c-2291-f5fc-2dcf0fc35242.png)

立ち戻って回路の接続を原資料ベースで確認。I2C機能が有効化されているか再確認、システム再起動、色々試したのですが結果は変わりませんでした。一度腰を上げて歩きながらチョー悩む。無関係に大谷選手の記録を眺める。。。マジありえない！すご過ぎっス大谷選手！などと思いながら。

最後は、半分あきらめ気味にエンターキー連打してみると・・・
![i2cdetect_ok.png](https://qiita-image-store.s3.amazonaws.com/0/248779/041ac076-9df6-3049-ebc6-71c5346d18fb.png)

あれれ？出たりでなかったり。どうやら２回に1回検出される様子。
ではあるがそうでもない時もあり・・・？
まあ一応検出できなくはない！！
ということで次に行きます！
（ここ、何かご存知の方があれば教えてくださいm(_ _)m）

# プログラム
今回は、プログラムも前回と比べるとシンプルです。
何せセンサーの情報を入力するだけですから。

```python:am2320test.py
#!/usr/bin/python
# coding: utf-8

# timeモジュールと補助モジュールをimport
import time
import smbus

print ("AM2320 test Start!")

i2c = smbus.SMBus(1)
# i2cdetect で確認したアドレスを指定
address = 0x5c

# I2C初期化
i2c.write_i2c_block_data(address, 0x00,[])
i2c.write_i2c_block_data(address, 0x03,[0x00, 0x04])

time.sleep(0.05)
# 温湿度情報読み出し
block = i2c.read_i2c_block_data(address, 0, 6)

# リトルエンディアン対応
hum = block[2] << 8 | block[3]
temp = block[4] << 8 | block[5]

print('hum : ' + format( hum/10) + ' %Rh')
print('temp: ' + format(temp/10) + ' digC')

print ("AM2320 test End!")
```
### リトルエンディアン
コンピュータによっては２バイト長以上のデータの配列（バイトオーダー）が逆転するものがあります。
そのような場合、ここで行っている様に上下のバイトを逆転させて処理させる必要が出てきます。
# テスト
`$python3 am2320.py`
![am2320test_ans.png](https://qiita-image-store.s3.amazonaws.com/0/248779/0750f791-3b14-1a93-9f7b-bf8d24ffea6e.png)

この様に、どうにかそれっぽく温度と湿度の情報を取得できました。
あとはループで回すなり、Linuxのcronを使って定期的に記録する様なシステムを組むなりするとグラフ表示などにも展開できるかな？と思います。

# まとめ
実はpythonも、ラズパイも初心者の私ですが、どちらもわりとスムースにここまでこれたように思います。
この記事を読んでいただいた方も、ぜひチャレンジしてみてください。

# 関連リンク
[ラズベリーパイこと始め１ -セットアップ編-](https://qiita.com/twinoze/private/42024e120c35eaa22357)
[ラズベリーパイこと始め２ -LED制御編-](https://qiita.com/twinoze/private/6b2d06c4ab5cbc23d62d)

# 追記
i2cdetectが不安定だった件、こちらもアドバイスをいただきまして[バスリピータ](http://akizukidenshi.com/catalog/g/gI-10882/)を使用しては？とのこと。こちらもいずれ試してみたいと思います。