発行済み 2026-04-02
このガイドでは、標準を制御する方法について説明します。サーボパルス幅変調 (PWM) 信号を使用するモーター。設定に必要な正確な PWM パラメータ (周期、パルス幅、デューティ サイクル) を学びます。サーボ0 度から 180 度までの任意の角度に調整できます。この命令は広く利用可能なマイクロコントローラー プラットフォームに基づいており、一般的な 50Hz アナログおよびデジタルで検証されています。サーボ趣味のロボット工学に使用されます。段階的なコード例とキャリブレーション方法に従うことで、ジッターやドリフトなしにサーボを確実に位置決めできます。
標準的なサーボ モーターは、次の固定特性を持つ PWM 信号を想定しています。
信号周期: 20 ms (ミリ秒)、これは次の周波数に相当します。50Hz.
パルス幅(ハイタイム): の間で異なります1.0ミリ秒そして2.0ミリ秒.
デューティサイクル= (パルス幅 / 20ms) × 100%。
注: 一部のサーボは拡張範囲として 0.5 ms ~ 2.5 ms を許容しますが、標準の 1.0 ~ 2.0 ms はほぼすべての一般的なサーボで機能します。
次のコード構造は、ハードウェア PWM を提供する任意のプラットフォーム (例: ハードウェア PWM を備えた Arduino、STM32、ESP32、Raspberry Pi) で動作します。特定のマイクロコントローラーに適応できるように、汎用の疑似コードを使用します。
PWM 対応ピンを選択してください。
PWM周波数を次のように設定します。50Hz(周期 = 20 ミリ秒)。
より細かく制御するには、解像度を少なくとも 8 ビット (0 ~ 255) または 16 ビットに設定します。
8 ビット PWM の場合 (0 = 0% デューティ、255 = 100% デューティ):
1.0 ms のデューティ サイクル = (1.0 / 20.0) × 255 = 12.75 → 四捨五入13
1.5 ms のデューティ サイクル = (1.5 / 20.0) × 255 = 19.125 → 四捨五入19
2.0 ms のデューティ サイクル = (2.0 / 20.0) × 255 = 25.5 → 四捨五入26
任意の角度 (0 ~ 180°) の一般式:
パルス幅ミリ秒 = 1.0 + (角度 / 180.0)(2.0 - 1.0) デューティ値 = (パルス幅_ms / 20.0)(2^解像度 - 1)
8 ビット解像度と 45° の例:
![]()
パルス幅ミリ秒 = 1.0 + (45/180)1.0 = 1.25ミリ秒
デューティ値 = (1.25/20)255 = 15.9375 → 整数16
// 疑似コード pwm_set_frequency(PWM_PIN, 50); // 50 Hz pwm_set_resolution(PWM_PIN, 8); // 8 ビット int 角度 = 90; // 目標角度 int due = map(angle, 0, 180, 13, 26); // 事前に計算された最小/最大デューティを使用 pwm_write(PWM_PIN,duty);
まったく同じサーボは 2 つとないため、常に実際のパルス幅制限を測定してください。
1. 1.0 ms パルスを書き込みます – サーボ位置を観察します。物理的な停止に達しない場合は、動きが停止するまでパルス幅を 0.05 ms ステップで増加させます (次のように記録します)。私のパルス).
2. 2.0 ms パルスを書き込みます – 同様に、完全な回転を与える最大パルス幅を見つけます (最大パルス).
3. 理論上の 1.0/2.0 ミリ秒の代わりに、コード内でこれらの測定値を使用します。
よくあるケース: 一般的な Tower Pro SG90 マイクロ サーボが必要です最小パルス = 0.9 ミリ秒そして最大パルス = 2.1 ミリ秒真の 0 ~ 180° の範囲。常にサーボモデルごとに校正を行ってください。
// PWM を使用したサーボ制御 - 外部ライブラリは必要ありません // ハードウェア PWM を備えたあらゆるボードで動作します (Uno、Nano、Mega、ESP32 など) const int servoPin = 9; // PWM ピン const int freq = 50; // 50 Hz const int 解像度 = 8; // 8 ビット (0-255) // 事前に校正されたパルス制限 (マイクロ秒単位) const int minPulseUs = 1000; // 1.0 ミリ秒 = 1000 マイクロ秒 const int maxPulseUs = 2000; // 2.0 ms = 2000 μs void setup() { // PWM を設定します。ledcSetup(0, freq,solution); // チャンネル 0 ledcAttachPin(servoPin, 0); } void setServoAngle(int angle) { // 角度を 0 ~ 180 に制限します angle = constrain(angle, 0, 180); // 角度をパルス幅 (マイクロ秒) に変換 intpulseUs = minPulseUs + (angle(maxPulseUs - minPulseUs)) / 180; // パルス幅をデューティ サイクル (0 ~ 255) に変換 int due = (pulseUs255) / 20000; // 20000 µs = 20 ms 周期 ledcWrite(0,duty); void ループ() { setServoAngle(0); // 0°に移動する遅延(1000); setServoAngle(90); // 90°の遅延(1000)に移動します。 setServoAngle(180); // 180°の遅延(1000)に移動します。 }
1. 常に各サーボを個別に校正してください– 同じモデルの 2 つのサーボであっても、±0.1 ms の変動が生じる可能性があります。 0.5 ms から 2.5 ms までスイープする簡単なテスト スケッチを作成し、0° と 180° の正確なパルス幅をメモします。
2. 別の電源を使用する– マイクロコントローラーの 5V ピンから直接サーボに電力を供給しないでください (電流スパイクによりボードがリセットされる可能性があります)。 5V/2A の安定化電源または 4 本の NiMH バッテリー (4.8V) で確実に動作します。
3. 100 ~ 470 µF の電解コンデンサを追加しますサーボに近いサーボの電源端子間に接続します。モーターの急な始動による電圧降下を吸収します。
4. ソフトウェアの遅延を回避するサーボが動いている間。プログラムが他のタスクを処理できるように、ノンブロッキング タイミング (millis() ベースのステート マシンなど) を使用します。
5. 高精度アプリケーション用 (例: ロボットアーム)、16 ビット PWM タイマーと校正されたポイント間の線形補間を使用します。また、ループを閉じるために 10 ビットのアナログ フィードバック ポテンショメータを追加することも検討してください。
重要なポイント: 周波数を 50 Hz に固定し、角度を 1.0 ~ 2.0 ms のパルス幅にマッピングすれば、PWM によるサーボの制御は簡単です。ただし、現実世界の信頼性は、適切な校正、適切な電力、理論値ではなく測定された限界値の使用から得られます。セクション 2.4 で説明されているキャリブレーション方法を統合するすべての新しいサーボに適用すると、プロジェクトは常にスムーズで正確な動作を実現します。
更新時間:2026-04-02