Raspberry Pi PicoでPicoMite(MMBasic)を使う〜PWM

PicoMite(MMBasic)ではPWM（パルス幅変調）を容易に利用できるコマンドが用意されている。ここではLEDの点灯をPWMで制御する方法を試した結果を示す。

# 使用部品

赤色LED2本、330Ωの抵抗器2本を使用する。

# 配線

下記のように配線した。2本のLEDはGP0とGO1にそれぞれ接続した。

<!-- 配線図 -->
![PICO-PWM_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72921/8a87a67c-0ee4-48e3-b616-08053adfff02.png)


# プログラム

2つのLEDを一つずつ徐々に明るく点灯させ、最後に2本とも徐々に暗くするプログラムを以下に示す。

```BASIC:PWM.bas
SetPin GP0, PWM             ' Define GP0 as a PWM0A
SetPin GP1, PWM             ' Define GP1 as a PWM0B
' Increases the duty cycle from 0% to 100% in 10% increments.
For I% = 0 To 100 Step 10
  PWM 0, 10, I%             ' Output to PWM channel 0A
  Pause 300                 ' Wait 300 msec
Next I%
' Increases the duty cycle from 0% to 100% in 10% increments.
For I% = 0 To 100 Step 10
  PWM 0, 10,, I%            ' Output to PWM channel 0B
  Pause 300                 ' Wait 300 msec
Next I%
'Increases the duty cycle from 100% to 0% in 10% decrements.
For I% = 100 To 0 Step -10
  PWM 0, 10, I%, I%         ' Output tp PWM channel 0A and 0B
  Pause 300                 ' Wait 300 msec
Next I%

PWM 0, OFF                  ' Stop PWM output

End
```

このプログラムは次に示す動作をする。
- PWM出力ピンとしてGP0をチャンネル0の出力A、GP1をチャンネル0の出力Bとして定義している
- 1番目のFORループでチャンネル0の出力Aに10HZの信号を300ミリ秒間隔でデューティサイクルを10%ずつ増やしながらPWM出力する
    - ループが完了するとLEDが最も明るく点灯している
- 2番目のFORループはチャンネル0の出力Bに1番目と同じように出力する
    - ループが完了するとLEDが最も明るく点灯している
- 3番目のFORループでチャンネル0の2つの出力（AとB）にデューティサイクルを100％から10％ずつ減らしながらPWM出力する
- 最後にチャンネル0へのPWM出力を停止する

## 実行結果の動画

![PWM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72921/1e20ca80-a6ed-494b-a444-ef1f72d78825.gif)


# PicoMite(MMBasic)のPWM機能

PicoMite(MMBasic)は`SETPIN`コマンドで指定したピンに対して`PWM`コマンドで容易に指定したデューティサイクルの矩形波を生成できます。

## PWMのチャンネル

プロセッサの種類によってPWMで利用できるチャンネルはしたの表に示すように異なっている。

| CPU    | チャンネル数 | チャンネル番号 | 出力  |
| ------ | :----: | :-----: | --- |
| RP2040 |   16   |   0〜7   | AとB |
| RP2350 |   24   |  0〜12   | AとB |

Raspberry Pi PicoとPico 2でPWMに利用できるピンは下記のチャンネル番号と出力AとBの組み合わせがあり、全部で26本を利用できます。

| チャンネル番号 |    出力A     |    出力B     |
| :-----: | :--------: | :--------: |
|    0    | GP0, GP16  | GP1, GP17  |
|    1    | GP2, GP18  | GP3, GP19  |
|    2    | GP4, GP20  | GP5, GP21  |
|    3    | GP6, GP22  |    GP7     |
|    4    |    GP8     |    GP9     |
|    5    | GP10, GP26 | GP11, GP27 |
|    6    | GP12, GP28 |    GP13    |
|    7    |    GP14    |    GP15    |

## PWM出力するピンの設定

MMBasicでPWMを利用するには`SETPIN`コマンドでPWM出力に使用するピンを指定します。

```
SETPIN ピン番号, PWM
```

## PWM出力の実行

PWM出力するにはPWMコマンドを使います。PWMコマンドの構文は次の通りです。

```
PWM channel, frequency, [dutyA][,dutyB][,phase][,defer]
```

それぞれの引数は表に示す意味があります。

| 引数        | 説明|
| --------- | ----------------------------------- |
| channel   | 出力するチャンネル番号0〜7のいずれかを指定|
| frequency | PWM信号の周波数を指定<br>$最小周波数=(CPU速度+1)/(2^{24})$Hz<br>最大速度はOPTION CPUSPEED/4 |
| dutyA     | 出力Aへの出力する信号のデューティサイクルを指定 |
| dutyB     | 出力Bへの出力する信号のデューティサイクルを指定  |
| phase     | 波形の位相の指定。波形を中央に配置するためのパラメータ<BR>短いデューティサイクルの波形が長いデューティサイクルの波形から等時間で開始および終了します |
| defer     | 1に設定すると、PWMチャンネルは出力開始状態になるが、出力は開始ない<BR>PWM SYNCコマンドを使用して出力を開始でき、望ましくない起動時のアーティファクトを回避できる＜BR>PWMコマンドはサーボ駆動も可能 |

- dutyAとdutyBのいずれか、または両方を指定する必要がある
- デューティサイクルは％で-100%〜100％の範囲で指定し、負数の場合は出力が反転する

## PWM出力の停止

PWM出力の停止は`PWM`コマンドを使う。チャンネル単位で出力が停止され、PWMのピン設定も無効化される。

```
PWM channel, OFF
```

# 参考サイトなど

- [PicoMite User Manual](https://geoffg.net/Downloads/picomite/PicoMite_User_Manual.pdf)