Maker Pi RP2040でサーボモータをMicroPythonで動かしてみました。
今回使用したサーボモータは マイクロサーボ9g SG - 90というタイプで、制御角が±90°動くものを使用しております。
なお、こちらはマルツ、秋月電子、Amazonなどあらゆる場所で取り扱いがある一般的なサーボモータのようです。
電子部品は秋月電子の解説が詳しいので、こちらのリンクを貼っておきます。
購入する際は、他の場所で購入する際は「サーボモータ SG - 90」で検索すれば表示されるかと思います。
秋月電子 マイクロサーボ9g SG - 90 のページ
サーボモータの解説に入る前に、Maker Pi RP2040のMicroPythonでのファームウェアをセットアップや開発環境の設定については下記をご覧ください。
【MicroPythonのファームウェアをセットアップ】
ファームウェアセットアップする際に、microUSB端子の横にある電源をONにしておきます。
設定方法は下記のURLに記載されています。
URL: https://www.raspberrypi.org/documentation/rp2040/getting-started/#getting-started-with-micropython
また、当ブログでは下記の記事に記載しています。
【開発環境の設定】
当ブログでは下記の記事に記載しています。
準備が整ったらUSBケーブルをコンピューターに接続します。
おそらく、BOOTSELボタンを押しながら起動するのは初期設定のときのみで、
普段は普通の接続で大丈夫そうです。
Thonnyを起動し、インタプリタとして「MicroPython(Raspberry Pi Pico)」を選択します。
これは、右下のボックスをクリックして行うことができます。
Maker Pi RP2040の準備ができたら、プログラムの準備をしていきます。
今回はプログラムの準備をする際にサーボモータの仕様を理解する必要があるので、こちらをまず解説していきます。
まず、プログラムでサーボモータの角度指示するためにデータシートを確認します。
マイクロサーボ9g SG - 90 のデータシート
(秋月電子の マイクロサーボ9g SG - 90のデータシートのリンクです。)
データシートによると、4.8Vで50Hz(20ms)の時に、角度0度で1.45ms(pulse)、角度90度で2.4ms(pulse)とあります。この後プログラムで指示するために比率も出しておくと下記となります。
角度(deg) | パルス幅(ms) | 20msに対する比率 |
-90 | 0.5 | 0.025 |
0 | 1.45 | 0.0725 |
90 | 2.4 | 0.12 |
準備ができたらプログラムを用意します。
Maker Pi RP2040はGitHubの下記のページにサーボモータのプログラムが用意されているので、こちらをベースにプログラムを修正していきます。
主に修正を行うのは周波数とデューティ比のところ(もしサーボモータをGP12以外につなぐときはPinの位置も)ですが、今回の場合は周波数は50Hzで変更の必要がないので、デューティ比のみ修正します。今回は-90-から90度まで動かすとして、デューティ比は下記の通り修正してみました。
MIN_DUTY = int (0.03*65536)
MAX_DUTY = int (0.12*65536)
※MIN_DUTY をMIN_DUTY = int (0.025*65536)で与えるとビビりが発生するため、少し大きな値に設定しました。
なお、今回サーボモータを動かすにあたり下記のページを参考にさせていただきました。
その1 デューティ比の考え方について
その2 サーボモータについて
動かしてみた様子です。
また、今回180度回転させているということで逆さ絵をやってみました。
また、細かい角度指示を与えたい場合の間の角度は均等割で下記の指示でよさそうです。
各角度に対するデューティ比を計算式で表すと下記の関係式となります。
deg_duty = ((2.4-0.5)*(角度+90)/180+0.5)/20*65536
この関係を使用して、-90~90度までサーボモータを動かすプログラムがこちらになります。
※-90度のときに少しビビりが発生します。
from machine import Pin, PWM
import time,sys
pwm = PWM(Pin(12))
pwm.freq(50)
a= -90
while True:
if a > 90:
sys.exit()
else:
DUTY_deg = int (((2.4-0.5)*(a+90)/180+0.5)/20*65536)
pwm.duty_u16(DUTY_deg)
time.sleep_ms(500)
a = a + 10
動かしてみたのがこちらになります。
Comments