PythonでLEDを点滅させる ~その2~
今回は、ひとつ前の記事「PythonでLEDを点滅させる ~その1~」で触れなかったプログラムの内容について解説します。少し長くなりますがお付き合い頂けたら幸いです。
さて、前回はコマンドラインで以下のコマンドとURLを入力してLED点滅用のプログラムをダウンロードしたと思います。
wget http://osoyoo.com/driver/pi3_start_learning_kit_lesson_4/pythontest.py
プログラム名は「pythontest.py」です。ダウンロードしたプログラムのコードはnanoエディタというテキストエディタ上で起動することにより見たり編集したりすることができます。起動には以下のコマンドを入力します。
sudo nano pythontest.py
プログラムの中身は以下の通りです。
import PRi.GPIO as GPIO
import time
# set GPIO 0 as LED pin
LEDPIN=17
def print_message():
print ('|*********************************|')
print ('| blink LED |')
print ('| ------------------------- |')
print ('| LED connect to GPIO |')
print ('| |')
print ('| LED will blink at 500ms |')
print ('| ------------------------- |')
print ('| |')
print ('| OSOYOO |')
print ('********************************** ')
print ('Program is running...')
print ('Please press Ctrl+C to end the program...')
def setup():
GPIO.setwarnings(False)
#set the gpio modes to BCM numbering
GPIO.setmode(GPIO.BCM)
#set LedPin's mode to output,and initial level to LOW(0V)
GPIO.setup(LEDPIN,GPIO.OUT,initial=GPIO.LOW)
#main function
def main():
#print info
print_message()
while True:
GPIO.output(LEDPIN,GPIO.HIGH)
print('...LED ON ')
time.sleep(0.5)
GPIO.output(LEDPIN,GPIO.LOW)
print('LED OFF... ')
time.sleep(0.5)
pass
pass
#define a destroy function for clean up everything after the script finished
def destroy():
#turn off LED
GPIO.output(LEDPIN,GPIO.LOW)
#release resource
GPIO.cleanup()
#if run this script directly ,do:
if __name__== '__main__':
setup()
try:
main()
#when 'Ctrl+C' is pressed, child program destroy() will be excused.
except KeyboardInterrupt:
destroy()
なにやら長くて難しく感じてしまいますが、順番に解説していきますのでご辛抱ください。まずこのプログラムは大きく分けて、①赤色のコード:必要なライブラリのインポート、②紫色のコード:使用するGPIOピンの指定、③緑色のコード:LED点滅に使用する関数の定義、④茶色のコード:関数の実行(LEDの点滅)、の4つのパートに分かれています。以下、各パートごとに解説していきます。
①必要なライブラリのインポート
LEDを点滅させるためには、RaspberryPiからGPIOピンを介してLEDへ信号を出力したり、出力する時間を制御したりする必要があります(例えば1秒間信号を出力してLEDを光らせた後、1秒間出力を止める。これを繰り返せば1秒おきにLEDは点滅する)。そのため、今回はGPIOピンの制御に使用する「PRI.GPIO」と時間の制御に使用する「time」の2つのライブラリをインポートします。
インポートは、
import ライブラリ名(今回の場合、RPI.GPIOやtimeのこと)
で実施します。ちなみに、
import ライブラリ名 as ○○
と入力するとライブラリ名を○○に置き換えることができ、ライブラリ名が長い場合は後々コードを書く作業が楽になります。今回は、PRI.GPIOをGPIOという名前に置き換えています。
PRI.GPIOとtimeは電子工作において必須のライブラリと言えます。プログラムを作成する際はコードの冒頭に必ずimport PRI.GPIOとimport timeを書いておきましょう。
②使用するGPIOピンの指定
ここはLEDPINという変数を定義しているだけです。今回の場合、GPIO17から信号を
出力するので17を指定します。
③ LED点滅に使用する関数の定義
ここがLEDを点滅させるのに一番大事なパートになります。プログラムでは同じ動作を何度も繰り返すことがよくあるので、繰り返し行う動作をひとつの関数として定義してしまいます。これによって、いちいち同じコードを書き直さなくても関数名を指定するだけで済みます。関数は以下のように定義します。
def 関数名():
関数の内容
ダウンロードしたプログラムでは、【1】print_message、【2】setup、【3】main、【4】destroy、の4つの関数が定義されています。このうち【1】はただコマンドラインに文字を表示するだけのプログラムなのでLEDの動作とは関係ありません。よってここでの解説は省略します。
【2】setup
GPIOでLEDを制御するための前準備にあたる関数です。最初にimport PRI.GPIO as GPIOと置き換えたので、コードに記されたGPIOはPRI.GPIOライブラリのことを指します。GPIO.○○と書くことでPRI.GPIOライブラリの関数を利用できます。
GPIO.setwarnings(False)
↑ 書かなくても問題ないです。setwarnings(False)とすることでGPIOピンの値がデフォルト値じゃないときに表示される警告を無視することができます。警告はGPIOピンを使った別のプログラムが並行で動作しているときなどに表示されます。
GPIO.setmode(GPIO.BCM)
↑ GPIOピンの番号を定義します。setmode(GPIO.BCM)ならBCMで番号指定。setmode(GPIO.BOARD)ならピンの並び順で番号指定。詳しく知りたい方は、「PythonでLEDを点滅させる ~その1~」か下記サイトを参考にしてみてください。
http://mamerium.com/raspberry-pi-rpi-gpio-basic/
GPIO.setup(LEDPIN,GPIO.OUT,initial=GPIO.LOW)
↑ setup(ピン番号,GPIO.OUT,initial=GPIO.LOW)は「指定したピンを,出力端子として使用します,初期値は0です」という意味になります。今回はLEDPIN=17と定義しているので、「GPIO17のピンからLEDへ出力します。最初は出力しません」という意味になります。
【3】main
LEDを点滅させる関数です。ここのプログラムに変更を加えることでLEDを点滅させるタイミングなども変えることができます。
print_message()
↑ 【1】のprint_message関数です。説明は省きます。
while True:
↑ While True:構文を使うとエラーが発生しない限り、コロン以降の字下げされたコードをひたすら繰り返します。以下は字下げされたコードです。
GPIO.output(LEDPIN,GPIO.HIGH)
print('...LED ON ')
time.sleep(0.5)
GPIO.output(LEDPIN,GPIO.LOW)
print('LED OFF... ')
time.sleep(0.5)
pass
↑ GPIO.output(LEDPIN,GPIO.HIGH)でGPIO17のピンの出力を1にする→print('...LED ON ')でコマンドラインに「...LED ON」と表示する( は改行を意味します)→time.sleep(0.5)で上記の状態を0.5秒間キープする
その後、GPIO.output(LEDPIN,GPIO.LOW)GPIO17のピンの出力を0にする→print('LED OFF... ')でコマンドラインに「...LED OFF」と表示する)→time.sleep(0.5)で上記の状態を0.5秒間キープする
passは字下げされたコード部分で例外が発生したときに何もしないという意味です。これによりエラーによるプログラムの停止を避けることができます。
【4】destroy
LED点滅プログラムを停止するための関数です。プログラムでWhile true:を使っているので、この関数がないとひたすらLEDは点滅し続けます。
GPIO.output(LEDPIN,GPIO.LOW)
GPIO.cleanup()
↑ GPIO17からの出力を0にし、GPIO.cleanup()でピンの設定を初期化します。cleanupを最後に行わないとsetup関数で設定した情報が残るため、別のプログラムを実行したときに誤作動を引き起こす可能性があります。
④関数の実行(LEDの点滅)
最後に関数の実行です。ここでは③で定義した各関数を呼び出すことでLEDを点滅させます。
if __name__== '__main__':
↑ if○○:は○○の条件がTrueである場合のみに、コロン以降の字下げされた部分のコードを実行するという構文です。__name__== '__main__'は今回扱ったプログラムをコマンドライン上で実行した場合のみTrueとなることを意味します。逆に、import python test.pyのように他のプログラムでモジュールとして呼び出した場合、Falseになりif構文に含まれたコードは実行されないということです。ここは私も今一つ理解できていませんが、詳しく知りたい方は以下のURLが参考になるかもしれません。
https://qiita.com/taigamikami/items/2713856b9f3c3b90f6fd
http://programming-study.com/technology/python-if-main/
setup()
try:
main()
except KeyboardInterrupt:
destroy()
↑ setup関数→main関数→例外が発生した場合はdestroy関数、という内容のコードです。ここで、try:とexcept エラー名:はセットで使われる構文で、tryの中で発生したエラーがexceptで指定したエラーと一致する場合はexceptの中のプログラムを実行するというものになります。そして、KeyboardInterruptはctrl+cを検出する関数です。よってここのコードは「try内のmainを実行するが、コマンドラインでctrl+cが入力された場合はdestroyを実行する」という意味で、もっとわかりやすく言うと「ctrl+cが入力されたらLEDの点滅を終了する」ということになります。
プログラムの内容の解説は以上になります。次回は、より複雑な信号をLEDに出力する方法について解説していきたいと思います。