1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LチカをWebで制御する

Posted at

利用する機材
① 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チカしてみましょう

ltika.py
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の制御画面を用意してみましょう

フォルダ構成 (/flask/test1)
├── app
│   ├── templates
│   │   └── main.html
│   ├── gpio_on.py   (LEDONするプログラム)
│   ├── gpio_off.py   (LEDOFFするプログラム)
│   └── __init__.py
└── app.wsgi
app.wsgi
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/flask/test1")
from app import app as application
app/templates/main.html
<!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>
app/__init__.py
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()
app/gpio_on.py
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
GPIO.output(17, 1)
app/gpio_off.py
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プロセスはハッカーに狙われやすい機能であり、強い権限を付与するのはリスクとなるので注意しましょう。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?