Raspberry Pi Pico W で、タクトスイッチとボリュームの値を読み取ってみた。

今回は Raspberry Pi Pico W を使って、タクトスイッチとボリュームの値を読み取ってみました。

Raspberry Pi Pico のセットアップなどがまだの場合は、下記の記事を参照してください。

https://qiita.com/IoriGunji/items/ebe6cefd3562639f7ca2

# 環境

今回の環境は下記のとおりです。

## 開発端末

- **OS**： Windows 11 Pro
- **CPU**： Intel Core i7-9750H
- **メモリ**： 64GB
- **GPU**： NVIDIA GeForce RTX 2070 Max-Q

## Python 環境

- **Python**： 3.11.0

## Raspberry Pi

- **Raspberry Pi**： Raspberry Pi Pico W
- **拡張ボード**： Pimoroni Pico Explorer Base（※任意）（[スイッチサイエンス](https://www.switch-science.com/products/7373)）

## 電子パーツ

- **スイッチ**： タクトスイッチ x1（※拡張ボードを使用する場合は不要）
- **ボリューム抵抗**： 小型ボリューム 10KΩ Bカーブ（[秋月電子 P-15813](https://akizukidenshi.com/catalog/g/gP-15813/)）

※ボリューム抵抗は、Bカーブのものを使うようにしてください。

:::note info
**ボリューム抵抗について**
ボリューム抵抗には、 `Aカーブ` , `Bカーブ` , `Cカーブ` の3つの種類があります。

![pico_vr_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/f436d154-5ae8-fcbe-5331-1a404b163d8d.png)

この内、 `Aカーブ` , `Cカーブ` はオーディオなどで用いられることが多いです。
今回は直線的に変化する `Bカーブ` のボリューム抵抗を用いました。
:::

# パーツの組み立て

今回、タクトスイッチは拡張ボードについていたので、これを利用します。
この拡張ボードのタクトスイッチの PIN アサインは次のとおりです。

- **SW A**： GPIO 12
- **SW B**： GPIO 13
- **SW X**： GPIO 14
- **SW Y**： GPIO 15

なお、タクトスイッチは1つだけで大丈夫です。

ボリューム抵抗は、 `3V3` , `ADC0` , `GND` に接続します。 
![pico_sw-vr_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/7660f35e-ddb3-21ef-41f6-61fa28500a73.jpeg)


ボリューム抵抗の接続方法や拡張ボードを使わない場合などの詳細は、下記の回路図を参考にしてください。
![pico_sw-vr_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/fa0d3b10-5fde-7f35-f765-dce374073908.png)

# Python コードの作成

Python コードを作成し、タクトスイッチとボリューム抵抗の値を読み取ってみます。

## MicroPico の初期設定

MicroPico の初期設定が終わってない場合は実施します。

VS Code の `表示(V)` → `コマンドパレット` をクリックします。
![pico_vscode_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/70e172a3-c69b-26ea-60de-59071d4e4a0f.png)

`>MicroPico: Configure project` と入力して `Enter キー` を押下します。
![pico_vscode_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/a2287e5a-db42-41c9-7d63-98c9d6fcc302.png)

## タクトスイッチの読み取り

今回の回路では Raspberry Pi Pico 内蔵のプルアップ抵抗を利用して、タクトスイッチの検出を行います。
スイッチ OFF で `1` となり、スイッチ ON で `0` になります。

```sw.py
from machine import Pin
import time

SW_PIN = 0

sw = Pin(SW_PIN, Pin.IN, Pin.PULL_UP)

while True:
    print(sw.value())
    time.sleep(0.5)
```

:::note info
**プルダウン抵抗・プルアップ抵抗について**
通常、タクトスイッチなどのスイッチを使用する場合、スイッチが OFF の際に GPIO がどこにも繋がっておらず、閉回路が形成されないということがあります。
この様に閉回路が形成されていない場合、ノイズが発生し、動作が不安定になることがあります。
本来であれば、スイッチにプルダウン抵抗やプルアップ抵抗を用いることで動作を安定させます。

しかし、 Raspberry Pi Pico は内部にプルダウン抵抗やプルアップ抵抗を内蔵しているため、コードで指定するだけで利用することができます。

**プルダウン抵抗を利用する場合**
```python
Pin(SW_PIN, Pin.IN, Pin.PULL_DOWN)
```

**プルアップ抵抗を利用する場合**
```python
Pin(SW_PIN, Pin.IN, Pin.PULL_UP)
```

※何も指定しない場合は、プルダウン抵抗もプルアップ抵抗も利用しない状態になります。
:::

## ボリューム抵抗の読み取り

次にボリューム抵抗の値を読み取ってみます。

```vr.py
from machine import ADC
import time

ADC_PIN = 0
VREF = 3.3

analog = ADC(ADC_PIN)

while True:
    value = analog.read_u16()
    volt = value / 65536 * VREF
    print('value : {} Volt : {:.2f}V'.format(value, volt))
    time.sleep(0.5)
```

:::note info
**A/D コンバータ（Analog Digital Converter）について**
アナログ回路の電圧を読み取るには、 A/D コンバータというデジタル値に変換する機能が必要になります。
Raspberry Pi Pico では `ADC0` , `ADC1` , `ADC2` の3つの入力端子が使えます。

また `ADC_VREF` に `0～3.3V` の間の任意の電圧を加えることで、アナログ入力で読み取る電圧の範囲（基準電圧）を設定することができます。

A/D コンバータは入力された電圧を `0V ～ 基準電圧` の範囲で等分して、デジタル値に割り当てます。
この際、割り当てられる値の範囲は A/D コンバータの分解能に左右されます。
Raspberry Pi Pico の A/D コンバータの分解能は `12bit` のため、 `0 ～ 4095` の範囲で割り当てられます。
ただし、 MicroPython はこの値を `16bit` に自動的に変換します。
そのため、 `0 ～ 65535` の範囲に変換されるため注意が必要です。
:::

# 参考文献

下記の書籍を参考にさせて頂きました。

- 福田 和宏 . 最新Pico W対応! ラズパイPico完全ガイド . 株式会社日経BP , 2023

<!-- EOF -->