9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Raspberry Pi で近寄る何かを撮影

Last updated at Posted at 2019-07-02

はじめに

Raspberry Pi と USB カメラを使った工作です。

仕事で、コンベアを流れてきたものを自動で撮影することになりました。場所は屋内ですが、PC を置ける場所がありません。そんな予算もありません。
そこで、Raspberry Piを使うことにしました。これなら 1 万円程度で収まります。
シャッターの代わりは、当初はボタンとか機械的なスイッチを考えていました。しかし、コンベアの周囲にスイッチを固定できそうな場所がありません。そこで、距離センサを使うことにしました。
画像は1日の終わりに取り出せれば良いので、撮影したらとりあえず micro SD に保存することにしました。

探せば、似たような(あるいはもっと高度な)システムを作っている方がたくさんいます。
それらの二番煎じですが、自分の備忘録として残します。

用意するもの

  • Raspberry Pi ... 1 式
    • Raspberry Pi 3 model B+ を使用したが、他のモデルでも大丈夫なはず。
    • OS は、Rasbian Stretch。
    • Python 3.5.3。
  • USB カメラまたはカメラモジュール ... 1 個
    • 手元にあった USB カメラ (Buffalo BSW13K05H) を使用したが、他の製品でも大丈夫なはず。
    • カメラモジュールは v1 互換品を使用したが、v2 互換品でも大丈夫なはず。
  • タクトスイッチ ... 2 個
    • シャッター用とシャットダウン用。
    • PC ケースから剥がしたものを使用したので、GPIO ピンに挿せるようになっていた。
    • 部品単品を使うなら別途ジャンパワイヤ(オス-メス) が 4 本必要。
  • 超音波距離センサ (HC-SR04) ... 1 個
    • 距離の測定に使用。
  • LED ... 緑と赤 各 1 個
    • 緑は待機中表示に、赤は処理中表示に使用。
  • 抵抗 ... 4 個
    • 330Ω と 470Ω ... HC-SR04 用に各 1 個
    • 330Ω ... LED用に 2 個
  • ブレッドボード ... 小 1 個
  • ジャンパワイヤ(オス-メス) ... 10 本程度
    • 電源ラインがないブレッドボードを使用したので、ちょっと多め。

ハードウェアの接続

  1. Raspberry Pi の電源を切る。
  2. カメラを接続する。
    • USB カメラなら、USB ポートに接続する。
    • カメラモジュールなら、リボンケーブルを CPI に接続する。
  3. タクトスイッチを接続する。
    • シャッタースイッチを 13 番ピン (GPIO27) と 14 番ピン (GND) に接続する。
    • シャットダウンスイッチを 39 番ピン (GND) と 40 番ピン (GPIO21) に接続する。
  4. 超音波センサ HC-SR04 を接続する。
    • HC-SR04 の Gnd を 9 番ピン (GND) に接続する。
    • HC-SR04 の Gnd に 470Ω を接続する。
    • HC-SR04 の Echo に 330Ω を接続する。
    • 2つの抵抗の反対側を 11 番ピン (GPIO17) に接続する。
    • HC-SR04 の Trig を 12 番ピン (GPIO18) に接続する。
    • HC-SR04 の Vcc を 2 番ピン (5V) に接続する。
  5. LEDを接続する。
    • 緑色と 330Ω を直列にして 29 番ピン (GPIO5) と 30 番ピン (GND) に接続する。
    • 赤色と 330Ω を直列にして 33 番ピン (GPIO13) と 34 番ピン (GND) に接続する。

部品をブレッドボードに刺したもの。

  • 銀色の筒がついた青い基板が超音波センサ HC-SR04。端子は左から、Gnd、Echo、Trig、Vcc。
  • 470Ω の代わりに、1kΩ を 2 個並列にしている。
    ブレッドボード

Raspberry Pi に接続したもの。
左下でとぐろを巻いているのは、PC ケースから剥がしたタクトスイッチ。
Raspberry Pi に接続

システムの構築

準備

  1. カメラを使えるように、設定する。
    • USB カメラであれば、sudo apt-get install fswebcam として fswebcam をインストールしておく。
    • カメラモジュールであれば、sudo raspi-config などでカメラインターフェイスを有効化して、再起動する。
  2. 下の Python スクリプト auto_camera.py を Raspberry Pi に転送する。
auto_camera.py
# auto_camera.py
# for python 3.5 and more

import os
import subprocess
import sys
from datetime import datetime
from time import sleep
from gpiozero import LED, Button, DistanceSensor
from picamera import PiCamera

## Configurations
#CAMERA_MODULE = 'PiCamera'  # 'USB' or 'PiCamera'
CAMERA_MODULE = 'USB'  # 'USB' or 'PiCamera'
SHUTTER = 'BUTTON'  # 'BUTTON' or 'DISTANCE'
#SHUTTER = 'DISTANCE'  # 'BUTTON' or 'DISTANCE'
SHUTTER_DISTANCE = 1.0  # Shutter when something will get close then 1.0m
USE_LED = True  # 
STOP_BY_SHUTDOWN = True  # True for shutdown, False for exit()

stop_auto_camera = lambda _=None: subprocess.run(('sudo', 'shutdown', '-h', 'now')) if STOP_BY_SHUTDOWN else sys.exit()
dummy_led = type('', (), {'on': lambda: None, 'off': lambda: None, 'blink': lambda **kw: None})

## Set up LEDs, super sonic sensor and buttons on GPIO
led_wait = LED(pin=5) if USE_LED else dummy_led  # HIGH = pin 29, GND = pin 30
led_busy = LED(pin=13) if USE_LED else dummy_led  # HIGH = pin 33, GND = pin 34
if SHUTTER == 'BUTTON':
    shutter = Button(pin=27)  # HIGH = pin 13, GND = pin 14
    wait_shutter = shutter.wait_for_press
else:
    shutter = DistanceSensor(echo=17, trigger=18, max_distance=3.0, threshold_distance=SHUTTER_DISTANCE)  # ECHO = pin 11, TRIG = pin 12, 5V = pin 2, GND = pin 9
    wait_shutter = shutter.wait_for_in_range
exit_sw = Button(pin=21)  # HIGH = pin 40, GND = pin 39
exit_sw.when_pressed = stop_auto_camera

## Guard from no camera
if not os.path.exists('/dev/video0'):
    # shutdown withoutcamera
    led_busy.blink(on_time=1, off_time=1, n=5)
    stop_auto_camera()

## Set camera control object
if CAMERA_MODULE == 'PiCamera':
    camera = PiCamera()
    camera.resolution = (1024, 768)
else:
    camera = type('', (), {})
    camera.capture = lambda imgpath: subprocess.run(('fswebcam', '--quiet', '--resolution', '1024x768', '--no-banner', imgpath))
    camera.start_preview = lambda: None
    camera.stop_preview = lambda: None

## take a photo for each shutter
camera.start_preview()
while True:
    led_wait.off()
    led_busy.on()
    cur = datetime.now()
    imgdir = cur.strftime('%Y%m%d')
    os.makedirs(imgdir, exist_ok=True)
    imgpath = cur.strftime('%Y%m%d/%Y%m%d-%H%M%S.jpg')
    camera.capture(imgpath)
    led_busy.off()
    led_wait.on()
    wait_shutter()
camera.stop_preview()

ボタンで撮影

  1. auto_camera.py の定数の値を修正する。
    • カメラに合わせて、CAMERA_MODULE の値を 'USB' (USB カメラ)または 'PiCamera' (カメラモジュール) から選択する。
    • LED を使わないなら、USE_LED = False にする。
  2. python3 auto_camera.py を実行する。
    • 赤色 LED が点灯して、しばらくすると赤色 LED が消灯 LED して緑色が点灯する。
    • 実行したディレクトリに、日付のサブディレクトリができている。書式は yyyymmdd
    • yyyymmdd の下に、日時を名前にした画像ファイルが保存されている。書式は yyyymmdd-HHMMSS.jpg
  3. シャッターボタンを押す。
    • ボタンを押すと、緑色 LED が消灯して赤色 LED が点灯する。しばらくすると赤色 LED が消灯 LED して緑色が点灯する。
    • yyyymmdd の下に、画像ファイルが追加されている。
  4. Ctrl+C を押して auto_camera.py を終了する。

超音波センサーで撮影

  1. auto_camera.py の定数の値を修正する。
    • SHUTTER の値を 'DISTANCE' (超音波センサー)に変更する。
    • X m 以内に近づいたらシャッターを切るように、SHUTTER_DISTANCE の値を変更する。X は 0.5~4.0 くらいの間。
  2. 超音波センサーの前を空ける。
    • 少なくとも SHUTTER_DISTANCE 以内に、物がないようにする。
  3. python3 auto_camera.py を実行する。
    • ボタンの時と同様に動作する。
  4. 超音波センサーでシャッターを切る。
    • 超音波センサーの前に何かを置いたり手をかざしたりすると、緑色 LED が消灯して赤色 LED が点灯する。しばらくすると赤色 LED が消灯 LED して緑色が点灯する。
    • yyyymmdd の下に、画像ファイルが追加されている。
  5. Ctrl+C を押して auto_camera.py を終了する。

ボタンでシャットダウン

  1. python3 auto_camera.py を実行する。
  2. シャットダウンボタンを押す。
    • シャットダウン処理が始まる。
    • Raspberry Pi の電源付近にある緑色 LED が点滅して消灯したら、シャットダウン完了。

起動時に自動実行

  1. crontab -e を実行して cron の設定ファイルを開く(sudo はつけない)。
  2. 設定ファイルの末尾に @reboot /usr/bin/python3 /home/pi/auto_camera.py & を追加する。
  3. Raspberry Pi を再起動して撮影できることを確認する。

おわりに

とりあえず、何かが近づいたら撮影するカメラが出来上がりました。この後も、

  • シャッターに連動してフラッシュを焚く。
  • ブラウザ経由で画像を見られるようにする。
  • 撮影したことを Twitter などで自分に通知する。

など、いろいろ発展させていきたいです。


  • 2019/7/3: auto_camera.py 中の dummy_LED を修正
9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?