部品 · 読了まで16分

ArduinoでMG996Rサーボ:トルク、電流、電源とコード

MG996Rサーボの使い方。11 kg·cmのトルクと2.5 Aのストール電流、5〜6 Vの外部電源、コンデンサ、500〜2500 µsの範囲、ジッター対策、PCA9685とSG90との違いを解説します。

MG996Rサーボは、メタルギアと6 Vで最大11 kg·cmのトルクを持つことから、Arduinoのプロジェクトで重い作業を任される定番のサーボです。55 gの本体で、ロボットアームの肩を持ち上げたり、重いふたを開けたり、パン・チルトのカメラ台を動かしたりできます。ただし、この力には代償があります。負荷がかかるとMG996Rは最大2.5 Aの電流を流します。そのためSG90のようにArduinoの5Vピンにそのまま挿して使うことはできず、5〜6 Vの外部電源、共通GND、サーボの近くに置いたコンデンサが必要です。これらのルールを守らないと、サーボが震え、Arduinoがリセットを繰り返し、パソコンがUSBポートを止めてしまうことさえあります。

このガイドでは、MG996Rのトルクと電流の数値を実際の数字で読み解く方法、適切な電源の選び方、Servoライブラリで500〜2500 µsの範囲を使って手元のサーボの限界を見つける方法、ジッターとリセットを防ぐ方法を学びます。続いて、ESP32とRaspberry Pi Picoのコード、2本の線で16個のサーボを動かすPCA9685モジュール、ロボットアーム用のサーボの選び方、SG90やMG90Sとの比較を紹介します。

メタルギアのMG996Rサーボモーター
MG996R:40.7 × 19.7 × 42.9 mmの本体、メタルギア、デュアルボールベアリング、25歯の出力軸を備えています。茶色の線がGND、赤がプラス、オレンジが信号です。

MG996Rサーボとは?仕組みは?

MG996Rは、TowerProの旧モデルMG995の改良版です。設計を見直した制御基板とギアにより、中央位置への戻りが安定し、ガタも小さくなっています。ケースの中には、小さなDCモーター、モーターの回転を落としてトルクを増やす金属製のギアボックス、出力軸の角度を測るポテンショメーター、そしてこれらをまとめて制御する基板が入っています。基板は20 msごと(50 Hz)に信号線に届くパルスの幅を読み取り、指示された角度とポテンショメーターが示す角度を比べ、差がなくなるまでモーターを回します。約1500 µsのパルスは中央位置を意味し、パルスが短いと軸は一方向に、長いと反対方向に回ります。データシートにある5 µsの不感帯は、それより小さな変化にはサーボが反応しないという意味です。サーボモーター全般の仕組みはサーボモーターとは?で解説しています。

項目値
動作電圧4.8〜7.2 V(実用上は5〜6 V)
ストールトルク9.4 kg·cm(4.8 V)、11 kg·cm(6 V)≈ 0.92〜1.08 N·m
速度(60°あたり)0.17秒(4.8 V)、0.14秒(6 V)
待機電流約10 mA(無負荷、軸が静止した状態)
動作時の電流500〜900 mA(6 V、動いている間)
ストール電流2.5 A(6 V)
不感帯5 µs
回転角1000〜2000 µsで約120°、500〜2500 µsで180°近く(個体差あり)
信号50 Hz(周期20 ms)、パルス幅で位置を指定
ギアとベアリングメタルギア、デュアルボールベアリング
出力軸25歯(25Tスプライン)
重さとサイズ55 g、40.7 × 19.7 × 42.9 mm
ケーブル約30 cm。茶色がGND、赤がプラス、オレンジが信号
動作温度0〜55 °C

トルクとは?kg·cmの値を正しく読む

トルクとは、軸から一定の距離にある負荷を回す力のことで、力 × 距離で表します。11 kg·cmは、軸から1 cmの位置で11 kg、10 cmの位置なら1.1 kgを支えられるという意味です。距離が2倍になると、支えられる負荷は半分になります。ニュートンメートルに換算するには0.098を掛けます。11 kg·cm ≈ 1.08 N·mです。ここで大事なのは、データシートの値がストールトルクだという点です。これは軸が止まり、電流がピークに達し、サーボが発熱する限界の値です。連続して使う場合は、この値の半分以下に抑えると、サーボが熱くならず、ジッターが減り、ギアも長持ちします。

アームの長さ(軸から負荷まで)ストールの限界(6 V)安全な連続負荷(50%)
2.5 cm(サーボホーンの先端)4.4 kg2.2 kg
5 cm2.2 kg1.1 kg
10 cm1.1 kg550 g
15 cm約730 g約365 g
20 cm550 g275 g

この表は先端の負荷だけを考えたものです。実際の機構では、アーム自体の重さ、その上に取り付けたほかのサーボ、グリッパーもすべてトルクに加わります。各部品の質量に軸からの距離を掛け、それを合計する必要があります。たとえば15 cmのアームの先に150 gのグリッパーと100 gの物体がある場合、この2つだけで0.25 × 15 = 3.75 kg·cmになり、アーム自体の重さを加えると合計5 kg·cmに達することもあります。これは6 VでのMG996Rのストールトルクの半分を少し下回るので、MG996Rは適切な選択です。部品ごとのトルク計算の例はArduinoのロボットアームのガイドにあります。

電流:なぜMG996RはArduinoの5Vピンで動かせないのか

MG996Rは無負荷で静止しているときは約10 mAしか流しませんが(負荷を保持すると、負荷に応じて増えます)、動いている間は0.5〜0.9 Aに上がり、軸に負荷がかかったときや、毎回の起動直後の数ミリ秒間は2.5 A近くに達します。Arduino UnoをUSBで動かしている場合、5Vピンから取り出せる電流の合計はボードの500 mAのヒューズで制限され、その一部はボード自体が使います。サーボが動き出した瞬間、5 Vのラインは数ミリ秒間はっきりと下がり、プロセッサーが不安定になってボードが再起動します。また、パソコンは過大な電流がしばらく流れたUSBポートを止めることもあります。

配線も問題の一部です。ブレッドボードで使う細いジャンパーワイヤーとブレッドボードの接点は、合わせると簡単に0.2 Ωになります。オームの法則で計算すると、2.5 Aのピークでは2.5 × 0.2 = 0.5 Vが配線だけで失われるので、5 Vの電源がサーボには4.5 Vとして届き、サーボの力が落ちてジッターが起きます。また、ブレッドボードの接点は約1 Aを想定して作られています。MG996Rの電源線はブレッドボードを通さず、ネジ端子(端子台)や、はんだ付けした電源分配用のバスに直接つなぎ、20〜22 AWGの線を使ってください。

サーボの数動作中最悪の場合(すべてストール)推奨電源
MG996R 1個0.5〜0.9 A2.5 A5〜6 V、3 A以上
サーボ2個1〜1.8 A5 A5〜6 V、5 A
サーボ4個2〜3.6 A10 A5〜6 V、6〜10 Aのスイッチング式ACアダプター
サーボ6個(ロボットアーム)3〜5.4 A15 A6 V、10 Aに加えて、サーボを順番に動かすコード
サーボ16個(PCA9685)8〜14 A40 A複数に分けた6 Vのライン、または20 A以上の電源

正しい電源の取り方:5〜6 Vの外部電源、共通GND、コンデンサ

  1. 電源を選ぶ:使うサーボの数に応じて、上の表の電流を供給できる5 Vまたは6 Vのスイッチング式ACアダプターを使います。持ち運ぶプロジェクトなら、単3ニッケル水素電池4本(4.8 V)か、6 Vに設定した降圧レギュレーター(UBEC)と2S LiPoの組み合わせが適しています。
  2. プラスはサーボにだけ:電源のプラスをMG996Rの赤い線につなぎます。Arduinoの5Vピンにはつながないでください。
  3. GNDをつなぐ:電源のマイナスを、サーボの茶色の線とArduinoのGNDピンの両方につなぎます。信号はGNDを基準に測る電圧なので、共通GNDがないとサーボはパルスを読み取れません。
  4. 信号をつなぐ:オレンジの線をArduino UnoのD9ピンにつなぎます(ESP32ではGPIO 18、PicoではGP15)。
  5. コンデンサを追加する:470〜1000 µF / 16 Vの電解コンデンサを、サーボの電源線の間にできるだけサーボの近くで入れます。帯の印がある足がマイナス側です。サーボが複数ある場合は、1個あたり約100 µFを目安にします。
  6. Arduinoは別に給電する:ボードはUSBかDCジャックから動かします。こうすると、サーボが原因の電圧降下がプロセッサーに届きません。
2S LiPo(満充電で8.4 V)をMG996Rに直接つながないでください。最大7.2 Vを超えるため、制御基板が焼損するおそれがあります。一方、9 V電池はそもそも必要な電流を供給できません。電解コンデンサを逆向きにつなぐと、発熱して破裂することがあります。耐圧はラインの電圧の2倍以上にします(6 Vなら16 V)。共通GNDが欠かせない理由はGNDと共通グラウンドで、コンデンサの選び方はコンデンサとは?で解説しています。
接続Arduino UnoESP32Raspberry Pi Pico
オレンジの線(信号)D9GPIO 18GP15
赤い線(プラス)外部5〜6 V電源のプラス外部5〜6 V電源のプラス外部5〜6 V電源のプラス
茶色の線(GND)電源のマイナス + ArduinoのGND電源のマイナス + ESP32のGND電源のマイナス + PicoのGND
コンデンサ(470〜1000 µF)サーボのプラスとマイナスの間サーボのプラスとマイナスの間サーボのプラスとマイナスの間
ポテンショメーター(ESP32の例)—中央の端子をGPIO 34に、両端の端子を3V3とGNDに—
電解コンデンサ
電解コンデンサは、電源が反応する前に、サーボが起動時に求める急な電流を自分にたまった電荷から供給します。本体の帯がマイナスの足の印です。MG996Rには470〜1000 µF / 16 Vから始めるのがよいでしょう。
12 VのACアダプターがあれば、LM2596モジュールで出力を6 Vに設定できます。ただしLM2596は最大3 Aまでで、ヒートシンクなしでは2 A前後で熱くなります。2.5 Aのストール電流だけでその限界に達するので、使えるのはMG996R 1個までです。サーボがもっと多い場合は、5 A以上の定格のコンバーターか、強力な5〜6 VのACアダプターを直接使ってください。電池で動かすプロジェクトでは、電池寿命計算ツールで動作時間を見積もれます。

Servoライブラリと500〜2500 µsの範囲

ArduinoのServoライブラリはIDEに最初から入っています。servo.attach(9)と書くと、ライブラリは544〜2400 µsの初期範囲を使い、write(0)とwrite(180)をこの両端に割り当てます。多くのMG996Rは、この範囲では180度に少し届きません。範囲を広げるにはservo.attach(9, 500, 2500)と書きます。この点が重要なのは、writeMicroseconds()もattachで指定した限界を超えられないからです。限界を設定せずにwriteMicroseconds(2500)と書くと、ライブラリは何も知らせずに2400に切り詰めます。またwrite()は、544未満の数を角度として、それより大きい数をマイクロ秒として扱います。

Arduino UnoのServoライブラリは最大12個のサーボに対応し、Timer1を使うため、サーボを接続している間は9番と10番ピンでanalogWriteが動作しません。また、MG996Rの機械的な限界は個体ごとに少しずつ違います。メーカーのデータシートでは標準の1000〜2000 µsのパルスで約120度の回転とされていますが、広い範囲を使うとほとんどのサーボが180度近くまで回ります。限界を超えて動かされたサーボは内部のストッパーに当たり、ストール電流を流し、うなって発熱します。そこで最初の作業は、下のスケッチで手元のサーボの安全なパルス範囲を見つけることです。

C++ (Arduino IDE)
1#include <Servo.h>
2
3const byte SERVO_PIN = 9;          // turuncu sinyal kablosu / orange signal wire
4Servo servo;
5int pulseUs = 1500;                // orta konum / center position
6
7void setup() {
8  Serial.begin(115200);
9  servo.writeMicroseconds(pulseUs);      // önce darbe, sonra attach / pulse first, then attach
10  servo.attach(SERVO_PIN, 500, 2500);    // aralığı genişlet / widen the range
11  Serial.println(F("500-2500 arasi bir deger yaz / type a value between 500 and 2500"));
12}
13
14void loop() {
15  if (Serial.available()) {
16    long value = Serial.parseInt();             // yazılan sayıyı oku / read the typed number
17    while (Serial.available()) Serial.read();   // satır sonunu temizle / clear the line ending
18    if (value >= 500 && value <= 2500) {
19      int step = (value > pulseUs) ? 10 : -10;  // 10 µs adımlarla yavaşça git / move slowly in 10 µs steps
20      while (abs(value - pulseUs) >= 10) {
21        pulseUs += step;
22        servo.writeMicroseconds(pulseUs);
23        delay(5);
24      }
25      pulseUs = value;
26      servo.writeMicroseconds(pulseUs);
27      Serial.print(F("Darbe / pulse: "));
28      Serial.print(pulseUs);
29      Serial.println(F(" us"));
30    }
31  }
32}
  1. スケッチを書き込み、シリアルモニタを115200ボーで開き、改行コードをNew Line(LFのみ)に設定します。
  2. 1500と入力すると、サーボが中央に移動します。このタイミングで、機構の中央位置を指すようにサーボホーンを取り付けます。
  3. 1000、800、700のような値で、50 µsずつ下限に近づけます。サーボが動かなくなったり、うなり始めたりしたら、最後の値から30〜50 µs戻し、その数をMIN_USとしてメモします。
  4. 上限も同じように、2000、2200、2300のような値でMAX_USを見つけます。この2つの数は次のスケッチで使います。

滑らかな動き:電流の急増とガクつきを抑えるコード

servo.write(160)のような1回の命令だけだと、サーボは全速力で目標まで動き、6 Vでは60度を0.14秒で回ります。その間モーターはストール電流に近い電流を流し、機構はガクッと動き、つかんでいる物が落ちることもあります。動きを小さなステップに分けると、電流のピークも機械的な衝撃も小さくなります。下のスケッチはサーボを15 msごとに1度ずつ進め(約67°/秒)、millis()を使っているので、同時にほかの処理もできます。

C++ (Arduino IDE)
1#include <Servo.h>
2
3const byte SERVO_PIN = 9;
4const int MIN_US = 550;            // kalibrasyonda bulduğun alt sınır / lower limit from calibration
5const int MAX_US = 2450;           // kalibrasyonda bulduğun üst sınır / upper limit from calibration
6const byte STEP_MS = 15;           // derece başına süre: 15 ms ≈ 67°/sn / time per degree: 15 ms ≈ 67°/s
7
8const int POSES[] = {20, 160, 90, 45, 135};    // sırayla gidilecek açılar / angles to visit in order
9const byte POSE_COUNT = sizeof(POSES) / sizeof(POSES[0]);
10
11Servo servo;
12int current = 90;                  // şu anki açı / current angle
13int target = 90;                   // hedef açı / target angle
14byte poseIndex = 0;
15unsigned long lastStep = 0;
16unsigned long arrivedAt = 0;
17
18int angleToUs(int angle) {
19  return map(angle, 0, 180, MIN_US, MAX_US);   // açıyı darbeye çevir / angle to pulse width
20}
21
22void setup() {
23  servo.writeMicroseconds(angleToUs(current)); // önce konum, sonra attach / position first, then attach
24  servo.attach(SERVO_PIN, MIN_US, MAX_US);
25  arrivedAt = millis();
26}
27
28void loop() {
29  unsigned long now = millis();
30
31  // Hedefe 1 derecelik adımlarla yaklaş / approach the target in 1-degree steps
32  if (current != target && now - lastStep >= STEP_MS) {
33    lastStep = now;
34    current += (target > current) ? 1 : -1;
35    servo.writeMicroseconds(angleToUs(current));
36    if (current == target) arrivedAt = now;
37  }
38
39  // Hedefte 1 sn bekle, sonra sıradaki poza geç / wait 1 s at the target, then take the next pose
40  if (current == target && now - arrivedAt >= 1000) {
41    target = POSES[poseIndex];
42    poseIndex = (poseIndex + 1) % POSE_COUNT;
43  }
44
45  // Burada başka işler de yapılabilir / other tasks can run here too
46}

angleToUs()関数は、キャリブレーションで見つけたMIN_USとMAX_USの間に角度を割り当てるので、0度と180度がサーボの実際の安全な端点になります。サーボは電源を切ると位置を覚えておらず、最初のパルスを受け取ると指示された角度まで全速力で動きます。attach()の前にwriteMicroseconds()を呼ぶと、ライブラリは初期値の1500 µsのパルスを送らず、指定した開始角度をすぐに送ります。電源を切る前に機構を同じ開始姿勢に戻しておけば、電源投入時の跳ねはほとんどなくなります。速度はSTEP_MSで設定します。30 msでゆっくり滑らかな動きに、5 msで速いもののガクつく動きになります。ポテンショメーターでサーボを動かしたい場合は、読み取った値を角度に変換してtarget変数に書き込むだけです。

ジッターとArduinoのリセット:原因と対策

症状考えられる原因対策
サーボが動くとArduinoがリセットされ、USB接続が切れるサーボをArduinoの5Vピンから給電していて、起動時の電流で電圧が下がっている5〜6 Vの外部電源、共通GND、470〜1000 µFのコンデンサ
止まっているときにサーボが震える、またはうなる電源が弱い、線が細い、またはストールトルクに近い負荷太い線とコンデンサを使い、アームを短くするか負荷を減らす
ポテンショメーターで操作するとピクピク動き続けるアナログの読み取り値に数カウント分のノイズがある平滑化フィルタと2度の不感帯を追加する
サーボが勝手に動く、またはまったく反応しない外部電源のGNDがArduinoにつながっていない電源のマイナスをArduinoのGNDピンにつなぐ
端でうなって発熱するパルスの範囲がサーボの機械的な限界を超えているキャリブレーションでMIN_USとMAX_USを狭める
NeoPixel、SoftwareSerial、IRのライブラリと一緒に使うとピクピク動くこれらのライブラリが一時的に割り込みを止めるため、パルスの長さがずれるサーボをPCA9685に移すか、ハードウェアPWMを持つボードを使う
ESP32が「Brownout detector was triggered」(ブラウンアウト検出)と表示して再起動するサーボとESP32が同じ弱い電源を共有しているサーボを別の電源から給電し、GNDをつなぐ
負荷がかかるとカチカチ鳴って滑るギアの歯が欠けているか、プラスチック製のサーボホーンがなめているギアセットを交換し、金属製の25Tサーボホーンと中央のネジを使う
トルクが定格よりかなり低い品質の低いコピー品、または電源電圧が低い6 Vを試し、信頼できる販売店から買い、50%の余裕を持たせる
サーボが負荷を保持する必要がなければ、目標に着いたところでservo.detach()で信号を止められます。サーボは静かになり、電流もほとんど流れません。ただし信号がなくなると保持トルクも失われるので、ロボットアームの肩のように負荷を支える関節ではdetachを使わないでください。リセットのすべての原因と診断用スケッチはArduinoがリセットを繰り返すときに、ESP32の場合はESP32のブラウンアウトエラーにまとめています。

ESP32でMG996Rを制御する

標準のArduino ServoライブラリはESP32では動作しません。ライブラリマネージャからESP32Servoライブラリをインストールしてください。使い方はほぼ同じで、setPeriodHertz(50)で周期を設定します。このライブラリは500〜2500 µsの範囲外の限界を受け付けません。ESP32の信号出力は3.3 Vですが、ほとんどのMG996Rは問題なく読み取ります。サーボが反応しない、または動きがおかしい場合は、信号線にレベル変換モジュールを入れてください。下の例では、GPIO 34につないだポテンショメーターでサーボを回します。ESP32のADCは12ビットなので読み取り値は0〜4095の範囲になり、ノイズも少しあります。そのためコードではフィルタと不感帯を使っています。

C++ (Arduino IDE)
1#include <ESP32Servo.h>
2
3const int SERVO_PIN = 18;          // servo sinyali / servo signal
4const int POT_PIN = 34;            // pot orta bacağı (ADC1) / pot wiper (ADC1)
5const int MIN_US = 500;            // ESP32Servo bu aralığın dışına çıkmaz / ESP32Servo stays within 500–2500
6const int MAX_US = 2500;
7
8Servo servo;
9float smooth = 0;                  // süzülmüş pot değeri / filtered pot value
10int lastAngle = -1;
11
12void setup() {
13  Serial.begin(115200);
14  ESP32PWM::allocateTimer(0);              // servo için zamanlayıcı ayır / reserve a timer for the servo
15  servo.setPeriodHertz(50);                // 50 Hz = 20 ms periyot / 20 ms period
16  servo.attach(SERVO_PIN, MIN_US, MAX_US);
17  smooth = analogRead(POT_PIN);
18}
19
20void loop() {
21  smooth += (analogRead(POT_PIN) - smooth) * 0.1;   // ADC gürültüsünü süz / filter ADC noise
22  int angle = map((int)smooth, 0, 4095, 0, 180);    // 12 bit ADC: 0–4095
23  if (abs(angle - lastAngle) >= 2) {                // ölü bant: titremeyi keser / deadband stops jitter
24    servo.write(angle);
25    lastAngle = angle;
26    Serial.println(angle);
27  }
28  delay(20);
29}

Raspberry Pi PicoでMG996Rを使う(MicroPython)

Raspberry Pi Picoでは追加のライブラリは要りません。PWMを50 Hzに設定し、duty_ns()でパルス幅をナノ秒で指定します。500 µsは500000 nsです。Picoの信号も3.3 Vです。サーボをPicoのVBUSピンやVSYSピンから給電しないでください。これらのピンの電流はパソコンのUSBポートから来ているので、MG996Rのピーク電流でPicoが再起動してしまいます。サーボは外部電源から給電し、GNDをつなぎます。下のコードは、3つの位置の間でサーボを1度ずつ滑らかに動かします。

MicroPython
1from machine import Pin, PWM
2import time
3
4MIN_NS = 500000                   # 500 µs = 0 derece / 0 degrees
5MAX_NS = 2500000                  # 2500 µs = 180 derece / 180 degrees
6
7servo = PWM(Pin(15))              # turuncu kablo GP15'e / orange wire to GP15
8servo.freq(50)                    # 50 Hz servo sinyali / 50 Hz servo signal
9
10def write_angle(angle):
11    angle = max(0, min(180, angle))                           # 0–180 ile sınırla / clamp to 0–180
12    servo.duty_ns(MIN_NS + (MAX_NS - MIN_NS) * angle // 180)  # açıyı darbeye çevir / angle to pulse
13
14def move_slow(start, end, ms_per_degree=15):
15    step = 1 if end > start else -1
16    for a in range(start, end + step, step):  # 1 derecelik adımlar / 1-degree steps
17        write_angle(a)
18        time.sleep_ms(ms_per_degree)
19
20write_angle(90)                   # ortadan başla / start at the center
21time.sleep(1)
22
23while True:
24    move_slow(90, 170)
25    time.sleep(1)
26    move_slow(170, 10)
27    time.sleep(1)
28    move_slow(10, 90)
29    time.sleep(1)

PCA9685で16個のサーボ:2本の線でたくさんのMG996Rを動かす

サーボの数が増えたときや、割り込みを止めるライブラリと一緒に使うときは、PCA9685モジュールが便利です。このボードは16チャンネル・12ビットのPWM生成器で、SDAとSCLの2本の線だけを使ってI2CでArduinoと通信します。自分のクロックでパルスを作るので、プロセッサーがほかの処理で忙しいときでも信号は安定しています。初期アドレスは0x40です。ボード上のA0〜A5のはんだジャンパーでアドレスを変えると、同じバスに62枚のボードをつなげるので、理論上は992個のサーボを動かせます。50 Hzでは20 msの周期が4096ステップに分けられ、1ステップは約4.9 µsです。500 µsは約102ステップ、2500 µsは約512ステップになります。

PCA9685のピンArduino UnoESP32Raspberry Pi Pico
GNDGNDGNDGND
VCC(チップの電源のみ)5V3V33V3
SDAA4GPIO 21GP4
SCLA5GPIO 22GP5
V+端子(サーボの電源)外部5〜6 V外部5〜6 V外部5〜6 V
OE接続しない接続しない接続しない
C++ (Arduino IDE)
1#include <Wire.h>
2#include <Adafruit_PWMServoDriver.h>
3
4Adafruit_PWMServoDriver pca = Adafruit_PWMServoDriver(0x40);   // varsayılan adres / default address
5
6const byte SERVO_COUNT = 16;
7const uint16_t MIN_US = 500;       // kalibrasyonla daralt / narrow it after calibration
8const uint16_t MAX_US = 2500;
9
10uint16_t angleToUs(float angle) {
11  return MIN_US + (uint16_t)(angle * (MAX_US - MIN_US) / 180.0);
12}
13
14void setup() {
15  pca.begin();
16  pca.setOscillatorFrequency(27000000);   // kartın gerçek saatine yakın / close to the real board clock
17  pca.setPWMFreq(50);                     // servolar için 50 Hz / 50 Hz for servos
18  delay(10);
19  for (byte ch = 0; ch < SERVO_COUNT; ch++) {
20    pca.writeMicroseconds(ch, angleToUs(90));   // hepsini ortala / center them all
21    delay(200);                                 // sırayla başlat: akım darbesini dağıt / one by one: spread the current surge
22  }
23}
24
25void loop() {
26  // Dalga: her servo komşusundan biraz geride / wave: each servo slightly behind its neighbour
27  float t = millis() / 1000.0;
28  for (byte ch = 0; ch < SERVO_COUNT; ch++) {
29    float angle = 90 + 40 * sin(t * 2.0 - ch * 0.4);   // 50–130° arası / between 50° and 130°
30    pca.writeMicroseconds(ch, angleToUs(angle));
31  }
32  delay(20);
33}

スケッチを動かすには、ライブラリマネージャからAdafruit PWM Servo Driverライブラリをインストールします。setOscillatorFrequency(27000000)の行は重要です。PCA9685の内部クロックは仕様上25 MHzですが、実際には約23〜27 MHzの間でばらつき、Adafruitのサンプルでは27 MHzを使っています。この設定がないと、writeMicroseconds()で指定したパルスが数パーセントずれることがあります。setupの中でサーボを200 ms間隔で1個ずつ起動すると、16個すべてが同時に起動電流を流すのを防げます。サーボごとに限界が違う場合は、MIN_USとMAX_USを16要素の配列にして、チャンネルごとにキャリブレーションしてください。このスケッチはESP32でもそのまま動きます。ESP32ではWireライブラリが初期設定でGPIO 21と22を使うからです。

PCA9685には2つの電源入力があります。VCCはチップだけに給電し、サーボはネジ端子のV+入力から給電されます。V+が空いていると、ボードはI2Cでは認識されてもサーボは動きません。V+には絶対にArduinoの5Vピンから給電しないでください。安いモジュールの細い基板パターンは数十アンペアを流すようには作られていません。MG996Rを4〜6個より多く使う場合は、サーボのプラスとマイナスの線を太い電源分配用のバスにつなぎ、ボードからは信号だけを取ってください。また、V+のラインにはサーボ1個あたり約100 µFの容量を追加します。

MG996R、SG90、MG90Sの比較

項目SG90MG90SMG996R
ストールトルク1.8 kg·cm(4.8 V)1.8 kg·cm(4.8 V)、2.2 kg·cm(6 V)9.4 kg·cm(4.8 V)、11 kg·cm(6 V)
速度(60°あたり)0.10秒(4.8 V)0.10秒(4.8 V)、0.08秒(6 V)0.17秒(4.8 V)、0.14秒(6 V)
重さ9 g13.4 g55 g
サイズ22.2 × 11.8 × 31 mm22.8 × 12.2 × 28.5 mm40.7 × 19.7 × 42.9 mm
ギアプラスチック金属金属、デュアルベアリング
動作電圧4.8〜6 V4.8〜6 V4.8〜7.2 V
ストール電流約0.6〜0.75 A約0.7〜1 A2.5 A(6 V)
Arduinoの5Vピンからサーボ1個、軽い負荷なら可サーボ1個、軽い負荷なら可不可、必ず外部電源
主な用途最初の実験、パン・チルト、グリッパー手首、グリッパー、小型ロボットロボットアームの肩、重いふた、ステアリング

決め手は負荷とアームの長さです。数グラムの部品を回すだけ、あるいは試してみるだけならSG90で十分です。同じ大きさで衝撃に強いメタルギアが欲しければMG90Sを選びます。必要なトルクが1 kg·cmを超える場合、たとえば10 cmのアームの先で100 gを運ぶなら、MG996Rに上げてください。MG996RのトルクはSG90の約5倍ですが、速度は遅く、重さは6倍、電流は3〜4倍になるので、電源と機械的な取り付けはそれに合わせて計画してください。11 kg·cmでも足りない場合は、DS3218のような20 kg·cmクラスの大型サーボを検討してください。

SG90
SG90
MG90S
MG90S
MG996R
MG996R

ロボットアーム用のサーボの選び方

  • 土台:MG996R。アーム全体の重さをサーボの軸にかけないでください。土台にベアリングを入れ、サーボは回すだけにします。
  • 肩:最も負担が大きい関節です。MG996Rを使い、アームが20 cmより長い場合は20 kg·cmクラスのサーボかカウンターウェイトを追加します。
  • ひじ:MG996R。重いサーボを肩の位置に移し、プッシュロッドでひじを動かすと、肩の負荷が減ります。
  • 手首と手首の回転:MG90Sで十分です。ここにMG996Rを使うと、肩が支える重さが増えるだけです。
  • グリッパー:SG90かMG90S。閉じる角度は指がちょうど物に触れる位置に設定します。握り続けようとするサーボはストール電流を流します。
  • 取り付け:MG996Rの25歯の軸には金属製のサーボホーンを付け、中央のネジで固定します。このトルクでは、プラスチック製のサーボホーンはすぐになめてしまいます。

MG996Rのプロジェクトアイデア

  • ロボットアーム:土台、肩、ひじにMG996R、手首とグリッパーにMG90Sを使う6軸のアームです。作り方はロボットアームのガイドを参照してください。
  • パン・チルトカメラ:2個のMG996RでESP32-CAMモジュールを水平方向と垂直方向に回します。
  • 太陽追尾装置:4個のLDRで光の方向を見つけ、MG996Rで小さなパネルを太陽に向けます。詳しくは太陽追尾装置の記事にあります。
  • スマートゴミ箱:手を近づけると重いふたが開くスマートゴミ箱です。
  • カード式ドアロック:RFID RC522で正しいカードを読み取ったら、MG996Rでかんぬきを引きます。
  • ジョイスティックで操作するクレーン:ジョイスティックで2軸に動く小さなクレーンやショベルカーです。
  • 連続回転の駆動:MG996Rの360度タイプを使った、遅いけれど力強い車輪です。違いは360度サーボの記事で解説しています。

正しく給電すれば、MG996Rは小さなサーボでは手に負えない作業も楽にこなす、丈夫で安価なモーターです。ルールを覚えておきましょう。5〜6 Vの外部電源、共通GND、サーボの近くのコンデンサ、キャリブレーションしたパルス範囲と滑らかな動き、そしてサーボが増えたらPCA9685です。BlueGraysアプリには、ポテンショメーターやジョイスティックでのサーボ制御、サーボを使ったESP32のRFIDドアロック、32個のサーボのダンスといったプロジェクトがあり、それぞれステップごとの回路図とすぐに使えるコードが付いています。

よくある質問

MG996Rはどのくらいの重さを持ち上げられますか?

MG996Rのトルクは6 Vで11 kg·cmです。これは軸から1 cmの位置で11 kg、10 cmの位置で1.1 kgという意味です。この値はサーボが止まるストールの限界なので、連続して使う場合はその半分で計画してください。つまり、10 cmのアームの先なら約500 gを余裕をもって保持できます。

MG996Rに必要な電圧は?12 Vは使えますか?

データシートによると動作範囲は4.8〜7.2 Vで、実際には5 Vか6 Vが使われ、6 Vのほうがトルクも速度も上がります。12 Vや、満充電で8.4 Vになる2S LiPoでは、サーボの制御基板が焼損します。もっと高い電圧の電源がある場合は、LM2596のような降圧コンバーターで6 Vに下げてください。

MG996Rの消費電流は?どんな電源が必要ですか?

無負荷で静止しているときは約10 mA、動いている間は0.5〜0.9 A、負荷がかかったときや起動時は最大2.5 Aです。サーボ1個なら3 A以上、4個なら6〜10 Aを供給できる5〜6 VのACアダプターを選んでください。電源のマイナスをArduinoのGNDピンにつなぐことも忘れないでください。

MG996Rは180度回りますか?360度タイプはありますか?

標準のMG996Rは角度を指定するサーボです。メーカーは標準のパルスで約120度としていますが、500〜2500 µsの範囲を使うとほとんどの個体が180度近くまで回ります。同じ名前で売られている360度タイプは角度で止まらず、信号に応じて速度と向きを変えながら回り続けます。購入するときは、商品説明に180°と360°のどちらが書かれているかを確認してください。

MG996Rが震えたり、Arduinoがリセットされたりするのはなぜですか?

原因はほぼ必ず電源です。サーボをArduinoの5Vピンから給電すると、ピーク電流で電圧が下がり、ボードが再起動します。5〜6 Vの外部電源、共通GND、サーボの近くに470〜1000 µFのコンデンサを使ってください。止まっているときの震えには、太い線を使い、ポテンショメーターの読み取り値を平滑化し、パルス範囲をサーボの機械的な限界内に収めてください。

MG996RとMG995の違いは?

どちらのサーボも同じ大きさで、配線も同じです。MG996RはMG995の改良版です。設計を見直した制御基板とギアにより、不感帯が狭く、中央位置への戻りが安定し、トルクも少し大きくなっています。新しいプロジェクトにはMG996Rを選んでください。古いMG995とそのまま交換できます。

全プロジェクトを見る
サーボモーターの使い方
#35初級
プレミアム

サーボモーターの使い方

小型サーボモーターのアームが、一方の端、中央、もう一方の端の3つの位置へ順番に回り、それぞれの位置で2秒間止まります。Arduinoが保持する角度をモーターに指示すると、モーターはその位置まで動いて止まります。ロボットアームや自動開閉するふたが動く仕組みを学べます。

4.7(48)
67
ポテンショメーターでサーボモーターを操作
#36初級
プレミアム

ポテンショメーターでサーボモーターを操作

ポテンショメーターのつまみを回すと、サーボモーターのアームもそれに合わせて回ります。つまみの一方の端が0度、もう一方の端が半回転に対応します。Arduinoがつまみの位置を常に読み取り、サーボモーターが動きにすぐ反応します。ロボットアームや回転式カメラ台などのプロジェクトへの第一歩です。

4.6(37)
52
ジョイスティックでサーボモーターを制御
#60中級
プレミアム

ジョイスティックでサーボモーターを制御

防犯カメラの向きを変えるように、ジョイスティックで2つのモーターを操作します。スティックを左右に倒すと下側のサーボモーターがゆっくり回り、上下に倒すと上側のサーボモーターが上下に傾きます。手を離すと、どちらもその位置で止まります。カメラやレーザーの台座など、2方向に動く装置の基礎を作ります。

4.7(42)
58
ESP32サーボモーター(ポテンショメーター制御)
#118中級
プレミアム

ESP32サーボモーター(ポテンショメーター制御)

このプロジェクトでは、ポテンショメーターでSG90サーボモーターを制御します。ポテンショメーターから読み取ったアナログ値を0~180度の範囲に変換し、サーボの角度を調整します。ESP32Servoライブラリは、ESP32の出力に対応した適切なGPIOでサーボ信号を生成します。このプロジェクトではGPIO 18を使います。ロボットアームやカメラ用ジンバル、自動ドアの機構に使われる基本的な制御方法です。

4.3(29)
42
ESP32のRFIDドアロック(RC522 + サーボモーター + OLED + ブザー + LED)
#137上級
プレミアム

ESP32のRFIDドアロック(RC522 + サーボモーター + OLED + ブザー + LED)

ESP32、RC522 RFIDモジュール、SG90サーボモーター、SSD1306 OLEDディスプレイ、アクティブブザー、LED2個を使ってスマートドアロックを作ります。カードを読み取ると、UIDをコード内に登録した許可済みカードの一覧と照合します。許可されたカードなら、サーボモーターを回して解錠し、緑色のLEDが点灯して短い音が2回鳴ります。5秒後に自動で施錠します。許可されていないカードでは赤色のLEDが点灯し、短い間隔で3回音を鳴らして警告し、読み取ったUIDをOLEDに表示します。実際のIoTセキュリティの仕組みを実践的に学べます。

4.8(9)
15
サーボの円形ダンス — 32個のサーボで動く模様
#102上級
プレミアム

サーボの円形ダンス — 32個のサーボで動く模様

Arduino Megaで、円形に並べた32個のサーボモーターを動かすビジュアルアニメーションのプロジェクトです。サーボは1つの配列で管理し、Megaの22–53番ピンに接続します。ランダムな角度でばらばらに振動する動き、全体が同時に動く同期スイープ、円周を滑らかに巡る波、左右に揺れる方位磁針の針という4種類の動きを見せます。回転する波の効果は、各サーボと動作中のサーボとの関係によって生まれます。

4.5(40)
62
障害物回避ロボット
#81上級
プレミアム

障害物回避ロボット

自分で進む道を見つける、賢い車を作ってみませんか?障害物回避ロボットは、前面の超音波センサーで周囲を常に調べます。障害物を見つけると停止し、サーボモーターで左右を確認して、最も障害物の少ない方向を選んで進みます。自動運転の基礎を学ぶのにぴったりの入門プロジェクトです。

5.0(38)
49