前回の #04 PWM ではプログラム側でデューティ比を変えて LED の明るさを調整しました。今回は 外側のツマミ(可変抵抗) を回して明るさを変えられるようにします。ここで初登場するのが ADC(Analog-to-Digital Converter, アナログ-デジタル変換器) です。
- 可変抵抗(ポテンショメーター)の 3 端子配線と分圧の仕組み
pico_analog_readでアナログ値を 0〜65535 として読み取る- ADC 値を計算ブロックで PWM のデューティ比に変換 して LED 制御
PycoBlocks(MicroPythonモード) を開き、左カテゴリ「Pico 電子工作 / 入力」のアナログ入力ブロックと、出力カテゴリのPWM 出力(変数版) を組み合わせて使います。前回 #04 で組んだ LED 回路に、可変抵抗を 1 個追加するだけで始められます。

可変抵抗とADC:ツマミの回転が「数値」に変わる仕組み
可変抵抗(potentiometer / ポット)は、3 端子の電子部品でつまみを回すと中央端子(SIG)の電圧が変わる仕組みです。両端を 3V3 と GND に繋ぐと、中央端子の電圧は 0V〜3.3V の間で連続的に変化します(これを分圧と呼びます)。
Pico の ADC(アナログ-デジタル変換器)は、この連続的な電圧を 0〜65535(16bit 符号なし整数) の数字に変換してくれる装置です。0V → 0、3.3V → 65535、1.65V(中間)→ 約 32768、というように対応します。下の図で、可変抵抗の配線と「電圧 → ADC 値」の対応を見てみましょう。

| つまみの位置 | SIG 電圧 | ADC 値 | イメージ |
|---|---|---|---|
| 左端 | 0V | 0 | 暗い |
| 少し回す | 0.8V | 約 16000 | うす暗い |
| 中間 | 1.65V | 約 32768 | 中くらい |
| 大きく回す | 2.5V | 約 49000 | 明るい |
| 右端 | 3.3V | 65535 | 最大 |
⚠️ ADC が使えるピンは 3 本だけ
ステップ1:可変抵抗の値を読んでprintしよう
まずは可変抵抗の値が本当に 0〜65535 の範囲で変わるかを確かめましょう。下の配線図の通り、可変抵抗の 3 端子をそれぞれ 3V3 / GP26 / GND に繋ぎます。


from machine import ADC
import utime
pot = ADC(26)
while True:
val = pot.read_u16()
print(val)
utime.sleep(0.5)
実行すると シリアル出力 欄(MicroPython モードでは画面下部)に0〜65535 の整数が次々と表示されます。つまみを左端まで回すと 0 に近い値、右端まで回すと 65535 に近い値が表示されることを確認しましょう。
📝 豆知識:ADC は実は 12bit
16 刻み(4096 段階)でしか変わりません。ですが「最大値が 65535 になる」と覚えておけば、PWM の duty_u16() とそのまま組み合わせられて便利です。ステップ2:ツマミでLEDの明るさを変えよう
ADC で読んだ値を PWM のデューティ比に渡す と、ツマミの回転に連動してリアルタイムで明るさが変わる LED が作れます。前回 #04 の 「PWM出力(変数版)」ブロック(pico_pwm_write_val)が大活躍します。

ここで一つ問題があります。ADC 値は 0〜65535 ですが、PWM のデューティ比は 0〜100(%)で指定するブロックを使っています。そこで 計算ブロック で val × 100 ÷ 65535 という変換を挟みます。

from machine import ADC, Pin, PWM
import utime
pot = ADC(26)
pwm = PWM(Pin(15))
while True:
val = pot.read_u16()
duty_pct = val * 100 / 65535
pwm.duty_u16(int(max(0, min(100, duty_pct)) * 65535 / 100))
utime.sleep(0.02)
utime.sleep(0.02) は「1 秒間に 50 回ループする」目安です。つまみを動かしてから LED に反映されるまでの遅延が 0.02 秒なら、人間にはほぼ即時に感じられます。もっと反応を速くしたい場合は 0.01 や 0.005 に縮めても問題ありません。
💡 動作確認のコツ
ステップ3(コラム):ADC の中身と他のセンサーへの応用
可変抵抗は 「分圧の練習台」 として最適ですが、Pico の ADC が読み取れるのは 電圧 なので、「電圧を出力するセンサー」全般を同じ仕組みで読めます。
- 光センサー(CdS):明るさで抵抗値が変わる素子。10kΩ などの固定抵抗と直列にして分圧すると、明るさ → 電圧 → ADC 値 に変換できる。
- 温度センサー:例 LM35(10mV/℃)。直接 ADC ピンに繋げる。
- 圧力センサー(FSR):押す強さで抵抗値が変わる。分圧で電圧化。
- 湿度センサー(土壌湿度モジュール):基板が電圧出力してくれるモジュール型なら ADC ピンに直結。
3 個のセンサーを同時に読みたいときは?ADC ピンは GP26 / GP27 / GP28 の 3 本あるので、3 種類のセンサーを同時にモニターできます(例:明るさ・温度・湿度を同時に取得)。それ以上必要な場合は 外付け ADC IC(MCP3008 など) を SPI 経由で繋ぐ手法もありますが、これは応用編です。
演習課題
課題3-5-1:ADC 値を電圧に変換してみよう
Pico の ADC は 0V → 0、3.3V → 65535 の対応で値を返します。つまり 「ADC 値 × 3.3 ÷ 65535」 で電圧(V)に戻せます。次の ADC 値を電圧に変換してみよう(小数第 2 位まで)。
- ADC 値 =
10000 - ADC 値 =
32768 - ADC 値 =
50000 - ADC 値 =
65535
▶ 模範解答と解説を見る
# 答え:
# 電圧 = ADC値 × 3.3 / 65535
#
# 10000 → 10000 × 3.3 / 65535 ≒ 0.50 V
# 32768 → 32768 × 3.3 / 65535 ≒ 1.65 V (ちょうど中間)
# 50000 → 50000 × 3.3 / 65535 ≒ 2.52 V
# 65535 → 65535 × 3.3 / 65535 = 3.30 V (最大)
#
# 逆変換(電圧 → ADC 値)も同じくらい大事:
# ADC値 = 電圧 × 65535 / 3.3
# 例: 1.0V → 1.0 × 65535 / 3.3 ≒ 19859
解説: 計算のコツ:3.3 ÷ 65535 ≒ 0.0000504(1 段あたり約 50µV の分解能)です。ADC 値の 変化 1 は約 50 マイクロボルトに相当します。ただし実際の精度は 12bit(4096 段階)なので、最小分解能は 3.3 ÷ 4096 ≒ 0.8 mV 程度です。発展:LM35 という温度センサーは 10mV/℃ で電圧を出力します。上の計算式を逆算すれば 「電圧 ÷ 0.01 = ℃」 として摂氏温度に変換できます。
課題3-5-2:ツマミで点滅速度を変えよう
可変抵抗の値を 「待ち時間」 に使えば、ツマミの位置で点滅の速さが変わる LED が作れます。配線はステップ2 と同じ(可変抵抗 + GP15 + LED)です。待ち時間は 0.02 秒〜1.3 秒 程度の範囲に収まるよう、(val + 1000) ÷ 50000 という式で計算しよう。
▶ 模範解答と解説を見る
ブロックの組み合わせ例:

from machine import ADC, Pin
import utime
pot = ADC(26)
led = Pin(15, Pin.OUT)
while True:
val = pot.read_u16()
wait = (val + 1000) / 50000 # 0.02 〜 1.33 秒
led.value(1)
utime.sleep(wait)
led.value(0)
utime.sleep(wait)
解説: ポイントは (val + 1000) ÷ 50000 という変換式です。val=0(ツマミ左端)→ 1000 / 50000 = 0.02 秒 で超高速点滅、val=65535(右端)→ 66535 / 50000 ≒ 1.33 秒 でゆっくり点滅。+ 1000 の意味は「ツマミを完全に左端にしても、最低 0.02 秒の待ち時間は確保する」(割り算でゼロに近づきすぎないようにする安全マージン)です。発展:50000 や 1000 の値を変えると、点滅速度の範囲を自由に調整できます。例:val / 30000 + 0.05 なら 0.05 〜 約 2.2 秒の範囲になります。
課題3-5-3:ツマミで2つのLEDの明るさを対称に変えよう
可変抵抗 + 2 つの LED で 「シーソー」演出 を作ろう。つまみを左に回すと GP15 が明るく GP14 が暗く、右に回すと GP15 が暗く GP14 が明るく なります。GP14 と GP15 にそれぞれ LED(330Ω 抵抗付き)を配線します。

▶ 模範解答と解説を見る
ブロックの組み合わせ例:

from machine import ADC, Pin, PWM
import utime
pot = ADC(26)
pwm14 = PWM(Pin(14))
pwm15 = PWM(Pin(15))
while True:
val = pot.read_u16()
duty = val * 100 / 65535 # 0〜100
pwm15.duty_u16(int(max(0, min(100, duty)) * 65535 / 100))
pwm14.duty_u16(int(max(0, min(100, 100 - duty)) * 65535 / 100))
utime.sleep(0.02)
解説: 鍵は 「duty を一度変数に入れて、2 つの LED で使い回す」 ことです。もし val × 100 ÷ 65535 を 2 回計算すると、わずかな時間差で val が変わって左右がぴたっと揃わなくなる可能性があります。同じ瞬間の値 から両方のデューティを計算するために変数 duty を使いましょう。発展:3 つの LED(赤・緑・青)にして RGB の色合成にすると、つまみ 1 個で 1 次元的に色を変える「カラーセレクター」が作れます。つまみを 3 個使えば、RGB を独立に操作するフル機能のカラーミキサーになります。
まとめ
- 可変抵抗(ポテンショメーター)は 3 端子配線で、中央端子の電圧が 0V〜3.3V で変化する分圧回路。
- ADC(Analog-to-Digital Converter)は電圧を 0〜65535 の整数に変換する装置。Pico では GP26 / GP27 / GP28 の 3 ピンが対応。
pico_analog_readでアナログ値を変数に入れ、pico_pwm_write_valに渡せば ツマミで LED 制御。- 変換式
val × 100 ÷ 65535で ADC 値(0〜65535)を デューティ比(0〜100%)に変換。 - 同じ仕組みで 光・温度・圧力センサー など「電圧を出すセンサー全般」を読み取れる。
次の記事は #06「ブザーで音を出そう」。PWM の周波数を音の高さに対応させて、ドレミの音階を鳴らしたり、簡単なメロディを演奏したりします。今回学んだ PWM の知識がそのまま音作りに活きてきます。