Raspberry Pi Pico の各 GPIO 端子には PWM 信号を出力することができます.今回はこの機能を使って、RGB の3色 LED とサーボモータの制御を試してみます.
Raspberry Pi Pico の PWM
RP2040 は下の図のような PWM ブロックを8つ持っており、それぞれのブロックは2つの信号出力を持っているため、合計で最大16個の PWM 出力が得られます. 各 PWM ブロック出力と GPIO 端子は下記の対応のように接続されているため、Raspberry Pi Pico ではすべての GPIO 端子で PWM 出力が利用可能です.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 の各出力端子の波形を表し、プログラム通り各出力のデューティが変化していることが分かります.サーボモータをドライブする
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】