ボリュームでサーボモーターを制御

ボリュームを使ってサーボモーターを制御します。

ボリューム(B型10kΩ)を指でつまんで回してサーボモータを好きな角度に回せるようにします。

サーボモーター

 

■主な仕様
・PWMサイクル:20mS
・制御パルス:0.5ms~2.4ms
・制御角:±約90°(180°)
・配線:茶=GND、赤=電源[+]、橙=制御信号 [JRタイプ]
・トルク:1.8kgf・cm
・動作速度:0.1秒/60度
・動作電圧:4.8V(~5V)
・温度範囲:0℃~55℃
・外形寸法:22.2×11.8x31mm
・重量:9g
 サーボモーターは、指示を出した通りに、位置/速度/回転力(トルク)などを正確に実現するサーボ機構に使用されるモーターのことです。
サーボモータの角度制御は、PWM信号で行います。

ボリューム(B型10kΩ)

可変抵抗器(ボリューム抵抗)とは機械的な位置の変化をアナログ電気信号に変換する電子部品で英語ではPotentiometer(ポテンショメータ)です。日本では、昔からオーディオ機器のボリューム調整に使われていたことからボリュームとも呼んでいます。

配線図

 

実際の配線

 

MicroPythonプログラム

from machine import Pin, PWM

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

sensor_adc = machine.ADC(0)

def servo_value(degree):
    return int((degree * 9.5 / 180 + 2.5) * 65535 / 100)

while True:
    pwm.duty_u16(servo_value(sensor_adc.read_u16() * 180 / 65535))

解説

サーボモーター「SG90」の仕様
・PWMサイクル:20mS
freq関数を使って、ON/OFFを1秒間に何回変化させるか(周期)を設定します。
PWMサイクル:20mSで20ms周期のパルスは1000ms/20で50Hzになります。
pwm.freq(50)
・制御パルス:0.5ms~2.4ms
・制御角:±約90°(180°)
制御パルス0.5ms~2.4msで制御角は0°~180°なので、そのパルス幅の変化で角度が決まります。
・トルク:1.8kgf・cm
1cmの棒にとりつけた1.8kgのものを持ち上げられるということのようです。
val = adc.read_u16() # 生のアナログ値を 0-65535 の範囲で読込み
パルス幅の設定

パルスの矩形波が上にのびた状態「1(ON)」のときの時間の長さ(矩形波の幅)によってサーボモータの位置が決まります。
1(ON)のときの時間の長さで、どの角度にするかの指示します。
SG90の制御パルスは0.5ms~2.4msなので
角度を0°(-90°)にしたければ、ONのときのパルス幅を0.5ms
角度を90°(0°)にしたければ、ONのときのパルス幅を1.45ms
角度を180°(+90°)にしたければ、ONのときのパルス幅を2.4msに設定します。
その設定はduty_u16関数でDuty比で設定します。
Duty(デューティ)比はPWMの周期(20ms)とON時間の比率です。単位は%です。
0°はON時間が0.5msで0.5ms/20ms=0.025:デューティ比2.5%、
180°はON時間が2.4msで2.4ms/20ms=0.12:デューティ比12%
画像ではDuty=12%になっているので180°回転させた状態です。
def servo_value(degree):
return int((degree * 9.5 / 180 + 2.5) * 65535 / 100)
この式でdegree(角度)からPWMのデューティ比に変換してデューティ比からRaspberry Pi Picoが理解できる数値に変換しています。
(degree * 9.5 / 180 + 2.5)
角度からPWMのデューティ比に変換する計算式

2.5~12%は、12%-2.5%=9.5%の幅があります。
9.5%の幅が180度なので、角度を9.5倍して180で割って、それに2.5を足すことによってデューティ比が求まります。
0°*9.5%/180°+2.5%=2.5%
180°*9.5%/180°+2.5%=12%
* 65535 / 100
デューティ比からRaspberry Pi Picoが理解できる数値に変換する計算式の部分
PicoはDuty比を16ビット( 0~65536)で表します。そのためデューティ比0%は0を、デューティ比100%は65535になります。そのためDuty比を65535を100で割ってセットすることになります。
0°はデューティ比2.5%なので2.5*65535/100=1638.375ですがintがついているので1638になります。
180°はint(12*65535/100)=7864で7864です
pwm.duty_u16(servo_value(sensor_adc.read_u16() * 180 / 65535))
ボリュームで得た数値で角度を決めます。

sensor_adc.read_u16()はボリュームの生のアナログ値を 0-65535 の範囲で読込みます。
最大のアナログ値は65535 で180に最小は0で0になり指定の角度に動きます。

実行

ボリューム抵抗のつまみを回すとサーボモーターが0°〜180°まで回ります。
後ろの波形を確認すると角度が大きくなるにつれて矩形波の幅が狭くなってデューティ比が変化していきます。

自由研究

複数のサーボモーターをいろいろ動かせるようにしてみましょう。