はじめに
訳あってLEDを用いた飾りつけを作ろうと思い立った。
ちょうど手元にマイコンボード「Raspberry Pi Pico W」があったため、これを使って製作することにした。
目次
作ったもの
スイッチを押したらしばらくLEDが点滅し続け、その後消灯するもの。
Raspberry Pi Pico Wを使用(以下ラズパイと呼称)。
ハード設計
・LEDの選定
今回点灯させるLEDはダイソーで調達した。スイッチをON/OFFさせるタイプなので、分解すれば簡単に流用できるはず。
分解すると、電池二本を直列に繋いでいるだけだった。3Vくらいの電圧を与えれば動く。
ただ、このLEDは正体が不明であるため、まずは動作電圧と消費電流を確認しておく必要がある。黄色い線は実験用に引き出した。
この時の消費電流は約150mA。明るさは充分である。
LEDが複数付いているという時点で当然ではあるが、ラズパイのGPIOから供給できる電流(4mA)を遥かに超えているため、外部電源から供給する方針で回路を作成する。
・回路構成
下記のような回路図を作成した。
ラズパイのGPIOピンでFETのゲート電圧を制御し、LEDに流す電流のON/OFFを切り替えるものである。
プログラム作成
LEDのON/OFFを切り替えるために作成したプログラムは下記の通り。
スイッチが押されると10回LEDが点滅する。
import machine
import utime
mode = 0 #点灯モード
period = 2 #点灯モードの周期(秒)
loop_count = 0 #点灯中のループカウンタ
loop_count_max = 10 #点灯中のループ回数
sw = machine.Pin(17, machine.Pin.IN, machine.Pin.PULL_UP) #スイッチピン準備
led = machine.Pin(16, machine.Pin.OUT) #LEDピン準備
while True:
#スイッチ押下でモードを切り替え
if sw.value() == 0:
mode = mode + 1
print("mode: " + str(mode))
#点灯処理
if mode == 0: #消灯
loop_count = 0
elif mode == 1: #点滅
if loop_count < loop_count_max:
led.value(1)
utime.sleep(period / 2)
led.value(0)
utime.sleep(period / 2)
loop_count = loop_count + 1
else:
mode = 0
loop_count = 0
else:
mode = 0
loop_count = 0
電源の改善
ここまでの設計でも実験室レベルでは動くが、電源に関して下記2点を改善したい。
1. 電源が2系統必要。
2. モバイルバッテリーは未使用状態が続くと電源がOFFになってしまう。
そこで、下記構成に変更してこれらの点を解決した。
電圧を昇降圧できる基板(XC9306搭載)を使うことで、不安定な電圧を出す電池からの安定した電圧供給を実現している。また、常時給電も可能になった。
点灯方法の改善
ここまで作ってきたような単純にON/OFFさせる方法だと、点滅が目に痛いように感じた。
そこで、ONとOFFをPWMで緩やかに制御し、柔らかい点滅にする。
新しいプログラムは下記の通り。
import machine
import utime
from machine import PWM
mode = 0 #点灯モード
period = 6 #点灯モードの大まかな周期(秒)
loop_count = 0 #点灯中のループカウンタ
loop_count_max = 5 #点灯中のループ回数
light_div = 6553 #明るさの分割数
#点灯の見た目を良くするためのSleep時間
delay_on = 0.4
delay_off = 0.6
sw = machine.Pin(17, machine.Pin.IN, machine.Pin.PULL_UP) #スイッチピン準備
#led = machine.Pin(16, machine.Pin.OUT) #LEDピン準備
led = PWM(machine.Pin(16, machine.Pin.OUT))
led.freq(1000)
led.duty_u16(0)
while True:
#スイッチ押下でモードを切り替え(点滅⇔消灯)
if sw.value() == 0:
mode = mode + 1
print("mode: " + str(mode))
#点灯処理
if mode == 1: #点滅
if loop_count < loop_count_max:
for i in range(light_div): #徐々に明るく
led.duty_u16(i*10)
utime.sleep((period-delay_on-delay_off) / (2*light_div))
utime.sleep(0.6) #点滅の見た目を良くするためのSleep
for i in range(light_div): #徐々に暗く
led.duty_u16((light_div-i)*10)
utime.sleep((period-delay_on-delay_off) / (2*light_div))
utime.sleep(0.6) #点滅の見た目を良くするためのSleep
loop_count = loop_count + 1
else:
mode = 0
loop_count = 0
else: #消灯
mode = 0
loop_count = 0