利用する機材
① LED1個
② ジャンパー線2本 (オス・メス)
③ 抵抗1個 (1kΩ)
④ ブレッドボード(小)
LED
LEDはプラス(アノード:長)とマイナス(カソード:短)が決まってます。
LEDを使うに当たり、Raspberryと直結すると、通常の御遊びのLEDであれば、即焼けるので、抵抗を直列に繋ぐのが一般的ですが、では、最低抵抗値は?
LEDの仕様:順電圧 (Vf) / 順電流 (If) の時、
抵抗値(R) =(電源電圧 - 順電圧)/ 順電流 で計算可能です。
(例)順電圧が2V、順電流が20mA のLED、Raspberryの電源電圧(5v)を利用する場合
R =(5V - 2V)/ 0.02A = 150 Ω
<勝手な個人見解>
LEDをAmazon等で買うのは良いのですが、順電圧や順電流の値を忘れ、結局、計算できず…
そんなズボラな私は、とりあえず1kΩで繋いでます。明かりが小さいと思えば、もう少し小さな抵抗値に変更です。
もちろん、何かが壊れたら、悲しみます… (痛い授業料です)
GPIO
Raspberry PI に用意された40本のピンですが、それぞれに役割があり、間違えて使うと本体が壊れる可能性もあるので、注意しましょう。
Raspberry 3や4では、外側が偶数ピン、SDカード側から順に並んでます。
特殊な事が出来るピンがあり(SDAやSCL等)、Lチカで使うなら、特殊な記載の無いピンを使いましょう。GND(Ground)は、マイナスを意味します。
私のRaspberry4では、4ピン(5V電源)と6ピン(GND)で冷却用のFANを常時回してます。
実機実装
11番ピン(GPIO17)をプラスに使い、9番ピン(GND)をマイナスに使います。
Raspberry本体にジャンパー線のメス、ブレッドボードにオスを刺し、11番と9番の間にLEDと抵抗を直列につなげます。
前準備
下記リンク先の手順で、RaspberryにPython-flaskでWeb表示する準備を済ませて下さい。
安価なWeb開発勉強環境の構築①
プログラムの用意
まずは、普通にLチカしてみましょう
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
try:
while True:
GPIO.output(17, 1)
time.sleep(0.5)
GPIO.output(17, 0)
time.sleep(0.5)
except KeyboardInterrupt:
print("Ctrl+C pressed. Cleaning up...")
GPIO.cleanup()
python3 ltika.py (プログラム実行)
LEDがチカチカと点滅したら、普通のLチカ完成です。
CTRLキー+Cで、プログラムを停止します。
余談
source /flask/test1/venv/bin/activate (仮想環境に切り替えて)
python3 ltika.py (プログラム実行)
エラー「ModuleNotFoundError: No module named 'RPi'」が表示されます。
これは、仮想環境にGPIOのパッケージが無い為に表示されるエラーです。
対応方法としては、少しコツがあって、、、
sudo apt-get install pip (コツ=デフォルトのpipを補填します)
pip install RPi.GPIO (仮想環境にGPIOのパッケージを用意します)
python3 ltika.py (プログラム実行)
正常に、LEDがチカチカと点滅しますよね。 <OK>
Webの制御画面を用意してみましょう
├── app
│ ├── templates
│ │ └── main.html
│ ├── gpio_on.py (LEDをONするプログラム)
│ ├── gpio_off.py (LEDをOFFするプログラム)
│ └── __init__.py
└── app.wsgi
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/flask/test1")
from app import app as application
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"></head>
<body>
<a href="?parm=on">点灯</a><br><br><br>
<a href="?parm=off">消灯</a>
</body>
</html>
import subprocess
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
if request.args.get('parm') == 'on':
subprocess.call("sudo python /flask/test1/app/gpio_on.py", shell=True)
elif request.args.get('parm') == 'off':
subprocess.call("sudo python /flask/test1/app/gpio_off.py", shell=True)
else:
subprocess.call("sudo python /flask/test1/app/gpio_off.py", shell=True)
return render_template('main.html')
if __name__ == '__main__':
app.run()
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
GPIO.output(17, 1)
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
GPIO.cleanup()
処理の説明
このままRaspberryを再起動して、「http://(RaspberryのIPアドレス):8080」へアクセスしても、想定通りの処理が行えません。
理由は、Web表示するプロセスが、「app/__init__.py」の「sudo python」を実行する際、権限が足らず実行できない為です。
sudoの制御は管理者権限を有するユーザが実行する必要があります。
この現象の対応の為、apacheとFlaskで実行されているユーザの、「www-data」に対して、「sudo python」を実行する権限を付与します。
sudo visudo (sudoの実行権限を設定)
root ALL=(ALL:ALL) ALL
+ www-data ALL=(ALL:ALL) NOPASSWD: /usr/bin/python
この後、Raspberryを再起動して、「http://(RaspberryのIPアドレス):8080」へアクセスし、「点灯」「消灯」をクリックしてみましょう。 <おしまい>
注意
「www-data」に対して、「sudo」の権限を付与していますが、一般的なWeb開発ではセキュリティ問題となる悪手です。
Webプロセスはハッカーに狙われやすい機能であり、強い権限を付与するのはリスクとなるので注意しましょう。