コレは何? †
RPi.GPIO のインストール †
API 仕様 †
- https://pypi.python.org/pypi/RPi.GPIO
- https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
- import 宣言
import RPi.GPIO as GPIO
- RPi.GPIO初期化
GPIO.setmode(mode)
- mode
GPIO.BOARD | 物理的なピン番号で I/O ポートを指定する |
GPIO.BCM | GPIO番号で I/O ポートを指定する |
- GPIOポート初期化
GPIO.setup(channel, mode)
- GPIO終了処理
- 出力
GPIO.output(channel, 0/1)
False/True, GPIO.LOW/GPIO.HIGH でも OK
- 入力
boolean = GPIO.input(channel)
- 割り込み待ち
channel = GPIO.wait_for_edge(channel, GPIO.RISING, timeout=2000)
最大2秒間 channel が変化するのを待つ。その間CPUを使わない
timeout した時には None が返る。
GPIO.RISING | wait the channel OFF → ON |
GPIO.FALLING | wait the channel ON → OFF |
GPIO.BOTH | |
- イベント発生をとっておく
GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):
print('Button pressed')
GPIO.remove_event_detect(channel)
do_something() を実行中に、channel が OFF→ON になることがあったら、GPIO.event_detected(channel) が True を返す
- イベント発生で、別スレッドで関数呼び出し
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)
or
GPIO.add_event_callback(channel, my_callback, bouncetime=200)
bouncetime は、スイッチの電圧が 3V になるまでの時間。
http://www.bbc.co.uk/schools/gcsebitesize/design/electronics/switchesrev2.shtml
GPIOの入力電圧が 1.5V 近辺のギザギザをまともに解釈すると ON→OFF→ON→OFF... となるので、電圧の立ち上がり期間(bouncetime)を無視する必要がある
他の方法のように、ある瞬間の ON/OFF を調べる分には問題ないけど、ON になるごとに別スレッドで関数を呼び出すと、電圧の立ち上がり期間で何度も関数が呼び出されるので bouncetime の設定が必要
0.1uF 程度のコンデンサをスイッチと並列に配置すると、bouncetime を短縮できる。
サンプルプログラム †
ランダムに点灯するLEDと同じ色のスイッチを押せ!
#!/usr/bin/env python3
# coding: utf-8
import RPi.GPIO as GPIO
import time
import random
LED_RED = 4
LED_YELLOW = 3
LED_BLUE = 2
SW_RED = 11
SW_YELLOW = 10
SW_BLUE = 9
def main() :
# mode
# GPIO.BOARD : pin number
# GPIO.BCM : gpio number
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_RED, GPIO.OUT)
GPIO.setup(LED_YELLOW, GPIO.OUT)
GPIO.setup(LED_BLUE, GPIO.OUT)
GPIO.setup(SW_RED, GPIO.IN)
GPIO.setup(SW_YELLOW, GPIO.IN)
GPIO.setup(SW_BLUE, GPIO.IN)
for _ in range(10) :
led = random.randint(LED_BLUE, LED_RED)
GPIO.output(led, True)
sw = SW_RED if led == LED_RED else (SW_YELLOW if led == LED_YELLOW else SW_BLUE)
GPIO.wait_for_edge(sw, GPIO.RISING, timeout=2000)
if GPIO.input(sw) == False :
GPIO.output(LED_RED, True)
GPIO.output(LED_YELLOW, True)
GPIO.output(LED_BLUE, True)
time.sleep(1.0)
GPIO.output(LED_RED, False)
GPIO.output(LED_YELLOW, False)
GPIO.output(LED_BLUE, False)
time.sleep(1.0)
GPIO.cleanup()
###
# If this script was called as shell command, __name__ is '__main__'.
if __name__ == '__main__':
main()
サービス化 †
- http://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/
- /etc/init.d/gpio_sample
#!/bin/sh
### BEGIN INIT INFO
# Provides: myservice
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Put a short description of the service here
# Description: Put a long description of the service here
### END INIT INFO
# Change the next 3 lines to suit where you install your script and what you want to call it
DIR=/home/pi/gpio
DAEMON=$DIR/Hello2.py
DAEMON_NAME=GPIO_Example
# Add any command line options for your daemon here
DAEMON_OPTS=""
# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root
# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid
. /lib/lsb/init-functions
do_start () {
log_daemon_msg "Starting system $DAEMON_NAME daemon"
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
log_end_msg $?
}
do_stop () {
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}
case "$1" in
start|stop)
do_${1}
;;
restart|reload|force-reload)
do_stop
do_start
;;
status)
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
exit 1
;;
esac
exit 0
root@raspberrypi:/etc/init.d# chown root:root gpio_sample
root@raspberrypi:/etc/init.d# chmod 755 gpio_sample
root@raspberrypi:/etc/init.d# /etc/init.d/gpio_sample start
[ ok ] Starting system GPIO_Example daemon:.
root@raspberrypi:/etc/init.d# /etc/init.d/gpio_sample status
[ ok ] /home/pi/gpio/Hello2.py is running.
root@raspberrypi:/etc/init.d# /etc/init.d/gpio_sample stop
[ ok ] Stopping system GPIO_Example daemon:.
root@raspberrypi:/etc/init.d# update-rc.d gpio_sample defaults
update-rc.d: using dependency based boot sequencing
root@raspberrypi:/etc/init.d# ls -l /etc/rc?.d/*gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc0.d/K01gpio_sample -> ../init.d/gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc1.d/K01gpio_sample -> ../init.d/gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc2.d/S02gpio_sample -> ../init.d/gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc3.d/S02gpio_sample -> ../init.d/gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc4.d/S02gpio_sample -> ../init.d/gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc5.d/S02gpio_sample -> ../init.d/gpio_sample
lrwxrwxrwx 1 root root 21 5月 6 00:46 /etc/rc6.d/K01gpio_sample -> ../init.d/gpio_sample
Raspberry Pi