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のように実行する。