せっかくなのでラズパイでLEDを光らせてみる(RPi.GPIO)

f:id:atuyosi:20161110045042j:plain:w480

なんとなくラズパイ買ったらやっておかないといけないような気がしたので(使命感?)。

ネタ元はトランジスタ技術 2016年 11月号

横着なのでGPIOとブレッドボードの接続はT字の接続基板キットを使用。

LED、抵抗(金属皮膜抵抗器?)、タクトスイッチとブレッドボードのセット商品。LEDのデータシートのようなものは付属しません*1

LEDの定格電流が不明ですが、とりあえず光ればいいので付属の抵抗の小さい方(1KΩ)を使うことにします。

ブレッドボードなんて学生時代以来です。オペアンプで増幅回路を組んで特性を調べるとかいう実験だったかな。

一応、目次。 [:contents]

接続とPython プログラム

タクトスイッチ、1Kの抵抗2本、赤と黄のLEDを繋ぎます。回路図は省略*2

GPIOへの接続はラズパイ側の電源を切った状態で行うこと。

  • LED側:T字基板側(P25に黄色、P28に赤色)から1Kの抵抗器*3をはさんでLEDのプラス極(長い方)をGNDへ
  • タクトスイッチ:一方の端子をGNDに接続、もう一方をGPIOの適当なポート(P26)

接続先のポートはピンの対応関係がよくわからずに試行錯誤した結果で特に意味はないです。プログラム側で意図した配置と実際のアサインがずれたりとかそういうしょうもない理由です。ジャンパ線がスイッチを押す際の邪魔にならないようにずらしたらこうなりました。

f:id:atuyosi:20161110043644j:plain:w480

プルアップ (or プルダウン)抵抗について

別途抵抗を用意して接続する例が多いですが、配線がごちゃっとなるのが嫌なのでラズパイのチップ側に内蔵されているプルアップ抵抗を利用することにします。

プルアップ抵抗、プルダウン抵抗の説明は以下のサイトがわかりやすい。

mamerium.com

正確な説明が必要なら電子工作の本を購入する方がベターかと。

Python プログラム

Python 2.x 用です。Print 文を除去すれば3.x でも動くはず。

GPIOポートの番号はgpio readilyコマンドで確認できます。T字基板側の表記については後述。

import RPi.GPIO as GPIO
from time import sleep

led_a = 20 # p28
led_b = 26 # p25

switch = 12 #p26

GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)


# pull up 抵抗の有効化
GPIO.setup(switch, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.setup(20, GPIO.OUT, initial=GPIO.LOW) 
GPIO.setup(26, GPIO.OUT, initial=GPIO.LOW)

try:
    while True :
        if(GPIO.input(switch) == 1 ):
            print "high"
            GPIO.output(led_a, GPIO.HIGH)
            sleep(0.5)
            GPIO.output(led_a, GPIO.LOW)
            sleep(0.5)
        else:
            print "low"
            GPIO.output(led_b, GPIO.HIGH)
            sleep(0.5)
            GPIO.output(led_b, GPIO.LOW)
            sleep(0.5)

except KeyboardInterrupt:
    pass

GPIO.cleanup()

冒頭に書いた通り、雑誌に記載のPythonプログラムほぼそのままです。注意点はGPIO.setupの引数ぐらいでしょうか。この箇所はプルアップ抵抗を使うのか、あるいはプルダウン抵抗を使うのかを指定します。未指定の場合はどちらも使わない設定になります。

タクトスイッチを押すと点滅するLEDが切り替わるだけ、です。

結果

適当なファイル名で保存して、実行するだけ。例えばswitch_led.pyという名前で保存したとすると、以下のようにpythonインタプリタで実行。sudoは不要です(後述の補足参照)。

$ python switch_led.py

初期状態では(内蔵の)プルアップ抵抗のおかげでスイッチからの入力は"1" (high)なので黄色いLEDが点滅。スイッチを押すと赤いLEDが点滅。

f:id:atuyosi:20161110050544g:plain

赤い方のLEDの点滅が綺麗に撮れていないです。スイッチを押し込んでからの反応に若干ラグがありますが、ちゃんと点滅しています。というか、それだけです。

iPhoneで撮影して下記のアプリでgifにしてみました。意外にサイズが小さくならないのか。

PicGIF Lite

PicGIF Lite

  • PearlMountain Technology
  • 写真
  • 無料

有料版だとクリッピングもできるのかな。

PicGIF

PicGIF

  • PearlMountain Technology
  • 写真
  • ¥600

各種補足

タクトスイッチの解説

実を言うと最初どう使うのかわからずにググりました。型番すら書いてないし。

とりあえず以下のサイトが詳しいかと。

タクトスイッチを使いこなそう! | Electronics Work House

内部構造さえわかれば使い方は別に難しくないです。

まず端子の出ている面を横にして、右上と左上、右下と左下の端子は内部で接続された状態。スイッチを押さない限り上下の端子間は分離されていて、スイッチを押すと上下が接続される仕組み。

物自体は見たことはあっても実際に繋いだのは初です。電気工学科卒なのに……。材料系の研究室だったので縁がなかったです*4

RPi.GPIO と管理者権限

少なくともこの記事を書いている時点ではディストリビューション次第ですが不要です。以前はGPIOにアクセスする際に管理者権限が必要だったのは確かなようです。

現状ではGPIOへのアクセス手段として/dev/gpiomemが提供されるようになった関係で、このデバイスファイルのパーミッションを適切に設定するだけで解決します。

Raspbian環境であれば、ユーザーをgpioグループに所属させるだけでOKです。Raspbianであれば初期設定済み。

pi@raspberrypi:~ $ ls -l /dev/gpiomem
crw-rw---- 1 root gpio 244, 0 11月  8 19:04 /dev/gpiomem
pi@raspberrypi:~ $ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio docker

最後のdocker以外が初期設定ユーザーpiがデフォルトで所属しているグループです。ちゃんとgpioグループの所属になっています。

関連:Add /dev/gpiomem device for rootless user GPIO access by Wren6991 · Pull Request #1112 · raspberrypi/linux · GitHub

ブレッドボードとT字基盤の補足

便利なのだが、中途半端に信号線の名称で記載されているためにピンアサインが非常にわかりにくい。

gpio readallの出力と基板の表示を見れば大体対応が判断できる。ただし、SDA.0SCL.0SDA.1SCL.1いうピンが存在するはずだが、印字されている信号名はSDASCLしかない。

以下にgpio readallの結果を示しておく。

f:id:atuyosi:20161108232605p:plain

また、Amazon のレビューに独自の変換表を作成された方がいる。これは非常にありがたい。

Amazon.co.jp: cocopar Raspberry Pi model B+/raspberry pi...の たかさんのレビュー

この表からすると、SDA.0SCL.0はそれぞれ、IDSAIDSCということになる。


接続のわかりやすさという点ではU字基盤の方がいいかもしれない。

まとめ

機会があればpigpio libraryを試してみたい。あとはボタンなしで交互に点滅させるとか、LEDの数を増やすとかやりようはある。

本命はこっちじゃなくてWebカメラの方。LEDはまたいずれ暇があれば。

参考URL

*1:型番も不明

*2:そもそもネタ元の雑誌にすら未記載

*3:本来はもっと低い抵抗でいいはずだが付属品がこれなので

*4:モーターの始動法とか円線図とか強電よりの実験は結構やりましたよ、もちろん忘却の彼方ですが