Raspberry PiでADT7410, DHT11, BMP180, HC-SR501を動かしてみた

# 話すこと
以前からRaspberry Piを使うことが多かったのですが、センサーを多く取り付けようとすると配線がめちゃくちゃ大変になります。
この記事は、使用したセンサーの使い方と配線のコツをまとめたものになります。

## 環境
- Raspberry Pi 3 Model B+
    - [ラズパイの仕様について](https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/)
    - 使用言語：Python3

    <img width="250" alt="ras-pi3b+" src="https://www.raspberrypi.org/homepage-9df4b/static/8ca4b04c6593a114ae562d25b6161d94/052d8/8c67a3e02f41441dae98f8b91c792c1e1b4afef1_770a5842.jpg">

- ADT7410 (温度センサー)
    - [ADT7410の仕様について](http://akizukidenshi.com/catalog/g/gM-06675/)
    
    <img width="250" alt="adt7410" src="http://akizukidenshi.com/img/goods/L/M-06675.jpg">

- DHT11 (温湿度センサー)
    - [DHT11の仕様について](http://akizukidenshi.com/catalog/g/gM-07003/)
    
    <img width="250" alt="dht11" src="http://akizukidenshi.com/img/goods/C/M-07003.jpg">

- BMP180 (大気圧センサー)
    - [BMP180の仕様について](http://akizukidenshi.com/catalog/g/gM-12854/)
    
    <img width="250" alt="bmp180" src="http://akizukidenshi.com/img/goods/C/M-12854.jpg">
    
- HC-SR501 (人感センサー)
    - [HC-SR501の仕様について](http://akizukidenshi.com/catalog/g/gM-09627/)
    
    <img width="250" alt="hc-sr501" src="http://akizukidenshi.com/img/goods/L/M-09627.jpg">

- 配線たくさん

# 配線のルール
配線するときに注意すべき点を自分なりにまとめました。
補足の情報があればコメントにてアドバイスしていただけると助かります！

- VDD(電源)は赤色あるいは橙色を使用する
- GND(アース)は青色または黒色を使用する
- VDD・GNDは一色のみに統一
- センサーごとに色を統一／データ種別で色を統一
- 入力用か出力用かで色分けを行う
- ブレッドボードを使用する場合は配線がたるまないようにする
- 金属部が他の配線と接触しないように間隔をあける
- <b>焼きそば配線にしない</b>

<img width="300" alt="adt7410" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266405/878ec999-1877-a822-33a2-500074a677ce.jpeg">

基本的なことですが、やっていると忘れがちなので注意が必要です。

# センサーの実装
各センサーで説明をしているピン番号は以下の画像を参考にしてみてください。

<img width="300" alt="gpio" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266405/3b5534cb-a9f7-886e-8f30-1c9ac4ed094b.png">

GPIOについて詳しく知りたい方は[公式サイト](https://www.raspberrypi.org/documentation/usage/gpio/README.md)を見てみてください。

## ADT7410 (温度センサー)
I2C対応センサーなので、データの取得は簡単です。
I2C用のコマンドが用意されていますので、詳しくはこちらの[サイト](https://www.qoosky.io/techs/2316d68b2e)を見てみてください。
また、センサーのアドレスが異なれば並列につなぐことで複数のi2c対応センサーを扱うことが可能です。

<img width="300" alt="adt7410_img" src="http://akizukidenshi.com/img/goods/2/M-06675.JPG">

ADT7410は接続箇所が4か所あるため、Raspberry PiのVDD(電源)・SCL(5番ピン)・SDA(3番ピン)・GND(アース)にそれぞれ接続しましょう。
プログラムはPython3で書いてあります。以下がコードになります。

```Python3:adt7410.py
import smbus

i2c = smbus.SMBus(1)
address = #アドレス番号(i2cdetectなどで確認)

block = i2c.read_i2c_block_data(address, 0x00, 12)
temp = (block[0] << 8 | block[1]) >> 3
if(temp >= 4096):
   temp -= 8192
print("Temperature:%6.2f" % (temp / 16.0))
```
## DHT11 (温湿度センサー)
DHT11はI2C規格ではないので、ライブラリを使用します。

```bash
pip install dht11
```

`pip`コマンドでライブラリをインストールし、Pythonで使用できるようにします。
@mininobu さんの[記事](https://qiita.com/mininobu/items/1ba0223af84be153b850)が分かりやすかったので紹介します。
DHT11は左から順に

- VDD：power supply 3.3～5.5V
- DATA：serial DATA (single bus)
- NC：empty 
- GND：power supply negative(grounding)

となっているため、左から2つ目の場所をRaspberry Piのピンと接続させましょう。
以下がデータ取得用のコードです。

```Python3:dht11.py
import RPi.GPIO as GPIO
import dht11

# GPIO初期化
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
# 使用するピン番号
PIN = #番号

# データ取得
instance = dht11.DHT11(pin = PIN)
result = instance.read()
if result.is_valid():
    print("Temperature: %-3.1f C" % result.temperature)
    print("Humidity: %-3.1f %%" % result.humidity)
else:
    print("Error: %d" % result.error_code)
```

## BMP180 (大気圧センサー)
BMP180は今回[Githubにあるライブラリ](https://github.com/adafruit/Adafruit_Python_BMP)を使用しました。
>https://github.com/adafruit/Adafruit_Python_BMP

BMP180は4箇所接続するところがあります。

<img width="300" alt="kxm52-1050" src="http://akizukidenshi.com/img/goods/2/M-12854.jpg">

VIN(電源)・GND(アース)・SCL(5番ピン)・SDA(3番ピン)の4か所をRaspberry Piに接続しましょう。
また、BMP180はi2c対応であるため、adt7410と同様にデータを取り出すことも可能です。
このライブラリを用いて実装していきます。以下がコードです。

```Python3:bmp180.py
import RPi.GPIO as GPIO
import Adafruit_BMP.BMP085 as BMP085
import time
import datetime

# GPIO初期化
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
# BMP085初期化
sensor = BMP085.BMP085()

try:
    while True:
        result = instance.read()
	if result.is_valid():
	    print("[Last valid input: " + str(datetime.datetime.now()) + "]")	
	    print("Temperature: {0:0.2f} C".format(sensor.read_temperature()))
	    print("Altitude: {0:0.2f} m".format(sensor.read_altitude()))
	    print("Barometric Pressure: {0:0.2f} Pa".format(sensor.read_pressure()))
	    print("Sea level Pressure: {0:0.2f} Pa".format(sensor.read_sealevel_pressure()))
	time.sleep(5)
except KeyboardInterrupt:
    print("Cleanup")
    GPIO.cleanup()
```

BMP180は、気圧データの他に温度や高度といった情報も取得できるようです。

## HC-SR501 (人感センサー)
HC-SR501は3つのピンがあります。

<img width="300" alt="kxm52-1050" src="http://akizukidenshi.com/img/goods/2/M-09627.JPG">

VCC(電源)・OUT(データ取得用)・GND(アース)の3か所をRaspberry Piに接続しましょう。
人を感知した場合に入力ピンから電気が流れるため、`GPIO.HIGH`でチェックができます。
以下がコードです。

```Python3:hc-sr501.py
from datetime import datetime
import time
import RPi.GPIO as GPIO

# インターバル
INTERVAL = 3
# スリープタイム
SLEEPTIME = 20
# 使用するGPIO
GPIO_PIN = #ピン番号
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN, GPIO.IN)
 
try:
    print ("処理キャンセル：CTRL+C")
    cnt = 1
    while True:
        # センサー感知
        if(GPIO.input(GPIO_PIN) == GPIO.HIGH):
            print(datetime.now().strftime('%Y/%m/%d %H:%M:%S') + "：" + str("{0:05d}".format(cnt)) + "回目の人感知")
            cnt = cnt + 1
            time.sleep(SLEEPTIME)
        else:
            print(GPIO.input(GPIO_PIN))
            time.sleep(INTERVAL)
except KeyboardInterrupt:
    print("終了処理中...")
finally:
    GPIO.cleanup()
    print("GPIO clean完了")
```

## さいごに

Raspberry Piは今後も使っていくので, 使ったセンサーはちょくちょくまとめていこうと思います.