Python × Pico 電子工作 | #05 センサーの値を読もう

前回の #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 値」の対応を見てみましょう。

可変抵抗(分圧回路)の配線と、電圧 0〜3.3V が ADC 値 0〜65535 に変換される対応図
可変抵抗の両端を 3V3 と GND に繋ぐと、中央端子(SIG)の電圧が 0V〜3.3V で変化する。Pico の ADC はこの電圧を 0〜65535 の整数に変換する。ADC が使えるのは GP26 / GP27 / GP28 の 3 本だけ。
つまみの位置SIG 電圧ADC 値イメージ
左端0V0暗い
少し回す0.8V約 16000うす暗い
中間1.65V約 32768中くらい
大きく回す2.5V約 49000明るい
右端3.3V65535最大

⚠️ ADC が使えるピンは 3 本だけ

アナログ値を読み取れるピンは GP26 / GP27 / GP28 の 3 本だけです(それぞれ ADC0 / ADC1 / ADC2 と呼ばれます)。他の GPIO ピンに可変抵抗を繋いでも電圧を読み取れません。配線前に必ず確認しましょう。

ステップ1:可変抵抗の値を読んでprintしよう

まずは可変抵抗の値が本当に 0〜65535 の範囲で変わるかを確かめましょう。下の配線図の通り、可変抵抗の 3 端子をそれぞれ 3V3 / GP26 / GND に繋ぎます。

可変抵抗を Pico の GP26・3V3・GND に配線した実体配線図
可変抵抗の両端 → 3V3 と GND、中央端子 → GP26(ADC0)。3 本配線するだけで分圧回路が完成します。(実体配線図は Fritzing の部品画像をもとに作図・CC BY-SA 3.0)
GP26 からアナログ値を読んで val に入れて print するブロック
ブロック構成:ずっと → アナログ入力 ADC0(GP26) を val に入れる → val を表示 → 0.5 秒待つ。
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

Pico の ADC は 実は 12bit(0〜4095) の精度しかありません。MicroPython はこれを 16bit(0〜65535)にスケールして返してくれるため、実際の値は 16 刻み(4096 段階)でしか変わりません。ですが「最大値が 65535 になる」と覚えておけば、PWM の duty_u16() とそのまま組み合わせられて便利です。

ステップ2:ツマミでLEDの明るさを変えよう

ADC で読んだ値を PWM のデューティ比に渡す と、ツマミの回転に連動してリアルタイムで明るさが変わる LED が作れます。前回 #04 の 「PWM出力(変数版)」ブロック(pico_pwm_write_val)が大活躍します。

可変抵抗 + GP15 LED の配線図
可変抵抗 → GP26(ADC0)、LED → GP15(330Ω 抵抗経由)。可変抵抗とLEDは独立した回路なので互いに干渉しません。

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

ADC 値を PWM デューティに変換して LED を制御するブロック
ブロック構成:ずっと → val = アナログ入力(GP26) → PWM出力 GP15 デューティ [val × 100 ÷ 65535] % → 0.02 秒待つ。
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 に縮めても問題ありません。

💡 動作確認のコツ

つまみをゆっくり回したときに LED がスムーズに明るくなる/暗くなるかをチェックしましょう。もし カクつく ようなら ADC の精度限界(12bit ≒ 4096 段階)が見えています。より滑らかにしたい場合は、何回か読んで平均を取る 移動平均フィルタ を入れるテクニックがあります(発展課題)。

ステップ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 という式で計算しよう。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

ツマミの値で点滅速度を変えるブロック
ブロック構成:ずっと → val = アナログ入力 → LED点灯 → 待つ(val+1000)/50000 → LED消灯 → 同じ待ち時間。
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Ω 抵抗付き)を配線します。

課題3-5-3 配線図:GP14 / GP15 にそれぞれ LED + 可変抵抗(GP26)
GP14 と GP15 にそれぞれ 330Ω + LED、可変抵抗は 3V3・GP26・GND の 3 端子配線。ツマミの位置で 2 個の LED の明るさが入れかわります。
▶ 模範解答と解説を見る

ブロックの組み合わせ例:

ツマミで 2 つの LED の明るさを対称に変えるブロック
ブロック構成:val = アナログ入力 → duty = val × 100 ÷ 65535 → PWM出力 GP15 デューティ [duty] → PWM出力 GP14 デューティ [100 - duty] → 0.02 秒。
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 の知識がそのまま音作りに活きてきます。

トップへ戻る