強弱をつけてLEDを点滅させる

こんにちは。

大分期間が空いてしまいましたが、LEDをただ光らせるのではなく明るくしたり、暗くしたり、強弱をつけて点滅させる方法について解説していきます。

詳細は下記URLを参照してください↓

http://osoyoo.com/2017/06/26/pi3-breathing-led/

 

PWMとは?

強弱をつけて点滅させるためには「PWM (Pulse Width Modulation)」という信号を使う必要があります。ご存知の通り、GPIOから出力される信号はデジタル信号なので0か1です。そのため、普通に考えればLEDの明るさを調整するなんてできるはずがありません。しかし、LEDは半導体なので電圧が加わってから明るくなるまでに多少のラグがあります(扇風機の電源を入れると最初ハネはゆっくり回って徐々に回転を上げていくあの現象をイメージして下さい)。この性質をうまく活用して、電圧を加える時間を調整することでLEDの明るさを調整します。「PWM」について詳しく知りたい場合は下記URLを参照してください↓

https://toshiba.semicon-storage.com/jp/design-support/e-learning/brushless_motor/chap3/1274512.html

 

LEDの配線

PWMに関する説明はここまでとして、まずLEDの配線を行います。以下配線図と実際の配線の様子です。今回はGPIO18のピンを使用します。前回も申し上げましたが、LEDの向きに気をつけて下さい。

f:id:eifme0840:20180805200646p:plain

f:id:eifme0840:20180805200755j:plain

 

プログラムのダウンロード

配線が終わったら、osoyooからプログラムをダウンロードします。コマンドラインを立ち上げて下記のコマンドを入力します。

sudo wget http://osoyoo.com/driver/pi3_start_learning_kit_lesson_6/breathing_led.py

ダウンロードしたプログラムの内容は下記の通りです。

import RPi.GPIO as GPIO
import time

#set BCM_GPIO 18(GPIO1) as LED pin
LEDPIN = 18

#print message at the begining ---custom function
def print_message():
 print ('|**********************************|')
 print ('| Breath LED |')
 print ('| ---------------------------- |')
 print ('| LED Connect to GPIO1 |')
 print ('| ---------------------------- |')
 print ('| |')
 print ('| OSOYOO|')
 print ('|**********************************|\n')
 print ('Program is running...')
 print ('Please press Ctrl+C to end the program...')
 pass

#setup function for some setup---custom function
def setup():
 global p
 GPIO.setwarnings(False)
 #set the gpio modes to BCM numbering
 GPIO.setmode(GPIO.BCM)
 #set all LedPin's mode to output,and initial level to HIGH(3.3V)
 GPIO.setup(LEDPIN,GPIO.OUT,initial=GPIO.LOW)

 #set LEDPIN as PWM output,and frequency=100Hz
 p = GPIO.PWM(LEDPIN,100)
 #set p begin with ualue 0
 p.start(0)
 pass

#main function
def main():
 #print info
 print_message()
 while True:
  print("|****************************|")
  print("| Increase duty cycle |")
  print("|****************************|")
  #increase duty cycle from 0 to 100
  for dc in range(0,101,4):
   #chang duty cycle to dc
   p.ChangeDutyCycle(dc)
   time.sleep(0.1)
   pass
  print("|****************************|")
  print("| Decrease duty cycle |")
  print("|****************************|")
  #decrease duty cycle from 100 to 0
  for dc in range(100,-1,-4):
   #change duty cycle to dc
   p.ChangeDutyCycle(dc)
   time.sleep(0.1)
   pass
  pass
 pass

#define a destroy function for clean up everything after the script finished
def destroy():
 #stop p
 p.stop()
 #turn off led
 GPIO.output(LEDPIN,GPIO.LOW)
 #release resource
 GPIO.cleanup()
 pass

# if run this script directly ,do:
if __name__ == '__main__':
 setup()
 try:
  main()
 #when 'Ctrl+C' is pressed,child program destroy() will be executed.
 except KeyboardInterrupt:
  destroy()
  pass
pass

 

コードの解説

前回解説した「LEDを点滅させる」場合と異なるのは赤文字青文字で示したコードです。そこだけ解説していきます。

※なお、

PythonでLEDを点滅させる ~その2~ - ひまひま電子工作

で解説済みのコードの解説は割愛します。

setup関数

この関数でPWMの設定を行っています。

global p 

↑変数の前にglobalを入れることで、関数の外でも変数を使えるようにします。実際、ここでのpという変数はmain関数でもdestroy関数でも使われています。
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LEDPIN,GPIO.OUT,initial=GPIO.LOW)
p = GPIO.PWM(LEDPIN,100)

↑GPIO.PWM(ピン番号,100)とすることで指定したPINでPWMが使用できるようになります。今回はLEDPIN=18なのでGPIO18のピンでPWMを使うということです。ちなみに100はPWMの周波数を100Hzにするという意味です。
p.start(0)

↑pの最初の出力を0にします。
pass

main関数

LEDを徐々に明るくしてその後徐々に暗くする動作を実行します。

 print_message()
 while True:
  print("|****************************|")
  print("| Increase duty cycle |")
  print("|****************************|")
  for dc in range(0,101,4):
   #chang duty cycle to dc
   p.ChangeDutyCycle(dc)
   time.sleep(0.1)
   pass

↑ChangeDutyCycleでsetup関数で定義したpにPWM信号を出力します。for dc in range(0,101,4)となっており、すなわち0から最大出力の101までを4のステップで上げていくことになります。101を変更すれば最大時の明るさを変更できますし、4を変更すれば最大の明るさになるまでのスピードを変更することができます。
  print("|****************************|")
  print("| Decrease duty cycle |")
  print("|****************************|")
  for dc in range(100,-1,-4):
   #change duty cycle to dc
   p.ChangeDutyCycle(dc)
   time.sleep(0.1)
   pass

↑今度はfor dc in range(100,-1,-4)となっており、明るい状態から徐々に暗くしていく、というコードです。
  pass
 pass

 

プログラムの実行

ではプログラムを実行します。コマンドラインで下記コマンドを入力することで実行可能です。

sudo python breathing_led.py

実行後の動作の様子は下記の通りです。


 

ちなみに複数のGPIOピンを使うとPWMでこんなこともできます。


 

以上になります。PWMを活用することで電子工作はより楽しいものになるはずです。ぜひ活用してください。