05 January 2013

Raspberry Pi GPIO入出力のサンプル(Python, C言語, shellスクリプト)

Raspberry PiのGPIO端子から入出力できるか、試してみる。RPi Low-level peripheralsを参考にした。

■ Python

Python用モジュールが既にインストールされているか確認する。


$ sudo apt-cache --names-only search gpio
python-rpi.gpio - Python GPIO module for Raspberry Pi
python3-rpi.gpio - Python 3 GPIO module for Raspberry Pi

$ sudo dpkg -l | grep -e "python.*gpio"
ii python-rpi.gpio 0.4.1a-1 armhf Python GPIO module for Raspberry Pi
ii python3-rpi.gpio 0.4.1a-1 armhf Python 3 GPIO module for Raspberry Pi

このモジュールは公式ページによれば「SPI, I2C, PWMには現在の所未対応」ということだ。

GPIO出力する(例:LEDを0.5秒間隔で点灯・消灯)だけのサンプルプログラム

20120105-rpi-ledblink.png

gpio_led_blink.py

#!/usr/bin/python

import RPi.GPIO as GPIO
import time

# 使うGPIOピンの番号
IO_NO = 4

print("press ^C to exit program ...\n")

# GPIOピン番号を用いる
GPIO.setmode(GPIO.BCM)
# 基板上のピン番号を用いる
#GPIO.setmode(GPIO.BOARD)

GPIO.setup(IO_NO, GPIO.OUT)

try:
while True:
GPIO.output(IO_NO, True)
time.sleep(0.5)
GPIO.output(IO_NO, False)
time.sleep(0.5)
except KeyboardInterrupt:
print("detect key interrupt\n")

GPIO.cleanup()
print("Program exit\n")

このプログラムはroot権限で実行する(sudo ./gpio_led_blink.py)。

RPi Rev2基盤ではGPIO 0, GPIO 1(I2C用にプルアップされている)を除いた全てのGPIOポートの出力をコントロールできる。

次に、GPIOピンからの入力

20120105-rpi-gpioinput.png

gpio_input.py

#!/usr/bin/python

import RPi.GPIO as GPIO
import time

IO_NO = 4

print("press ^C to exit program ...\n")

GPIO.setmode(GPIO.BCM)
GPIO.setup(IO_NO, GPIO.IN)

try:
while True:
print(GPIO.input(IO_NO))
time.sleep(1)
except KeyboardInterrupt:
print("detect key interrupt\n")

GPIO.cleanup()
print("Program exit\n")

GPIO.input関数は、3.3Vが入力されている場合True, 0Vの場合Falseが返される。

■ C言語

C library for Broadcom BCM 2835 as used in Raspberry Piで公開されているライブラリをインストールして使う。

gpio_led_blink.c

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <signal.h>

// Rpi P1ヘッダの07ピン(GPIO 4)をPINと定義する
#define PIN RPI_V2_GPIO_P1_07

// 割り込みコールバック関数
void signal_callback_handler(int signum)
{
printf("\ndetect key interrupt\n",signum);
bcm2835_close();
printf("Program exit\n");
exit(0);
}

int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;

bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);

signal(SIGINT, signal_callback_handler);
printf("press ^C to exit program ...\n");

while (1)
{
bcm2835_gpio_write(PIN, HIGH);
delay(500); // 0.5秒待つ
bcm2835_gpio_write(PIN, LOW);
delay(500); // 0.5秒待つ
}
}

このコードを、librtライブラリを読み込む形でビルドし、root権限で実行する


$ gcc gpio_led_blink.c -l bcm2835 -lrt

$ sudo ./a.out

入力は次のようなものになる

gpio_led_blink.c

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <signal.h>

// Rpi P1ヘッダの07ピン(GPIO 4)をPINと定義する
#define PIN RPI_V2_GPIO_P1_07

// 割り込みコールバック関数
void signal_callback_handler(int signum)
{
printf("\ndetect key interrupt\n",signum);
bcm2835_close();
printf("Program exit\n");
exit(0);
}

int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;

bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
// VCCまでプルアップする
bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP);

signal(SIGINT, signal_callback_handler);
printf("press ^C to exit program ...\n");

while (1)
{
uint8_t value = bcm2835_gpio_lev(PIN);
printf("read from pin 15: %d\n", value);
delay(500); // 0.5秒待つ
}
}

■ シェルスクリプト

gpio_led_blink.sh

#!/bin/bash

# GPIO 4 を出力として用いる設定
echo "4" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio4/direction

# 点滅を5回繰り返す
for ((i=0; i<5; i++))
do
echo "1" > /sys/class/gpio/gpio4/value
sleep 1
echo "0" > /sys/class/gpio/gpio4/value
sleep 1
done

# GPIO終了処理
echo "4" > /sys/class/gpio/unexport

このスクリプトもroot権限でしか動作しない。sudo ./gpio_led_blink.shのように実行する。