RaspberryPiでGPIOを使用してみる

RaspberryPiのGPIOをPythonを使用して操作

やっと電子工作っぽくなってきて楽しみになってきました。

f:id:ueponx:20160529130824p:plain

GPIOをコマンドラインから操作する

Linux には /sys ディレクトリ以下にSysfs仮想ファイルシステムカーネルの情報をユーザ領域からファイルシステムの形で操作できるようにしたもの)がある。 Raspbianではsysfs経由でGPIOの制御ができるようになっています。

  1. 使用するGPIOピンを設定
  2. 使用するGPIOピンの入力・出力を指定
  3. GPIOを制御
  4. GPIOピンを使用終了を設定

使用するGPIOピンを設定

/sys/class/gpio/exportに使用するGPIOの番号を書き込みます。 これによって/sys/class/gpio/ディレクトリにGPIOの18ピン制御に必要となる仮想ファイルが生成されます。

例えば18番のGPIOピンを使用を設定するには以下のようにします。

~ $ sudo echo 18 > /sys/class/gpio/export

コマンドが実行されると/sys/class/gpio/gpio18/directionというファイルが生成されます。

使用するGPIOピンの入力・出力を指定

GPIOピンの入力指定する場合には以下のようにします。

~ $ sudo echo in > /sys/class/gpio/gpio18/direction

GPIOピンの出力指定する場合には以下のようにします。

~ $ sudo echo out > /sys/class/gpio/gpio18/direction

GPIOを制御する

これでGPIOの制御ができるようになります。 ピンの状態をsh取得する場合、GPIO18ピンであれば、/sys/class/gpio/gpio18/valueを確認することになります。 値は0または1が格納されています。

確認するには以下のようにコマンドを実行します。

~ $ sudo cat /sys/class/gpio/gpio18/value

また、GPIOを特定の値にセットするには以下のようにします。以下の例では1(On)にしています。

~ $ sudo echo 1 > /sys/class/gpio/gpio18/value

GPIOピンを使用終了を設定

GPIOピンの使用が終わったら終了をシステムに設定する必要があります。

GPIOの18ピンの使用を終了させるには以下のようにします。

~ $ sudo echo 18 > /sys/class/gpio/unexport

まとめ

# GPIO18ピンの使用を開始
~ $ sudo echo 18 > /sys/class/gpio/export

# GPIO18ピンを入力として設定
~ $ sudo echo in > /sys/class/gpio/gpio18/direction

# GPIO18ピンの値を取得
~ $ sudo cat /sys/class/gpio/gpio18/value

# GPIO18ピンをONを状態へ
~ $ sudo echo 1 > /sys/class/gpio/gpio18/value

# GPIO18ピンの使用を終了
~ $ sudo echo 18 > /sys/class/gpio/unexport

センサーを使ってみる

では実際にGPIO経由でセンサーを使ってみます。 以下の人感センサーが家にあったので使用してみます。

www.aitendo.com

回路は以下のようになっているので

f:id:ueponx:20160529131407j:plain

+は5Vに、OはGPIO18、-はGNDを接続します。

人の認識した時の信号線をGPIOの18PINに接続すると値を取得することができます。 また認識すると一定時間その状態を保持するセンサーなので定期的に判定をループ処理に入れています。

今回は1秒ごとにセンサーの値を取得し、初回の検知から該当の時間(今回は15秒)毎に「人を感知しました」という出力を行うプログラムになります。

gpiotest.py

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import time
import RPi.GPIO as GPIO

INTERVAL = 15
SLEEPTIME = 1
SENSOR_PIN = 18

GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
GPIO.setup(SENSOR_PIN, GPIO.IN)

st = time.time()-INTERVAL

while True:
  print GPIO.input(SENSOR_PIN)
  if(GPIO.input(SENSOR_PIN) == GPIO.HIGH) and (st + INTERVAL < time.time()):
    st = time.time()
    print("人を感知しました")

  time.sleep(SLEEPTIME)

このプログラムを動作させるとWarningが出ますが念のために入れているGPIO.cleanup()が原因です。Ctrl+Cで中断するため正規の手順でGPIO.cleanup()ができないために入れているので気にしないでください。

$ sudo python gpiotest.py
gpiotest.py:11: RuntimeWarning: No channels have been set up yet - nothing to clean up!  Try cleaning up at the end of your program instead!
  GPIO.cleanup()
0
0
0
1
人を感知しました
1
1
1
1
1
0
0
0
0
/* -----codeの行番号----- */