RaspberryPiのGPIOをPythonを使用して操作
やっと電子工作っぽくなってきて楽しみになってきました。
GPIOをコマンドラインから操作する
Linux には /sys ディレクトリ以下にSysfs仮想ファイルシステム(カーネルの情報をユーザ領域からファイルシステムの形で操作できるようにしたもの)がある。 Raspbianではsysfs経由でGPIOの制御ができるようになっています。
- 使用するGPIOピンを設定
- 使用するGPIOピンの入力・出力を指定
- GPIOを制御
- 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経由でセンサーを使ってみます。 以下の人感センサーが家にあったので使用してみます。
回路は以下のようになっているので
+は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