はじめに:「サーボを動かす」その先へ

「サーボモータを動かす」のは電子工作の基本ですが、実はその内部で何が起きているかを知ることで、制御の精度は格段に上がります

今回は、ホビー用サーボの定番 SG90 を例に、オシロスコープでPWM信号を可視化しながら、その仕組みを深掘りします。単にライブラリを使って動かすだけでなく、「なぜこの信号でこう動くのか」を理解することで、より高度な制御への扉が開きます。

📝 この記事で学べること:

  • ホビー用サーボモータの内部構造とフィードバック制御の仕組み
  • PWM信号とサーボ制御の関係を視覚的に理解
  • オシロスコープを使った信号の可視化と解析方法
  • Arduino UNO R4とServo.hライブラリによる正確な角度制御
  • 個体差への対応と安定動作のためのハードウェア設計

💡 Arduinoが初めての方へ
Arduino IDEのインストールや基本的な使い方については、こちらの記事をご覧ください:
👉 【Arduino入門】開発環境の準備とLED点滅でHello World!

Arduino UNO R4 Minima

Arduino UNO R4 Minima

Arduino UNO R4 Minima starter kit

Arduino UNO R4 Minima starter kit


🎥 実際の動作をご覧ください

まずは、今回の実験の様子をご覧ください。画面左にサーボモータ、右上にシリアルモニタで送信した角度指令値、右下にオシロスコープでリアルタイム観測したPWM信号が表示されています。

シリアルモニタから角度値を送信すると、画面右下の波形の「山の幅(パルス幅)」が変化し、それに応じてサーボモータが指定の角度へ移動するのが確認できます。


🔧 必要な部品リスト

必須部品

部品名 数量 用途 参考価格
Arduino UNO R4 Minima/WiFi 1個 メイン制御ボード 約3,000〜4,000円
SG90 サーボモータ 1個 角度制御用アクチュエータ 約300〜500円
ジャンパー線(メス-オス/オス-オス) 3本 サーボとArduinoの接続 -
外部電源(5V) 1個 サーボモータ用電源 約1,000円〜

測定・固定用機材(推奨)

部品名 数量 用途 参考価格
オシロスコープ 1台 PWM信号の可視化 約5,000円〜
プロクソンバイス 1個 サーボモータの固定 約2,000円
ブレッドボード 1個 配線の整理 約300円

推奨製品のご紹介

これから始める方におすすめの製品をご紹介します。Arduino本体とサーボモータがあれば、すぐに実験を始められます。

Arduino UNO R4 Minima

Arduino UNO R4 Minima

Amazonで見る
SG90 9gマイクロサーボモーター

SG90 9gマイクロサーボモーター

Amazonで見る
Arduino UNO R4 スターターキット

Arduino UNO R4 スターターキット

Amazonで見る

💡 スターターキットがおすすめ
初めての方は、Arduino本体に加えて、ブレッドボード、ジャンパー線、抵抗などの基本部品がセットになったスターターキットが経済的です。

⚠️ 重要な注意点:電源分離の必要性
サーボモータは動作時に大きな電流(最大500mA〜1A)を消費します。Arduino の 5V ピンから直接電源を取ると、電圧降下によって Arduino 自体がリセットされる可能性があります。必ず外部電源を使用し、GND(マイナス側)のみを Arduino と共通接続してください


🤖 ホビー用サーボの中身はどうなっている?

ブラックボックスになりがちなサーボモータですが、その中には小さな「ロボットシステム」が凝縮されています。

サーボモータの内部構造

SG90サーボモータの内部構造(分解図)

SG90サーボモータの内部構造(分解図)

1. 小型DCモータ

動力源です。非常に高速で回転しますが、そのままでは力(トルク)が弱く、角度制御もできません。

2. 減速ギア

モータの高速回転をゆっくりな回転に変換し、代わりに強力な**トルク(回転力)**を生み出します。SG90では約1:200の減速比を持ち、数千回転/分の回転を数十回転/分まで減速します。

3. ポテンショメータ(可変抵抗)

出力軸の角度を検知するセンサーです。出力軸に機械的に連結されており、角度に応じて抵抗値(=電圧)が変化します。これが「現在角度」の情報源となります。

4. 制御基板(ドライバIC)

ここが心臓部です。Arduino からの「指示(PWM信号)」とポテンショメータからの「現在の角度」を常に比較し、一致するまでモータを回し続けます

フィードバック制御の仕組み

これが フィードバック制御(閉ループ制御) と呼ばれるメカニズムです。

┌──────────────────────────────────────┐
│  Arduino からの指令(目標角度)      │
│          ↓                           │
│  制御基板がPWM信号を解釈             │
│          ↓                           │
│  モータを回転させる                  │
│          ↓                           │
│  ポテンショメータが現在角度を測定    │
│          ↓                           │
│  目標角度と比較 → 一致?             │
│    NO → さらに回転(ループ)         │
│    YES → 停止                        │
└──────────────────────────────────────┘

💡 重要なポイント
Arduino はモータを直接回しているのではなく、中の基板に対して**「何度の位置にいてください」と命令を送っているだけ**なのです。実際の位置制御は、サーボ内部の制御回路が自律的に行っています。


📡 制御の鍵「PWM信号」をオシロスコープで見る

サーボへの命令は、PWM(Pulse Width Modulation:パルス幅変調) という方式で行われます。

PWM信号の基本仕様

サーボが求める信号には、決まったルールがあります。

周期(Period)

20ms(50Hz)。20ミリ秒に1回、信号が立ち上がります。これは1秒間に50回パルスを送ることを意味します。

パルス幅(Pulse Width)

信号が「ON(HIGH)」になっている時間。この長さで角度が決まります

サーボ制御用PWM信号の周期とパルス幅

サーボ制御用PWM信号の周期とパルス幅

一般的な仕様値(理論値)

標準的なサーボモータのPWM信号仕様は以下の通りです:

パルス幅 角度
1.0 ms 0度
1.5 ms 90度(中立位置)
2.0 ms 180度

しかし、実際のSG90のような安価なサーボは、この仕様に個体差があります

オシロスコープでの実測結果

今回の実験で確認した、実際のSG90の動作範囲は以下の通りでした:

オシロスコープで観測したSG90のPWM信号(実測値)

オシロスコープで観測したSG90のPWM信号(実測値)

パルス幅 角度 備考
0.5 ms (500μs) 0度付近 実際に動作する最小値
1.45 ms (1450μs) 90度(中立) 個体により±0.05ms程度のズレあり
2.4 ms (2400μs) 180度付近 実際に動作する最大値

⚠️ 個体差への対応が重要
SG90のような安価なサーボは、このパルス幅の定義に個体差があるため、実機で波形を見ながら「どこまで回せるか」を確認するのが「思い通り」に動かす近道です。

なぜオシロスコープが必要なのか?

オシロスコープを使うことで、以下の情報が視覚的に確認できます:

  1. パルス幅の正確な測定:理論値と実測値の違いを確認
  2. 信号の周期確認:正しく50Hzで送信されているか
  3. ノイズの検出:電源ノイズなどの外乱を発見
  4. 個体差の把握:そのサーボの実際の動作範囲を特定

💻 Arduinoでの実践コード解説

Arduino標準の Servo.h ライブラリを使えば、複雑なタイマー処理を意識せずに制御できます。

基本的な制御プログラム

#include <Servo.h>

const int SERVO_PIN = 9;  // サーボ信号線を接続するピン
Servo myServo;

void setup() {
  Serial.begin(115200);
  
  // 個体差に合わせてパルス幅の最小・最大を指定するのがコツ!
  // attach(pin, min_pulse_width_us, max_pulse_width_us)
  myServo.attach(SERVO_PIN, 500, 2400); 
  
  Serial.println("=== Arduino Servo Control ===");
  Serial.println("Enter angle (0-180):");
}

void loop() {
  if (Serial.available() > 0) {
    int angle = Serial.parseInt();
    
    // 入力値の範囲チェック
    if (angle >= 0 && angle <= 180) {
      myServo.write(angle);  // 角度を指定
      Serial.print("Command: ");
      Serial.print(angle);
      Serial.println(" degrees");
    } else {
      Serial.println("Error: Angle must be 0-180");
    }
    
    // シリアルバッファをクリア
    while (Serial.available() > 0) {
      Serial.read();
    }
  }
}

コードの重要ポイント解説

1. myServo.attach() の第2・第3引数

myServo.attach(SERVO_PIN, 500, 2400);

この2つの数値がキモです:

  • 第2引数(500):0度の位置で出力するパルス幅(マイクロ秒)
  • 第3引数(2400):180度の位置で出力するパルス幅(マイクロ秒)

デフォルト値は attach(SERVO_PIN) で 1000μs と 2000μs ですが、SG90の実際の動作範囲に合わせて調整することで、可動範囲を最大限に活用できます。

2. シリアル通信の設定

Serial.begin(115200);

Arduino UNO R4は高速なマイコンなので、115200 bps の高速通信が安定して使えます。オシロスコープでの観測と同時にシリアルモニタを使う場合、高速通信の方が画面更新がスムーズです。

3. 入力値の検証

if (angle >= 0 && angle <= 180) {
  // 処理
}

不正な値をサーボに送らないよう、必ず範囲チェックを行います。範囲外の値を送ると、サーボが限界位置で無理に動こうとして消費電流が増え、故障の原因になります。

より高度な制御:スムーズな角度遷移

急激な角度変化を避け、滑らかに動かすコード例:

#include <Servo.h>

const int SERVO_PIN = 9;
Servo myServo;
int currentAngle = 90;  // 現在の角度
int targetAngle = 90;   // 目標角度

void setup() {
  Serial.begin(115200);
  myServo.attach(SERVO_PIN, 500, 2400);
  myServo.write(currentAngle);
  Serial.println("=== Smooth Servo Control ===");
  Serial.println("Enter target angle (0-180):");
}

void loop() {
  // シリアル入力の処理
  if (Serial.available() > 0) {
    int input = Serial.parseInt();
    if (input >= 0 && input <= 180) {
      targetAngle = input;
      Serial.print("Target: ");
      Serial.println(targetAngle);
    }
    while (Serial.available() > 0) Serial.read();
  }
  
  // スムーズに角度を変化させる
  if (currentAngle < targetAngle) {
    currentAngle++;
    myServo.write(currentAngle);
    delay(15);  // 15msごとに1度ずつ変化
  } else if (currentAngle > targetAngle) {
    currentAngle--;
    myServo.write(currentAngle);
    delay(15);
  }
}

このコードでは、目標角度に向かって1度ずつ、15msごとに変化させることで、機械的な衝撃を減らし、サーボの寿命を延ばすことができます。


⚠️ なぜ analogWrite() ではダメなのか?

Arduino初心者が陥りやすい落とし穴として、「PWMだから analogWrite() で制御できるはず」という誤解があります。

周波数の違いが致命的

Arduino の analogWrite() は、主にLEDの調光などに使われる関数で、以下のような高速PWMを出力します:

Arduino ボード 周波数 周期
UNO(ピン5, 6を除く) 約490 Hz 約2.04 ms
UNO(ピン5, 6) 約980 Hz 約1.02 ms

一方、サーボモータが求めるPWM信号は:

仕様 周波数 周期
サーボ制御信号 50 Hz 20 ms

約10〜20倍も速い信号を送ることになります。

何が起きるのか?

サーボ内部の制御回路は「20msに1回、パルスが来る」ことを前提に設計されています。しかし analogWrite() では:

  1. 1秒間に490〜980回もパルスが来る
  2. 制御回路が「命令が速すぎる!」とパニック状態に
  3. サーボが震える、異音を発する、最悪の場合は発熱・破損

⚠️ 絶対に守るべきルール
サーボモータを制御する際は、必ず Servo.h ライブラリを使い、50Hzの適切な信号を送りましょう。


🔌 安定した動作のためのハードウェアの工夫

動画でも実践している通り、精密な制御には環境作りが欠かせません。

1. 電源の分離

なぜ電源分離が必要か?

サーボモータは、以下のような大電流を消費します:

動作状態 消費電流
無負荷(停止中) 約10〜50 mA
軽負荷動作時 約100〜300 mA
最大負荷(ストール)時 500 mA〜1 A

Arduino の 5V ピンから供給できる電流は最大 500mA 程度で、これを超えると:

  1. 電圧降下が発生
  2. Arduino の動作電圧が下がる
  3. マイコンがリセットされる(ブラウンアウト)
  4. プログラムが停止・誤動作

正しい接続方法

外部5V電源 ─┬─ サーボモータ(赤:VCC)
            │
            └─ Arduino 5V ピン(接続しない!)

GND共通 ────┬─ サーボモータ(茶:GND)
            ├─ Arduino GND
            └─ 外部電源 GND

Arduino D9 ──── サーボモータ(橙:信号線)

💡 推奨電源

  • USB電源アダプタ(5V 2A以上)
  • 安定化電源
  • 単3電池4本(約6V)+ レギュレータ

2. 物理的固定の重要性

サーボがガタつくと:

  • 反動で正確な角度が出せない
  • ポテンショメータの読み取り値がブレる
  • オシロスコープでの測定結果が不安定になる

バイスなどでしっかりと土台を固定することで、安定した測定が可能になります。特にオシロスコープで波形を観測する場合、物理的な振動はノイズとして現れるため、固定は必須です。

3. 配線のノイズ対策

  • 信号線はできるだけ短く:長い配線はアンテナとなり、ノイズを拾う
  • 信号線とGNDをツイスト(ねじる):電磁ノイズをキャンセル
  • 電源線と信号線を離す:電源のスイッチングノイズが混入しないように

📊 実験データと考察

個体差の実測データ

同じSG90を3個用意し、それぞれの実際の動作範囲を測定しました:

サーボNo. 0度時のパルス幅 90度時のパルス幅 180度時のパルス幅
#1 500 μs 1450 μs 2400 μs
#2 520 μs 1470 μs 2380 μs
#3 480 μs 1440 μs 2420 μs

最大で ±40μs の個体差があることが分かりました。この差は角度にすると約 ±3.6度 に相当します。


🎓 まとめ:仕組みを知ればもっと楽しくなる

シリアルモニタから値を送り、それが電気信号(PWM)に変わり、モータが物理的に動く。この一連の流れをオシロスコープで可視化すると、ブラックボックスだったサーボモータが、非常に論理的で愛着の持てるパーツに見えてきませんか?

この記事で学んだこと

✅ サーボモータの内部構造とフィードバック制御の原理
✅ PWM信号の仕様とオシロスコープでの可視化方法
✅ Servo.hライブラリの正しい使い方と個体差への対応
✅ 電源分離やノイズ対策などのハードウェア設計の重要性
analogWrite() が使えない理由と周波数の違い

次のステップ

今回の知識を基に、以下のような応用に挑戦してみてください:

  1. 複数サーボの同時制御:ロボットアームの製作
  2. センサー連動:超音波センサーと組み合わせた自動追尾
  3. インピーダンス制御:電流監視で障害物検知(次回予告!)

🔍 専門用語解説

サーボモータ(Servo Motor)

指定した角度に正確に回転し、その位置を保持できるモーター。フィードバック制御により、目標角度と現在角度を常に比較して制御する。

PWM(Pulse Width Modulation:パルス幅変調)

デジタル信号のON時間(パルス幅)を変化させることで、アナログ的な制御を実現する技術。サーボ制御では、パルス幅で角度を指定する。

フィードバック制御(Feedback Control)

出力(現在の角度)を測定し、目標値との差を計算して制御量を調整する方式。閉ループ制御とも呼ばれる。

ポテンショメータ(Potentiometer:可変抵抗)

回転角度に応じて抵抗値が変化する素子。サーボモータでは角度センサーとして使用される。

デューティ比(Duty Cycle)

PWM信号の1周期において、ON時間が占める割合。サーボ制御では、周期20msに対するパルス幅の比率。

オシロスコープ(Oscilloscope)

電気信号の電圧変化を時間軸で表示する測定器。PWM信号の波形やパルス幅を正確に測定できる。

ストール(Stall)

モーターが負荷により回転できない状態。サーボがストールすると大電流が流れ、発熱や破損の原因となる。

ブラウンアウト(Brownout)

電圧降下により、マイコンが正常に動作できなくなる現象。サーボの大電流により発生しやすい。


📚 関連記事


💬 次回予告

次回は、この「サーボに流れる電流」を監視することで、障害物を検知するインピーダンス制御編に挑戦します!サーボが「何かにぶつかった」ことを電流値から判断し、自動停止する仕組みを実装します。お楽しみに!


📢 この記事が役に立ったら、ぜひSNSでシェアしてください!
質問や改善案があれば、コメント欄でお気軽にお知らせください。