モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

任意の言語で Raspberry Pi デジタル入出力、アナログ出力 (PWM)

モーダルを閉じる

ステッカーを選択してください

お支払い手続きへ
モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2016/04/10
最終更新最終更新
2024/12/27
記事区分記事区分
一般公開

python を用いた例

書籍や公式ドキュメントなどを見ると、Raspberry Pi は python を (発音が似ているからでしょうか) 標準的な言語としてサポートしているように思われます。python には GPIO を操作するライブラリが標準で導入されています。

デジタル出力

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time

# 初期設定
GPIO.setmode(GPIO.BCM)

# GPIO 14 をデジタル出力に設定
GPIO.setup(14, GPIO.OUT)

try:
    # ON(3.3V)/OFF(GND) トグル (Ctrl-C 待ち)
    while True:
        print time.strftime("%Y/%m/%d %H:%M:%S GPIO 14 HIGH")
        GPIO.output(14, GPIO.HIGH)
        time.sleep(2.0)
        print time.strftime("%Y/%m/%d %H:%M:%S GPIO 14 LOW")
        GPIO.output(14, GPIO.LOW)
        time.sleep(2.0)
except:
    print "interrupted"
finally:
    # 後片付け
    GPIO.cleanup()

デジタル入力

回路図は CircuitLab で作成しました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time

# 初期設定
GPIO.setmode(GPIO.BCM)

# GPIO 14 をデジタル入力に設定
GPIO.setup(14, GPIO.IN)

try:
    # Ctrl-C 待ち
    while True:
        print "%s GPIO 14 is %d" % (time.strftime("%Y/%m/%d %H:%M:%S"), GPIO.input(14))
        time.sleep(1.0)
        #time.sleep(0.1) # チャタリング防止 (ON/OFF の振動状態にある時間は待つ)
except:
    print "interrupted"
finally:
    # 後片付け
    GPIO.cleanup()

擬似的なアナログ出力 (PWM)

Raspberry Pi はアナログ出力できません。PWM (Pulse Width Modulation) で擬似的にアナログ出力します。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time

# 初期設定
GPIO.setmode(GPIO.BCM)

# GPIO 14 を出力に設定
GPIO.setup(14, GPIO.OUT)

# PWM 設定
freq = 50 # Hz (PWM のパルスを一秒間に 50 個生成)
duty = 0.0 # デューティー比 0.0 で出力開始 (パルス内に占める HIGH 状態の時間が 0.0 %)
pwm = GPIO.PWM(14, freq)
pwm.start(duty)

try:
    # デューティー比 (duty cycle) を 0..100 の範囲で変化 (Ctrl-C 待ち)
    while True:
        duty = (duty + 1) % 101
        print "%s GPIO 14 duty cycle %d%%" % (time.strftime("%Y/%m/%d %H:%M:%S"), duty)
        pwm.ChangeDutyCycle(duty)
        time.sleep(0.1)
except:
    print "interrupted"
finally:
    # 後片付け
    pwm.stop()
    GPIO.cleanup()

他のプログラミング言語での例

Wiring Pi で提供される gpio コマンドを利用することで GPIO を簡単に制御できます。2016-4-12 現在の最新 Raspbian (NOOBS インストーラ経由) には gpio コマンドが標準でインストールされています。

pi@raspberrypi:~ $ cat /etc/issue
Raspbian GNU/Linux 8 \n \l

pi@raspberrypi:~ $ uname -r
4.1.19+

pi@raspberrypi:~ $ which gpio
/usr/bin/gpio

基本的な使い方

ピン番号の割り振り方には何種類かあります。このうち python の例でも利用した BCM 形式のピン割り当てを利用することにします。コマンド実行時に -g オプションを付与します。また、WiringPi の gpio コマンドで利用する GPIO ピンに関する注意事項があります。

Special Pin Functions

基本的な処理を行うにあたって知っておくとよさそうなことは以下のとおりです。

  • デジタル入出力の用途であればとりあえず GPIO 17,18,21,22,23,24,25 の中から選んでおけば間違いない
  • PWM 出力の用途で使用できるのは GPIO 18 のみ

デジタル出力

1 で 3.3V, 0 で 0.0V です。

gpio -g mode 18 out
gpio -g write 18 1
gpio -g write 18 0

デジタル入力

gpio -g mode 18 in
gpio -g read 18

PWM 出力 (疑似アナログ出力)

0 (0.0V) から 1023 (3.3V) の範囲で調整します。

gpio -g mode 18 pwm
gpio -g pwm 18 0
gpio -g pwm 14 500
gpio -g pwm 14 1023

ピンの設定値を出力

gpio readall

任意のプログラミング言語から扱う

各プログラミング言語には外部コマンドを実行するための何らかの仕組みが備わっています。これを利用して gpio コマンドを操作すれば、任意のプログラミング言語で Raspberry Pi を制御できます。厳密なリアルタイム性が求められないマイコン制御は C/C++ だけのものではなくなりました。

The GPIO utility

This program, called gpio, can also be used in scripts to manipulate the GPIO pins – set outputs and read inputs. It’s even possible to write entire programs just using the gpio command in a shell-script, although it’s not terribly efficient doing it that way… Another way to call it is using the system() function in C/C++ or it’s equivalent in other programming languages.

Ruby

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

system "gpio -g mode 18 out"

while true do
  puts "GPIO 18 HIGH"
  system "gpio -g write 18 1"
  sleep 2.0
  puts "GPIO 18 LOW"
  system "gpio -g write 18 0"
  sleep 2.0
end

Perl

#!/usr/bin/perl
use strict;
use warnings;
use utf8;

system "gpio -g mode 18 out";

while(1) {
    print "GPIO 18 HIGH\n";
    system "gpio -g write 18 1";
    sleep 2;
    print "GPIO 18 LOW\n";
    system "gpio -g write 18 0";
    sleep 2;
}

Python

前述の通り RPi.GPIO を利用することもできます。コマンドを利用する場合は以下のようにできます。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import time

os.system("gpio -g mode 18 out")

while True:
    print "GPIO 18 HIGH"
    os.system("gpio -g write 18 1")
    time.sleep(2.0)
    print "GPIO 18 LOW"
    os.system("gpio -g write 18 0")
    time.sleep(2.0)

C/C++

C/C++ の場合は wiringPi ライブラリを include して利用することもできますが、以下のように system 関数を利用するのも簡単でよいですね。

#include <iostream>
#include <cstdlib>
#include <unistd.h>

using namespace std;

const int SLEEP_TIME = 2 * 1000 * 1000;

int main() {
    system("gpio -g mode 18 out");
    while(1) {
        cout << "GPIO 18 HIGH" << endl;
        system("gpio -g write 18 1");
        usleep(SLEEP_TIME);
        cout << "GPIO 18 LOW" << endl;
        system("gpio -g write 18 0");
        usleep(SLEEP_TIME);
    }
    return 0;
}

Java

class Main {
    public static void main(String args[]) {
        Runtime r = Runtime.getRuntime();
        try {
            r.exec("gpio -g mode 18 out");
            while(true) {
                System.out.println("GPIO 18 HIGH");
                r.exec("gpio -g write 18 1");
                Thread.sleep(2000);
                System.out.println("GPIO 18 LOW");
                r.exec("gpio -g write 18 0");
                Thread.sleep(2000);
            }
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    }
}

Scala

import scala.sys.process._
import scala.language.postfixOps

object Main {
  def main(args: Array[String]): Unit = {

    "gpio -g mode 18 out" !

    while(true) {
      println("GPIO 18 HIGH")

      "gpio -g write 18 1" !

      Thread.sleep(2000)
      println("GPIO 18 LOW")

      "gpio -g write 18 0" !

      Thread.sleep(2000)
    }
  }
}

シェルスクリプト

#!/bin/sh
gpio -g mode 18 out

while :
do
    echo "GPIO 18 HIGH"
    gpio -g write 18 1
    sleep 2
    echo "GPIO 18 LOW"
    gpio -g write 18 0
    sleep 2
done

仮想ファイルシステムについて

python の GPIO ライブラリでも gpio コマンドでも、内部的には OS が提供する仮想ファイルシステムが利用されています。

GPIO Sysfs Interface for Userspace

実用性はありませんが、例えば以下のシェルスクリプトで直接仮想ファイルシステムを操作してもデジタル出力が実現できます。

#!/bin/sh

# GPIO 14 を利用する宣言
echo 14 > /sys/class/gpio/export
sleep 1

# 出力に設定
echo 'out' > /sys/class/gpio/gpio14/direction

# HIGH/LOW トグル
cnt=1
while [ $cnt -lt 5 ]; do
    date +'%Y/%m/%d %H:%M:%S LOW'
    echo 0 > /sys/class/gpio/gpio14/value
    sleep 2
    date +'%Y/%m/%d %H:%M:%S HIGH'
    echo 1 > /sys/class/gpio/gpio14/value
    sleep 2
    cnt=`expr $cnt + 1`
done

# 後片付け
echo 14 > /sys/class/gpio/unexport
Likeボタン(off)0
詳細設定を開く/閉じる
アカウント プロフィール画像

GitHub Actions とか CI/CD が好きです。

記事の執筆者にステッカーを贈る

有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

>>さらに詳しくステッカーを贈る
ステッカーを贈る コンセプト画像

Feedbacks

Feedbacks コンセプト画像

    ログインするとコメントを投稿できます。

    ログインする

    関連記事