Raspberry Pi Pico を使ってみた [3] – Micro Python で PWM 出力


Raspberry Pi Pico の各 GPIO 端子には PWM 信号を出力することができます.今回はこの機能を使って、RGB の3色 LED とサーボモータの制御を試してみます.
Raspberry Pi Pico の PWM
RP2040 は下の図のような PWM ブロックを8つ持っており、それぞれのブロックは2つの信号出力を持っているため、合計で最大16個の PWM 出力が得られます.
Raspberry Pi Pico の PWM
各 PWM ブロック出力と GPIO 端子は下記の対応のように接続されているため、Raspberry Pi Pico ではすべての GPIO 端子で PWM 出力が利用可能です.
PWM 出力と GPIO 端子のマッピング

3色 RGB LED を PWM 信号でドライブする

ハードウェア接続
下に Raspberry Pi Pico の I/O 端子と LED、タクトスイッチの配線を示します.今回使用した RGB 3色 LED は、 秋月電子で入手した LATBT66B で、アノードコモンの LED になりますので、RGB 各 LED カソード端子を GPIO 端子に接続します.
回路
実体接続
ソフトウェア(Micro Python コード)
これまでと同様、Micro Python を使用します. MicroPython ライブラリのドキュメントを参照し、パルス幅変調制御に使う PWM クラスの使用例を確認しながらコーディングしていきます. 主に下記のような機能を使用して PWM のモード設定や出力の駆動ができます.
# 指定のピン(GP0)の PWM オブジェクトを作成
pwm_r = PWM(Pin(0))

# PWM 周波数を設定
pwm_r.freq(100)

# PWM デューティ比を duty_u16 / 65535 の比率で設定
pwm_r.duty_u16(32768)

各 LED の制御用の GP0 / GP1 / GP2 を PWM 設定、デューティ比を可変して表示色を変化させていきます.
from machine import PWM, Pin
import time

pwm_r = PWM(Pin(0))
pwm_g = PWM(Pin(1))
pwm_b = PWM(Pin(2))
pwm_r.freq(100)
pwm_g.freq(100)
pwm_b.freq(100)

#led_r = 0xFFFF
#led_g = 0x0000
#led_b = 0x0000

def firefly( r, g, b ) :
    led_r = 0xFFFF
    led_g = 0x0000
    led_b = 0x0000
    
    for i in range(65535) :
        led_r = led_r + r
        led_g = led_g + g
        led_b = led_b + b
        pwm_r.duty_u16(led_r)
        pwm_g.duty_u16(led_g)
        pwm_b.duty_u16(led_b)

while True:
    firefly( 0, 1, 0 )
    firefly( -1, 0,  0 )
    firefly( 0,  0,  1 )
    firefly( 0, -1,  0 )
    firefly( 1,  0,  0 )
    firefly( 0,  0, -1 )

実行結果
実行結果の波形を確認してみました.D0~D3 が LED の各出力端子の波形を表し、プログラム通り各出力のデューティが変化していることが分かります.
PWM 波形

サーボモータをドライブする

Raspberry Pi Pico で PWM の使用方法がわかりましたので、ついでにサーボモータを接続して動かしてみました. 使用したサーボモータは、 秋月電子で入手した マイクロサーボ SG-90 です.
ハードウェア接続
実体接続
ソフトウェア(Micro Python コード)
上記と同様、PWM クラスを使って制御します. サーボの制御方法については こちらのサイトで詳細に紹介されていましたので、デューティの設定値等はこちらを使わせていただきました.
from machine import PWM, Pin
import time

pwm1 = PWM(Pin(0))
pwm1.freq(50)
i = 0;

servo1 = PWM(Pin(0))
servo1.freq(50)

max_duty = 65025
dig_0 = 0.0725    #0°
dig_90 = 0.12     #90°
dig_m90 = 0.025   #-90°

while True :
    servo1.duty_u16(int(max_duty*dig_0))
    time.sleep_ms(1000)
    servo1.duty_u16(int(max_duty*dig_90))
    time.sleep_ms(1000)
    servo1.duty_u16(int(max_duty*dig_0))
    time.sleep_ms(1000)
    servo1.duty_u16(int(max_duty*dig_m90))
    time.sleep_ms(1000)

参考

MicroPython ライブラリの PWM クラスドキュメント
【Raspberry Pi Pico】サーボモーターをPWMで動かす【MicroPython】

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です