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

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

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

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

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

モーダルを閉じる

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

モーダルを閉じる

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

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

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

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

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

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

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

目次

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

    0
    ステッカーを贈るとは?

    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
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

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

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

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

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

    Feedbacks

    Feedbacks コンセプト画像

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

      関連記事