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は、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 kg | 2.2 kg |
| 5 cm | 2.2 kg | 1.1 kg |
| 10 cm | 1.1 kg | 550 g |
| 15 cm | 約730 g | 約365 g |
| 20 cm | 550 g | 275 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 A | 2.5 A | 5〜6 V、3 A以上 |
| サーボ2個 | 1〜1.8 A | 5 A | 5〜6 V、5 A |
| サーボ4個 | 2〜3.6 A | 10 A | 5〜6 V、6〜10 Aのスイッチング式ACアダプター |
| サーボ6個(ロボットアーム) | 3〜5.4 A | 15 A | 6 V、10 Aに加えて、サーボを順番に動かすコード |
| サーボ16個(PCA9685) | 8〜14 A | 40 A | 複数に分けた6 Vのライン、または20 A以上の電源 |
正しい電源の取り方:5〜6 Vの外部電源、共通GND、コンデンサ
- 電源を選ぶ:使うサーボの数に応じて、上の表の電流を供給できる5 Vまたは6 Vのスイッチング式ACアダプターを使います。持ち運ぶプロジェクトなら、単3ニッケル水素電池4本(4.8 V)か、6 Vに設定した降圧レギュレーター(UBEC)と2S LiPoの組み合わせが適しています。
- プラスはサーボにだけ:電源のプラスをMG996Rの赤い線につなぎます。Arduinoの5Vピンにはつながないでください。
- GNDをつなぐ:電源のマイナスを、サーボの茶色の線とArduinoのGNDピンの両方につなぎます。信号はGNDを基準に測る電圧なので、共通GNDがないとサーボはパルスを読み取れません。
- 信号をつなぐ:オレンジの線をArduino UnoのD9ピンにつなぎます(ESP32ではGPIO 18、PicoではGP15)。
- コンデンサを追加する:470〜1000 µF / 16 Vの電解コンデンサを、サーボの電源線の間にできるだけサーボの近くで入れます。帯の印がある足がマイナス側です。サーボが複数ある場合は、1個あたり約100 µFを目安にします。
- Arduinoは別に給電する:ボードはUSBかDCジャックから動かします。こうすると、サーボが原因の電圧降下がプロセッサーに届きません。
| 接続 | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| オレンジの線(信号) | D9 | GPIO 18 | GP15 |
| 赤い線(プラス) | 外部5〜6 V電源のプラス | 外部5〜6 V電源のプラス | 外部5〜6 V電源のプラス |
| 茶色の線(GND) | 電源のマイナス + ArduinoのGND | 電源のマイナス + ESP32のGND | 電源のマイナス + PicoのGND |
| コンデンサ(470〜1000 µF) | サーボのプラスとマイナスの間 | サーボのプラスとマイナスの間 | サーボのプラスとマイナスの間 |
| ポテンショメーター(ESP32の例) | — | 中央の端子をGPIO 34に、両端の端子を3V3とGNDに | — |

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度近くまで回ります。限界を超えて動かされたサーボは内部のストッパーに当たり、ストール電流を流し、うなって発熱します。そこで最初の作業は、下のスケッチで手元のサーボの安全なパルス範囲を見つけることです。
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}- スケッチを書き込み、シリアルモニタを115200ボーで開き、改行コードをNew Line(LFのみ)に設定します。
- 1500と入力すると、サーボが中央に移動します。このタイミングで、機構の中央位置を指すようにサーボホーンを取り付けます。
- 1000、800、700のような値で、50 µsずつ下限に近づけます。サーボが動かなくなったり、うなり始めたりしたら、最後の値から30〜50 µs戻し、その数をMIN_USとしてメモします。
- 上限も同じように、2000、2200、2300のような値でMAX_USを見つけます。この2つの数は次のスケッチで使います。
滑らかな動き:電流の急増とガクつきを抑えるコード
servo.write(160)のような1回の命令だけだと、サーボは全速力で目標まで動き、6 Vでは60度を0.14秒で回ります。その間モーターはストール電流に近い電流を流し、機構はガクッと動き、つかんでいる物が落ちることもあります。動きを小さなステップに分けると、電流のピークも機械的な衝撃も小さくなります。下のスケッチはサーボを15 msごとに1度ずつ進め(約67°/秒)、millis()を使っているので、同時にほかの処理もできます。
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%の余裕を持たせる |
ESP32でMG996Rを制御する
標準のArduino ServoライブラリはESP32では動作しません。ライブラリマネージャからESP32Servoライブラリをインストールしてください。使い方はほぼ同じで、setPeriodHertz(50)で周期を設定します。このライブラリは500〜2500 µsの範囲外の限界を受け付けません。ESP32の信号出力は3.3 Vですが、ほとんどのMG996Rは問題なく読み取ります。サーボが反応しない、または動きがおかしい場合は、信号線にレベル変換モジュールを入れてください。下の例では、GPIO 34につないだポテンショメーターでサーボを回します。ESP32のADCは12ビットなので読み取り値は0〜4095の範囲になり、ノイズも少しあります。そのためコードではフィルタと不感帯を使っています。
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度ずつ滑らかに動かします。
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 Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| GND | GND | GND | GND |
| VCC(チップの電源のみ) | 5V | 3V3 | 3V3 |
| SDA | A4 | GPIO 21 | GP4 |
| SCL | A5 | GPIO 22 | GP5 |
| V+端子(サーボの電源) | 外部5〜6 V | 外部5〜6 V | 外部5〜6 V |
| OE | 接続しない | 接続しない | 接続しない |
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を使うからです。
MG996R、SG90、MG90Sの比較
| 項目 | SG90 | MG90S | MG996R |
|---|---|---|---|
| ストールトルク | 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 g | 13.4 g | 55 g |
| サイズ | 22.2 × 11.8 × 31 mm | 22.8 × 12.2 × 28.5 mm | 40.7 × 19.7 × 42.9 mm |
| ギア | プラスチック | 金属 | 金属、デュアルベアリング |
| 動作電圧 | 4.8〜6 V | 4.8〜6 V | 4.8〜7.2 V |
| ストール電流 | 約0.6〜0.75 A | 約0.7〜1 A | 2.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クラスの大型サーボを検討してください。



ロボットアーム用のサーボの選び方
- 土台: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とそのまま交換できます。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
サーボモーターの使い方
小型サーボモーターのアームが、一方の端、中央、もう一方の端の3つの位置へ順番に回り、それぞれの位置で2秒間止まります。Arduinoが保持する角度をモーターに指示すると、モーターはその位置まで動いて止まります。ロボットアームや自動開閉するふたが動く仕組みを学べます。

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

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

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

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

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

障害物回避ロボット
自分で進む道を見つける、賢い車を作ってみませんか?障害物回避ロボットは、前面の超音波センサーで周囲を常に調べます。障害物を見つけると停止し、サーボモーターで左右を確認して、最も障害物の少ない方向を選んで進みます。自動運転の基礎を学ぶのにぴったりの入門プロジェクトです。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

