Raspberry Pi + Camera + 超音波ソナー + リレー

https://qiita.com/nanbuwks/items/a14bca7ce6b5003e1935
のバリエーションです

RaspberryPiでHeadlessで超音波ソナーで何か検出したらリレーで照明を付けて、カメラ撮影するよ！


# 準備


以下まで終わらせておこう。

- Raspberry Pi を用意 
- Raspberry Pi へ Raspbian をインストール
- Raspberry Pi がインターネットに接続
- ipアドレスを取得しておく
- 母艦(PC)からログイン

cf., 「Raspberry Pi 最初の設定をCUIで行う（ディスプレイ、キーボードがある場合）」
https://qiita.com/nanbuwks/items/9a1d46c22e898178015c

# インストール

```
sudo apt-get install apache2

```

# 設定

```

sudo raspi-config
```
 で、カメラを有効にします。




# リレーをON／OFFする

まずは、リレーをGPIO 0番（WiringPi番号）に取付て、動作するかどうかテストです。


```

gpio mode 0 OUT
```

として、OUTPUTモードにした後に、

```

gpio write 0 1
```

として、リレーがONになったでしょうか？

```

gpio write 0 0
```

とすると、リレーがOFFとなります。


# カメラを撮影する

```

sudo rm /var/www/html/index.html

sudo chmod 777 /var/www/html
```

とします。（一度だけすれば、OKです）

raspistill -o /var/www/html/201812081719.jpg

とすると、

http://(IPアドレス)

で写真が見えます。


## 写真を撮るスクリプトをつくる

```

nano shot.sh
```


として、画面を開きます。

```


raspistill -o /var/www/html/shottest.jpg
```

として保存します。



これを実行すると、キーボードで入力したように実行できます。

実行のためには、実行許可を与えます。

```

chmod 777 shot.sh
```

として、

```

./shot.sh
```

とすると、shottest.jpg が撮影出来たでしょうか？

## 時刻を自動で写真のファイル名にする


OKだったら、次に、自動で日付をつけるようにします。
shot.shの中身を、

```

raspistill -o /var/www/html/`date +%Y%m%d%H%M%S`.jpg

```

とします。


```

./shot.sh
```
で実行すると



と出てきました。

# ライトをつけて写真を撮る


```

gpio write 0 1
sleep 1
raspistill -o /var/www/html/`date +%Y%m%d%H%M%S`.jpg
gpio write 0 0

```

sleep 1 というのは、１秒待つという意味です。


# センサープログラムを作る

WiringPi でいうGPIO 1番に磁石センサーを繋いでみました

```

gpio mode 1 in
while [ 1 ]
do
  SENSOR=$(gpio read 1)
  if test "1" = $SENSOR ; then
    echo "Detect"
  else
    echo "Normal"
  fi
  sleep 0.1  
done
```

これで、通常の場合は Normal 、反応があったらDetect と出ます。

# センサー連動で写真を撮る


以下のシェルスクリプトを使って実行してみます。

```

gpio mode 0 out
gpio mode 1 in
while [ 1 ]
do
  SENSOR=$(gpio read 1)
  if test "0" = $SENSOR ; then
    echo "Detect"
    gpio write 3 1
    sleep 1
    raspistill -o /var/www/html/`date +%Y%m%d%H%M%S`.jpg
    gpio write 3 0
    sleep 20 
  else
    echo "Normal"
  fi
  sleep 0.1  
done

```

今回は、磁石センサーの他にWiringPI のGPIO3番にブザーを取り付けてみました。
これで、センサーに反応があったら写真を撮影して、２０秒待って次の反応を待ちます。
また、

```
    gpio write 3 1
```
のところで、ブザーから音が鳴ります。

# ライトを光らせる

さて、WiringPi GPIO 0 番にはリレーが付いていました。リレーにLEDライトを取り付けておくと、ライトを点灯してカメラ撮影ができるようになります。プログラムは、

```
    gpio write 3 1
↓
    gpio write 0 1
```

のように、書き直す必要があります。（書き直す箇所は、更にもう一箇所ありますね！）




# 超音波ソナーを設定する

超音波ソナーを使って距離を即テイしてみます。
今まではシェルスクリプトだったのですが、だんだん複雑になってきましたのでpythonを使うことにします。

Using a Raspberry Pi distance sensor (ultrasonic sensor HC-SR04)
https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-sensor-hc-sr04/

を元にして以下のプログラムを作ります。
```

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import os,signal
import subprocess

def reading(sensor):
    import time
    import RPi.GPIO as GPIO
    GPIO.setwarnings(False)

    GPIO.setmode(GPIO.BOARD)
    TRIG = 18
    ECHO = 13

    if sensor == 0:
        GPIO.setup(TRIG,GPIO.OUT)
        GPIO.setup(ECHO,GPIO.IN)
        GPIO.output(TRIG, GPIO.LOW)
        time.sleep(0.3)

        GPIO.output(TRIG, True)
        time.sleep(0.00001)
        GPIO.output(TRIG, False)
        while GPIO.input(ECHO) == 0:
          signaloff = time.time()

        while GPIO.input(ECHO) == 1:
          signalon = time.time()

        timepassed = signalon - signaloff
        distance = timepassed * 17000
        return distance
        GPIO.cleanup()
    else:
        print "Incorrect usonic() function varible."
level=0
while 1:
  distance = reading(0)
  print distance
  time.sleep(0.01)

```

と直したものを、sonner.pyとして保存します。


以下のようにして実行します。

```

python  sonner.py
```

すると距離が表示されます。


# 超音波ソナーで距離を測定してライトとカメラを動作させる

```

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import os,signal
import subprocess
import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)
TRIG = 27
ECHO = 18
RELAY = 17
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
GPIO.setup(RELAY,GPIO.OUT)

def reading(sensor):

    if sensor == 0:
        GPIO.output(TRIG, GPIO.LOW)
        time.sleep(0.3)

        GPIO.output(TRIG, True)
        time.sleep(0.00001)
        GPIO.output(TRIG, False)
        signaloff = time.time()
        while GPIO.input(ECHO) == 0:
          signaloff = time.time()

        while GPIO.input(ECHO) == 1:
          signalon = time.time()

        timepassed = signalon - signaloff
        distance = timepassed * 17000
        return distance
        GPIO.cleanup()
    else:
        print "Incorrect usonic() function varible."

def shot():
  GPIO.output(RELAY, True)
  time.sleep(1)
  cmd = "raspistill -o /var/www/html/`date +%Y%m%d%H%M%S`.jpg"
  subprocess.call(cmd, shell=True)
  GPIO.output(RELAY, False)
while 1:
  distance = reading(0)
  print distance
  if ( distance < 120 ):
    print("bingo")
    shot()
  time.sleep(0.1)
```

これを実行すると、ソナーで検出したらライトを点灯し、写真撮影します。写真撮影したものは同じネットワークにつながったWebブラウザから閲覧できます。