Raspberry Pi Pico WでLEDを点滅させる

## はじめに
訳あってLEDを用いた飾りつけを作ろうと思い立った。
ちょうど手元にマイコンボード「Raspberry Pi Pico W」があったため、これを使って製作することにした。

## 目次
- [作ったもの](#作ったもの)
- [ハード設計](#ハード設計)
- [プログラム作成](#プログラム作成)
- [電源の改善](#電源の改善)
- [点灯方法の改善](#点灯方法の改善)

## 作ったもの
スイッチを押したらしばらくLEDが点滅し続け、その後消灯するもの。
Raspberry Pi Pico Wを使用（以下ラズパイと呼称）。

## ハード設計
・LEDの選定
今回点灯させるLEDはダイソーで調達した。スイッチをON/OFFさせるタイプなので、分解すれば簡単に流用できるはず。
![241119191533575.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/17d64ae1-abcc-ad41-1ce1-62cb90a31b97.jpeg)

分解すると、電池二本を直列に繋いでいるだけだった。3Vくらいの電圧を与えれば動く。
ただ、このLEDは正体が不明であるため、まずは動作電圧と消費電流を確認しておく必要がある。黄色い線は実験用に引き出した。
![241119191719783.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/5a3248fc-c56a-2fac-3a67-72d235339263.jpeg)

そこで、安定化電源で3Vを入れて点灯の確認を行った。
![241119192321127.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/fb856f40-3a3b-8e0c-3b09-642a4ce66ee2.jpeg)

この時の消費電流は約150mA。明るさは充分である。
LEDが複数付いているという時点で当然ではあるが、ラズパイのGPIOから供給できる電流（4mA）を遥かに超えているため、外部電源から供給する方針で回路を作成する。

・回路構成
下記のような回路図を作成した。
ラズパイのGPIOピンでFETのゲート電圧を制御し、LEDに流す電流のON/OFFを切り替えるものである。
![circuit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/e347ea35-7c74-175b-a193-cfc6fa6c1e1b.png)

電源供給は下記構成にて行っている。
![supply.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/62e9c326-fc2e-b33b-2948-55797ddcb262.png)

## プログラム作成
LEDのON/OFFを切り替えるために作成したプログラムは下記の通り。
スイッチが押されると10回LEDが点滅する。
```main.py
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になってしまう。

そこで、下記構成に変更してこれらの点を解決した。
![circuit_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/a1b463cc-4a6e-e734-5e6f-2a204bf76c19.png)
電圧を昇降圧できる基板（XC9306搭載）を使うことで、不安定な電圧を出す電池からの安定した電圧供給を実現している。また、常時給電も可能になった。

![circuit_picture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/e7cdb475-7205-498a-2a87-4c7467ad376b.png)
（クリスマスが近いため、配線はクリスマスカラーにした）

## 点灯方法の改善
ここまで作ってきたような単純にON/OFFさせる方法だと、点滅が目に痛いように感じた。
![Animation_0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/dbc7d336-7548-5ab6-580f-a4de9888e4ce.gif)
そこで、ONとOFFをPWMで緩やかに制御し、柔らかい点滅にする。
新しいプログラムは下記の通り。
```main.py
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
```

目に優しい点滅へ変わった。
![Animation_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/00a95296-1a67-7ffe-fa9c-d5f83c3d2384.gif)