第8章 アナログ入力とPWM出力
この章の目的
Section titled “この章の目的”この章では、10kΩの可変抵抗を回した位置を 連続的な電圧としてPico Wへ入力します。
GP26のADCで電圧を数値へ変換し、 読み取った値に合わせてGP15のLEDの明るさを変化させます。
可変抵抗を回す ↓電圧が変化する ↓ADCで数値へ変換する ↓PWMのデューティ比を変える ↓LEDの明るさが変化するデジタル入力・出力の0と1だけでは表しにくい、
途中の大きさを扱う方法を確認します。
この章でできるようになること
Section titled “この章でできるようになること”- デジタル値とアナログ値の違いを説明できる
- 可変抵抗の固定端子と中央端子の役割を説明できる
- GP26をADC0として使用できる
read_u16()でアナログ入力を数値として取得できる- PWMの周波数とデューティ比を説明できる
duty_u16()でLEDの明るさを変化させられる- アナログ入力の値をPWM出力へ渡せる
- 入力、数値化、出力のつながりを説明できる
使用するもの
Section titled “使用するもの”| 分類 | 使用するもの | 数量 |
|---|---|---|
| 制御用ボード | ピンヘッダー実装済みのRaspberry Pi Pico WまたはPico WH | 1 |
| 配線 | ブレッドボード | 1 |
| 入力部品 | 10kΩリニア可変抵抗(B10K、3端子) | 1 |
| 出力回路 | 第5章で配線した赤色LEDと330Ω抵抗 | 1組 |
| 配線 | ジャンパーワイヤー | 3本程度を追加 |
| PC接続 | データ通信対応Micro USBケーブル | 1 |
第6章・第7章のタクトスイッチ回路は、 配線したままでも構いません。 この章のプログラムではGP14を使用しません。
安全上の注意
Section titled “安全上の注意”- 配線を追加・変更するときは、Pico WからUSBケーブルを外します
- 可変抵抗の電源には
3V3(OUT)を使用し、VBUSやVSYSへ接続しません - GP26へ3.3Vを超える電圧を入力しません
3V3(OUT)とAGNDをジャンパーワイヤーだけで直結しません- 第5章のLEDには、引き続き330Ω抵抗を直列に使用します
- 可変抵抗の端子配置は、部品の資料またはテスターで確認します
- 配線後は講師または接続表による確認を行ってからUSB接続します
8-1 デジタル値とアナログ値
Section titled “8-1 デジタル値とアナログ値”第5章から第7章では、GPIOの状態を0と1で扱いました。
このように、決められた段階で表す値をデジタル値と呼びます。
一方、電圧、温度、明るさなどは、 範囲の中で連続的に変化します。 このような量をアナログ値と呼びます。
| 種類 | 例 | Pico Wでの扱い |
|---|---|---|
| デジタル入力 | スイッチを離す/押す | 1または0 |
| アナログ入力 | 可変抵抗の位置 | 電圧をADCで数値化 |
| デジタル出力 | LEDを消灯/点灯 | LOWまたはHIGH |
| PWM出力 | LEDの明るさ | HIGHの時間割合を変更 |
Pico WのGPIOは、すべてがアナログ入力に対応しているわけではありません。
この章では、ADC0へ接続されたGP26を使用します。
8-2 ADCで電圧を数値化する
Section titled “8-2 ADCで電圧を数値化する”ADCは、Analog-to-Digital Converterの略で、 アナログ電圧をデジタル値へ変換する回路です。
RP2040のADCは12ビットで変換します。
MicroPythonのread_u16()は、その結果を
0から65535の範囲へ拡大して返します。
| GP26の入力電圧 | read_u16()の目安 |
|---|---|
| 約0V | 0付近 |
| 約1.65V | 32768付近 |
| 約3.3V | 65535付近 |
実際の値は、電源電圧、部品の誤差、配線、ノイズなどによって変動します。
端まで回しても、必ず0または65535になるとは限りません。
ADC値から入力電圧の目安を求める式は次のとおりです。
voltage = adc_value * 3.3 / 65535この計算結果は目安です。 正確な電圧測定が必要な場合は、基準電圧や測定誤差も考慮します。
8-3 可変抵抗の端子
Section titled “8-3 可変抵抗の端子”3端子の可変抵抗には、抵抗体の両端につながる2つの固定端子と、 回転位置に応じて抵抗体上を移動する中央端子があります。 中央端子を摺動端子またはワイパーと呼びます。
| 端子 | この章での接続 |
|---|---|
| 固定端子1 | 3V3(OUT) |
| 中央端子(ワイパー) | GP26 / ADC0 |
| 固定端子3 | AGND |
可変抵抗を回すと、中央端子の電圧が 約0Vから約3.3Vの範囲で変化します。
外側の2端子を入れ替えても回路は動作しますが、 明るくなる回転方向が反対になります。 中央端子をGP26へ接続することが重要です。
部品を上から見た端子順や、つまみを回した方向は 製品によって異なる場合があります。 外観だけで決めず、部品資料またはテスターで確認します。
8-4 可変抵抗とLEDを配線する
Section titled “8-4 可変抵抗とLEDを配線する”第5章のGP15 LED回路を残し、 可変抵抗を次のように追加します。
可変抵抗の接続
Section titled “可変抵抗の接続”| 接続元 | 接続先 | 物理ピン |
|---|---|---|
| 可変抵抗の固定端子1 | Pico Wの3V3(OUT) | 36 |
| 可変抵抗の中央端子 | Pico WのGP26 / ADC0 | 31 |
| 可変抵抗の固定端子3 | Pico WのAGND | 33 |
LED回路の接続
Section titled “LED回路の接続”| 接続元 | 接続先 | 物理ピン |
|---|---|---|
Pico WのGP15 | 330Ω抵抗 | 20 |
| 330Ω抵抗 | LEDのアノード | |
| LEDのカソード | Pico WのGND | 18 |
図8-1 GP26の可変抵抗入力とGP15のLED出力
次の順番で配線します。
- Pico WからUSBケーブルを外します
- 第5章のLED回路を接続表と照合します
- B10K可変抵抗の固定端子と中央端子を確認します
- 固定端子1を物理ピン36の
3V3(OUT)へ接続します - 中央端子を物理ピン31の
GP26 / ADC0へ接続します - 固定端子3を物理ピン33の
AGNDへ接続します GP26、AGND、3V3(OUT)を再確認します- 講師の確認後、USBケーブルを接続します
8-5 ADC値を読み取る
Section titled “8-5 ADC値を読み取る”次のプログラムをch08_01_adc_value.pyとしてPC側へ保存し、実行します。
from machine import ADC, Pinimport time
POT_PIN = 26
pot = ADC(Pin(POT_PIN))
while True: adc_value = pot.read_u16() print("ADC値:", adc_value) time.sleep(0.2)可変抵抗を端から端までゆっくり回し、 Shellに表示される値が変化すれば成功です。
ADC値: 320ADC値: 15872ADC値: 32640ADC値: 49120ADC値: 65184表示される値は実機ごとに異なります。 つまみを止めていても、下位の桁が少し変動することがあります。
ADCオブジェクトを作成する
Section titled “ADCオブジェクトを作成する”pot = ADC(Pin(POT_PIN))Pin(26)でGP26を指定し、
ADC()でアナログ入力として準備します。
ADC値を読み取る
Section titled “ADC値を読み取る”adc_value = pot.read_u16()read_u16()は、その時点の入力電圧を測定し、
0から65535の整数として返します。
このプログラムは0.2秒ごとにADC値を読み取るため、 第6章で学んだポーリングの例でもあります。
8-6 PWMでLEDの明るさを変える
Section titled “8-6 PWMでLEDの明るさを変える”GPIOはHIGHまたはLOWを出力するデジタル端子です。 途中の電圧を連続的に出力しているわけではありません。
PWMは、Pulse Width Modulationの略で、 HIGHとLOWを高速に切り替え、 1周期の中でHIGHにする時間の割合を変える方式です。
HIGHになっている時間の割合をデューティ比と呼びます。
duty_u16()の値 | デューティ比の目安 | LED |
|---|---|---|
0 | 0% | 消灯 |
16384 | 約25% | 暗め |
32768 | 約50% | 中間 |
49151 | 約75% | 明るめ |
65535 | 100% | 点灯 |
LEDは高速に点滅していますが、 人の目には平均的な明るさとして見えます。 デューティ比と、人が感じる明るさは完全な比例関係ではありません。
8-7 ADC値をPWM出力へ渡す
Section titled “8-7 ADC値をPWM出力へ渡す”次のプログラムをch08_02_adc_pwm.pyとしてPC側へ保存し、実行します。
from machine import ADC, Pin, PWMimport time
POT_PIN = 26LED_PIN = 15PWM_FREQ = 1000
pot = ADC(Pin(POT_PIN))led_pwm = PWM(Pin(LED_PIN), freq=PWM_FREQ, duty_u16=0)
try: while True: adc_value = pot.read_u16() led_pwm.duty_u16(adc_value) print("ADC値:", adc_value) time.sleep(0.1)finally: led_pwm.duty_u16(0) led_pwm.deinit()可変抵抗を回すと、ADC値に合わせて 外付けLEDの明るさが変化すれば成功です。
PWM出力を準備する
Section titled “PWM出力を準備する”led_pwm = PWM(Pin(LED_PIN), freq=PWM_FREQ, duty_u16=0)主な指定を確認します。
| 記述 | 意味 |
|---|---|
Pin(LED_PIN) | GP15を使用する |
freq=PWM_FREQ | PWMの周波数を1000Hzにする |
duty_u16=0 | デューティ比を0%から開始する |
ADC値をそのまま渡す
Section titled “ADC値をそのまま渡す”adc_value = pot.read_u16()led_pwm.duty_u16(adc_value)read_u16()とduty_u16()は、
どちらも0から65535を扱います。
このため、ADC値をPWMのデューティ比へそのまま渡せます。
停止時にPWMを終了する
Section titled “停止時にPWMを終了する”finally: led_pwm.duty_u16(0) led_pwm.deinit()tryの中でプログラムを実行し、
通常の停止などでtryを抜けるとfinallyの処理へ進みます。
LEDを消灯してからdeinit()でPWM出力を終了します。
停止後にLEDが最後の明るさのまま残ることを防ぎます。
8-8 入力から出力までを確認する
Section titled “8-8 入力から出力までを確認する”図8-2 アナログ入力を数値化し、PWM出力へ渡す流れ
この演習には、DXで使用するデータ活用の小さな流れがあります。
| 段階 | この章で行うこと |
|---|---|
| 現場の状態 | 可変抵抗の回転位置 |
| 取得 | GP26の電圧をADCで測定 |
| 数値化 | 0から65535のADC値 |
| 判断・変換 | ADC値をPWMデューティ比として使用 |
| 出力 | LEDの明るさを変化 |
| 確認 | ADC値とLEDの状態を観察 |
センサーを使用する章でも、 物理的な状態を数値へ変換する考え方は同じです。
変更してみる
Section titled “変更してみる”可変抵抗の回転方向とLEDの明るさの関係を反対にします。
次の行を探します。
led_pwm.duty_u16(adc_value)次のように変更します。
led_pwm.duty_u16(65535 - adc_value)ADC値が大きいほどPWM値が小さくなるため、 明るくなる回転方向が反対になります。
確認後は、元のled_pwm.duty_u16(adc_value)へ戻します。
- B10K可変抵抗の固定端子と中央端子を確認できる
-
3V3(OUT)、GP26 / ADC0、AGNDへ接続できる - 可変抵抗を回すとADC値が変化する
-
read_u16()が0から65535を返すことを説明できる - PWMの周波数とデューティ比を説明できる
- 可変抵抗を回すとLEDの明るさが変化する
- ADC値をPWM値へそのまま渡せる理由を説明できる
- PWM終了時にLEDが消灯することを確認できる
よくある問題と確認方法
Section titled “よくある問題と確認方法”| 状況 | 主な確認箇所 |
|---|---|
| ADC値がほとんど変わらない | 可変抵抗の中央端子、GP26、固定端子の3V3とAGND |
ADC値が常に0付近 | GP26または中央端子がAGNDへ直結していないか |
ADC値が常に65535付近 | GP26または中央端子が3V3へ直結していないか |
| ADC値が大きく変動する | 中央端子の接触、AGND、ジャンパーワイヤー |
| LEDの明るさが変わらない | GP15、330Ω抵抗、LEDの向き、duty_u16() |
| 内蔵LEDが反応する | Pin("LED")ではなくPin(15)を使用しているか |
| 回転方向が想定と反対 | 可変抵抗の外側2端子を入れ替えるか、値を65535 - adc_valueへ変換 |
| 停止後もLEDが点灯する | finally、duty_u16(0)、deinit()を確認し、必要ならソフトリセット |
配線を確認するときは、先にUSBケーブルを外します。 原因が分からないまま別の電源端子へ接続しません。
- アナログ値は、範囲の中で連続的に変化する量です
- ADCは、アナログ電圧をデジタル値へ変換します
- GP26はADC0として使用できます
read_u16()はADC値を0から65535で返します- PWMは、HIGHとLOWを高速に切り替えて出力の時間割合を変えます
duty_u16()はデューティ比を0から65535で指定します- ADC値をPWM値へ渡すと、可変抵抗でLEDの明るさを制御できます
- PWMは中間のアナログ電圧を直接出力しているわけではありません
- 入力を数値化し、処理して出力する流れは、センサーデータ活用の基本です
- MicroPython公式「RP2クイックリファレンス」(v1.26.0)
- MicroPython公式「machine.ADC」(v1.26.0)
- MicroPython公式「machine.PWM」(v1.26.0)
- Raspberry Pi公式「Picoマイクロコントローラーボード」
- Raspberry Pi公式「Raspberry Pi Pico W Datasheet」(PDF)
次の第9章では、温湿度センサーから環境データを取得し、 条件によって状態を判定します。