Python Raspberry Pi Pico WOKWi プログラム 回路 電子工作 高専3年生

【Raspberry Pi Pico入門④】ADC(アナログ-デジタル変換)【アナログ入力】

前回はPWM制御を学びました。

今回はアナログ入力について学んでゆきます。

アナログ入力とは

アナログ信号とは、「連続的に変化する値」のことです。

例:

  • 電圧:0V〜3.3V の間をなめらかに変化
  • 光の明るさ:0〜100% まで細かく変化
  • 温度:22.3℃、22.4℃、22.5℃…と連続して変わる

デジタル信号との違い

種類説明値の例
デジタル信号「0か1」「ONかOFF」など、はっきりした2つだけ0V or 3.3V
アナログ信号中間の値も含めた連続的な変化0.0V〜3.3V

Raspberry Pi Pico W は「デジタルの世界」で動いているため、**電圧そのもの(アナログ値)**を直接理解することができません。

そこで必要になるのがADC(Analog to Digital Converter)です。

ADC(Analog to Digital Converter)とは?

ADCとは、アナログ信号(電圧)をデジタルの数値に変換する部品・機能です。

Pico W にはこの機能が標準で備わっています。

Raspberry Pi Pico W のADCの特徴

特徴内容
解像度16ビット(0〜65535)で出力される(実際は12ビット分を16ビットに拡張)
電圧範囲0V〜3.3V(それ以外の電圧は入力NG!)
使用可能なピンGPIO26(ADC0)、GPIO27(ADC1)、GPIO28(ADC2)

電圧と数値の関係

電圧ADC値(read_u16)
0.0V0
1.65V約32768(中間)
3.3V65535(最大)

つまり、0〜3.3V の電圧を、0〜65535 の数値に変換してくれます。

Pico W のADCは本来12ビット(= 0〜4095)ですが、MicroPythonでは処理を簡単にするため16ビット(0〜65535)に拡張して扱っています。

ビット数値の範囲解像度(1ステップ)
12ビット0〜4095約 0.8mV(= 3.3V/4096)
16ビット0〜65535約 0.05mV(= 3.3V/65536)※実際の精度は12bit

活用例

センサの種類測れるものADCに接続する出力例
可変抵抗つまみの角度0〜3.3V
光センサ明るさ0〜3.3V
温度センサ(NTC)温度抵抗の変化を電圧に変換
水位センサ水の高さ0〜3.3V

よくある注意点

問題原因対策
値が0か65535に固定される電圧が範囲外 / ピン未接続センサ回路を確認
値がバラつくノイズの影響time.sleep() で読み取りをゆっくりにする or 平均化処理
センサの仕様が合わない出力電圧が3.3Vを超えるなどレベル変換・抵抗分圧で対応

例題1

アナログ値を読み取って表示

以下のようなプログラムになります。

from machine import ADC, Pin
import time

adc = ADC(Pin(26))  # GPIO26(ADC0)を使用

while True:
    value = adc.read_u16()  # 0〜65535の範囲で読み取る
    print("アナログ値:", value)
    time.sleep(0.1)
関数説明
ADC(Pin(26))GPIO26ピンをADCとして使う
.read_u16()16ビット(0〜65535)でアナログ値を読み取る
0〜65535の値0V〜3.3Vに対応(0=0V、65535=3.3V)

例題2

可変抵抗でLEDの明るさを変える

from machine import ADC, PWM, Pin
import time

adc = ADC(Pin(26))         # 可変抵抗入力(GPIO26)
led = PWM(Pin(15))         # LED出力(GPIO15)
led.freq(1000)             # PWM周波数を設定

while True:
    value = adc.read_u16()     # 0〜65535のアナログ値を取得
    led.duty_u16(value)        # そのままPWMに渡して明るさを制御
    time.sleep(0.01)

課題9

アナログ値でLEDの明るさを3段階に分けて制御する回路を作成せよ。

可変抵抗を回すと、LEDの明るさを以下の3段階で切り替えるプログラムを作る:

アナログ値の範囲明るさ(デューティ比)
0〜20000弱(約10%)
20001〜40000中(約50%)
40001〜65535強(100%)
解答例はこちら
from machine import ADC, PWM, Pin
import time

adc = ADC(Pin(26))         # 可変抵抗(ADC0 = GPIO26)
led = PWM(Pin(15))         # LED出力(GPIO15)
led.freq(1000)

while True:
    value = adc.read_u16()  # 0〜65535 のアナログ値を取得
    
    if value < 20000:
        led.duty_u16(6553)      # 約10%の明るさ(65535の1/10)
    elif value < 40000:
        led.duty_u16(32768)     # 約50%の明るさ
    else:
        led.duty_u16(65535)     # 最大明るさ

    time.sleep(0.01)

課題10

ジョイスティックは基本的に2つのアナログ出力(X軸・Y軸)と、場合によってはスイッチ出力(押し込み)を持っています。

ジョイスティックを使って、その方向のLEDが点灯する回路を作成せよ。

ジョイスティックを上に倒すと LED(上) が点灯

下に倒すと LED(下)、左に倒すと LED(左)、右に倒すと LED(右)

倒していないとき(中心位置)ではすべてのLEDが消灯

回答例はこちら
from machine import ADC, Pin
import time

# ADCピン設定
x_adc = ADC(Pin(26))  # X軸(ADC0)
y_adc = ADC(Pin(27))  # Y軸(ADC1)

# LED出力設定
led_up = Pin(2, Pin.OUT)
led_down = Pin(3, Pin.OUT)
led_left = Pin(4, Pin.OUT)
led_right = Pin(5, Pin.OUT)

# 中央値としきい値
center = 32768
threshold = 10000

while True:
    x_val = x_adc.read_u16()
    y_val = y_adc.read_u16()

    # 全LED消灯
    led_up.value(0)
    led_down.value(0)
    led_left.value(0)
    led_right.value(0)

    # X軸:左右判定
    if x_val < center - threshold:
        led_right.value(1)
    elif x_val > center + threshold:
        led_left.value(1)

    # Y軸:上下判定
    if y_val < center - threshold:
        led_down.value(1)
    elif y_val > center + threshold:
        led_up.value(1)

    time.sleep(0.05)

次回はこちら

Follow me!

-Python, Raspberry Pi Pico, WOKWi, プログラム, 回路, 電子工作, 高専3年生
-, , , , ,

PAGE TOP