Arduinoでサーボモーターを制御する方法–完全ガイド
このチュートリアルでは、サーボモーターの仕組みについて学習します。 Arduinoでサーボモーターを制御する方法 。サーボモーターは非常に人気があり、使いやすく、優れた位置制御を提供するため、多くのArduinoプロジェクトで広く使用されています。
サーボは、ロボット工学プロジェクト、自動化、RCモデルなどに最適です。私はすでにArduinoプロジェクトの多くでそれらを使用しており、ここでそれらのいくつかをチェックすることができます:
次のビデオを見るか、以下のチュートリアルを読むことができます。 Arduinoでサーボモーターを使用する方法のいくつかの例、配線図、およびコードが含まれています。さらに、PCA9685PWMドライバーを使用してArduinoで複数のサーボモーターを制御する方法のガイドがあります。
サーボモーターは、位置フィードバックを使用してその動きと最終位置を制御する閉ループシステムです。サーボモーターには多くの種類があり、その主な特徴はシャフトの位置を正確に制御できることです。
産業用サーボモーターでは、位置フィードバックセンサーは通常高精度エンコーダーですが、小型のRCまたはホビーサーボでは、位置センサーは通常単純なポテンショメーターです。これらのデバイスによってキャプチャされた実際の位置は、エラー検出器にフィードバックされ、そこでターゲット位置と比較されます。次に、エラーに応じて、コントローラーはモーターの実際の位置を修正して、目標位置と一致させます。
このチュートリアルでは、ホビーサーボモーターについて詳しく見ていきます。これらのサーボがどのように機能し、Arduinoを使用してそれらを制御する方法を説明します。
ホビーサーボは、RCおもちゃの車、ボート、飛行機などを制御するために使用される小型のアクチュエータです。また、ロボット工学のプロトタイピング、ロボットアームの作成、生物学的に着想を得たロボット、ヒューマノイドロボットなどのエンジニアリング学生によっても使用されます。
ホビーサーボの内部には、DCモーター、ギアボックス、ポテンショメーター、制御回路の4つの主要コンポーネントがあります。 DCモーターは高速で低トルクですが、ギアボックスは速度を約60 RPMに下げ、同時にトルクを上げます。
ポテンショメータはファイナルギアまたは出力シャフトに取り付けられているため、モーターが回転するとポテンショメータも回転し、出力シャフトの絶対角度に関連する電圧が生成されます。制御回路では、このポテンショメータ電圧が信号線からの電圧と比較されます。必要に応じて、コントローラーは統合されたHブリッジをアクティブにし、2つの信号がゼロの差に達するまでモーターをどちらの方向にも回転できるようにします。
サーボモーターは、信号線を介して一連のパルスを送信することによって制御されます。制御信号の周波数は50Hzであるか、20msごとにパルスが発生する必要があります。パルスの幅によってサーボの角度位置が決まり、これらのタイプのサーボは通常180度回転できます(物理的な移動制限があります)。
一般に、持続時間が1msのパルスは0度の位置に対応し、持続時間1.5msは90度、2msは180度に対応します。パルスの最小および最大持続時間はブランドによって異なる場合があり、0度の場合は0.5ms、180度の位置の場合は2.5msになる可能性があります。
RCやホビーにはさまざまなモデルやメーカーがあります。サーボモーターを選択する際の主な考慮事項は、そのトルク、動作電圧、消費電流、およびサイズです。
メーカー間で最も人気のある2つのサーボモデル、SG90マイクロサーボとMG996Rを次に示します。
SG90マイクロサーボ 技術仕様:
MG996Rサーボ 技術仕様:
上記をテストして、Arduinoを使用してホビーサーボを制御する実際的な例を作成しましょう。ストールトルク10kg-cmのメタルギアを採用した高トルクサーボMG996Rを使用します。高トルクには代償が伴い、それがサーボのストール電流である2.5Aです。動作電流は500mAから900mAで、動作電圧は4.8から7.2Vです。
現在の定格は、このサーボをArduinoに直接接続できないことを示していますが、別の電源を使用する必要があります。
この例の回路図は次のとおりです。
サーボの制御ピンをArduinoボードのデジタルピンに接続し、アース線とプラス線を外部5V電源に接続し、Arduinoアースをサーボアースに接続するだけです。
小型のホビーサーボであるS90MicroServoを使用する場合は、5VArduinoピンから直接電力を供給することができます。
S90 Micro Servoの消費電流は低く、無負荷時の動作電流は約100〜200mAですが、ストール電流は約500〜700mAです。一方、Arduino 5Vピンは、USB経由で電力を供給した場合は約500mAしか出力できず、バレルコネクタ経由で電力を供給した場合は最大1Aしか出力できません。
これらの9gサーボモーターを直接Arduinoに接続することは可能ですが、より安定した作業のために、常に外部電源を使用することをお勧めします。
この例に必要なコンポーネントは、以下のリンクから入手できます。
それでは、サーボモーターを制御するためのArduinoコードを見てみましょう。コードは非常に単純です。サーボが接続されているピンを定義し、そのピンを出力として定義し、ループセクションで、前に説明したように特定の持続時間と周波数のパルスを生成する必要があります。
いくつかのテストの後、サーボで機能するパルスの持続時間について、次の値を考え出しました。持続時間が0.6msのパルスは、0度の位置、1.45msから90度、2.3msから180度に対応しました。
マルチメータをサーボと直列に接続して、電流引き込みを確認しました。私が気付いた最大消費電流は、ストール時に最大0.63Aでした。これは、元のTowerPro MG996Rサーボではなく、より安価なレプリカであり、明らかにパフォーマンスが低下しているためです。
それでも、Arduinoを使用してサーボを制御するより便利な方法を見てみましょう。 Arduinoサーボライブラリを使用しています。
ここでは、ライブラリを含め、サーボオブジェクトを定義し、attach()関数を使用して、サーボが接続されているピンを定義し、パルス幅の最小値と最大値を定義する必要があります。次に、write()関数を使用して、サーボの位置を0度から180度に設定するだけです。
Arduinoサーボライブラリは、ほとんどのArduinoボードで同時に最大12個のサーボの制御をサポートし、ArduinoMegaボードを使用して48個のサーボの制御をサポートします。さらに、Arduinoで複数のサーボモーターを制御するのは、1つだけを制御するのと同じくらい簡単です。
複数のサーボを制御するためのサンプルコードは次のとおりです。
したがって、サーボモーターごとにServoクラスからオブジェクトを作成し、どのArduinoピンに接続するかを定義する必要があります。もちろん、いつでも、どの位置にでも移動するようにサーボを設定できます。
例として、ArduinoMEGAボードを使用して22個のサーボモーターを制御したArduinoAntHexapodRobotプロジェクトを確認することもできます。
Arduinoでサーボを制御する別の方法もあります。それはPCA9685サーボドライバーを使用することです。これは、I2Cバスを使用してArduinoと通信する16チャネル12ビットPWMおよびサーボドライバーです。クロックが組み込まれているため、16個のサーボをフリーランニングで、またはArduinoとは独立して駆動できます。
さらにクールなのは、1つのI2Cバスで最大62個のドライバーをデイジーチェーン接続できることです。したがって、理論的には、Arduinoボードの2つのI2Cピンのみを使用して最大992のサーボを制御できます。 6つのアドレス選択ピンは、追加のドライバーごとに異なるI2Cアドレスを設定するために使用されます。この表に従ってはんだパッドを接続するだけです。
これが回路図です。サーボ用に別の電源が必要であることにもう一度気付くことができます。
この例に必要なコンポーネントは、以下のリンクから入手できます。
それでは、Arduinoコードを見てみましょう。このサーボドライバーを制御するには、GitHubからダウンロードできるPCA9685ライブラリを使用します。
したがって、最初にライブラリを含め、PCA9685オブジェクトを定義する必要があります。次に、Servo_Evaluatorインスタンスを使用して、ドライバーのパルス幅またはPWM出力を定義します。出力は12ビットであることに注意してください。つまり、4096ステップの解像度です。したがって、0.5msまたは0度の位置の最小パルス持続時間は102ステップに対応し、2.5msまたは180度の位置の最大パルス持続時間は512ステップに対応します。ただし、前に説明したように、これらの値はサーボモーターに応じて調整する必要があります。私の値は102から470で、これは0から180度の位置に対応します。
セットアップセクションでは、I2Cクロックレートを定義し、ドライバーアドレスを設定し、周波数を50Hzに設定する必要があります。
ループセクションで、 setChannelPWM()を使用します およびpwmForAngle() 機能は、サーボを希望の角度に設定するだけです。
2つ目のサーボをドライバーに接続しましたが、予想どおり、最初のサーボと同じ位置にありませんでした。これは、使用しているサーボが安価なコピーであり、信頼性が低いためです。ただし、 Servo_Evaluator を使用しているため、これは大きな問題ではありません。 たとえば、サーボごとに異なる出力設定を設定できます。正確に真ん中にない場合は、90度の位置を調整することもできます。このようにして、すべてのサーボが同じように動作し、正確な角度で配置されます。
もう1つの例を見てみましょう。これは、複数のチェーンPCA9685ドライバーで多くのサーボを制御しています。
そのためには、ドライバーを相互に接続し、適切なアドレス選択はんだパッドを接続する必要があります。回路図は次のとおりです。
ここでArduinoコードを見てみましょう。
したがって、ドライバーごとに個別のPCA9685オブジェクトを作成し、ドライバーごとにアドレスを定義し、周波数を50Hzに設定する必要があります。これで、setChannelPWM()関数とpwmForAngle()関数を使用するだけで、任意のドライバーに任意のサーボを設定して、任意の角度に配置できます。
これは、これらのホビーサーボモーター、SG90マイクロサーボおよびMG996Rに共通の問題です。この理由は、前述のように、負荷がかかっているときにかなりの量の電流を引き込む可能性があるためです。これにより、特にArduino 5Vピンから直接サーボに電力を供給している場合、Arduinoボードがリセットされる可能性があります。
この問題を解決するために、GNDと5Vピンの両端にコンデンサを使用できます。これは、DCモーターの始動時に、始動時にシステムに追加の電流を供給するデカップリングコンデンサとして機能します。
これは、これらのホビーサーボに共通するもう1つの問題です。前に説明したように、1ms(0.5ms)のパルス幅は0度の位置に対応し、2ms(2.5ms)は180度に対応します。ただし、これらの値はサーボごとに、またメーカーによって異なる場合があります。
この問題を解決するには、Arduinoでサーボモーターに送信するパルス幅を調整する必要があります。幸い、Arduino Servoライブラリを使用すると、 attach()でパルス幅の値を簡単に調整できます。 機能。
attach() 関数は2つの追加パラメーターを受け取ることができます。これは、マイクロ秒単位の最小および最大パルス幅です。デフォルト値は、最小(0度)角度の場合は544マイクロ秒(0.544ミリ秒)、2400マイクロ秒(2.4ms)です。したがって、これらの値を調整することで、サーボのモーメント範囲を微調整できます。
最も人気のある2つのサーボモーターであるSG90マイクロサーボとMG996Rサーボモーターの3Dモデルを作成しました。以下のリンクからダウンロードしてロードできます。
3Dモデル:Thangsからダウンロードします。
寸法:
MG996Rサーボモーター3Dモデル:Thangsからダウンロード。
寸法:
したがって、Arduinoでサーボモーターを使用することについて知っておく必要のあるほとんどすべてをカバーしました。もちろん、これらのタイプのホビーまたはRCサーボモーターのメーカーやモデルは数多くあり、それぞれに独自の機能があり、上記で説明したものとは異なる場合があります。
モーターを使用して素晴らしいロボット工学、自動化、RCプロジェクトを作成する可能性は無限ですが、アプリケーションに適したモデルを選択することは非常に重要です。
このチュートリアルを楽しんで、何か新しいことを学んだことを願っています。以下のコメントセクションでお気軽に質問してください。また、Arduinoプロジェクトコレクションができることを確認してください。
Arduinoでサーボモーターを使用するのは非常に簡単です。サーボモーターには3本のワイヤーがあり、そのうち2本は電源用のGNDと5Vで、3本目のワイヤーはArduinoボードに接続する制御ラインです。
Arduinoから直接サーボモーターを実行できますが、電源に問題がある可能性があります。サーボモーターに500mAを超える電流が流れると、Arduinoボードの電源が失われてリセットされる可能性があります。サーボモーターには常に別の電源を使用することをお勧めします。
Arduinoサーボライブラリを使用すると、ほとんどのArduinoボードで最大12個のサーボモーターを制御でき、ArduinoMegaボードで最大48個のサーボモーターを制御できます。もちろん、サーボモーター専用の電源を使用する必要があります。
サーボモーターとは何ですか?
Arduinoプロジェクトで人気のRC/ホビーサーボ
ストールトルク 1.2kg・cm @ 4.8V、1.6kg・cm @ 6V、 動作電圧 3.5 – 6V 無負荷電流 100mA 現在のストール 650mA 最大速度 0.12秒で60度 重量 9g
ストールトルク 11kg.cm @ 4.8v、13kg.cm @ 6V 動作電圧 4.8 – 7.2V 無負荷電流 220mA @ 4.8V、250mA @ 6V 現在のストール 650mA 最大速度 0.20秒で60度 重量 55g Arduinoサーボモーター制御
回路図
/*
Servo Motor Control - 50Hz Pulse Train Generator
by Dejan, https://howtomechatronics.com
*/
#define servoPin 9
void setup() {
pinMode(servoPin, OUTPUT);
}
void loop() {
// A pulse each 20ms
digitalWrite(servoPin, HIGH);
delayMicroseconds(1450); // Duration of the pusle in microseconds
digitalWrite(servoPin, LOW);
delayMicroseconds(18550); // 20ms - duration of the pusle
// Pulses duration: 600 - 0deg; 1450 - 90deg; 2300 - 180deg
}
Code language: Arduino (arduino)/*
Servo Motor Control using the Arduino Servo Library
by Dejan, https://howtomechatronics.com
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
void setup() {
myservo.attach(9,600,2300); // (pin, min, max)
}
void loop() {
myservo.write(0); // tell servo to go to a particular angle
delay(1000);
myservo.write(90);
delay(500);
myservo.write(135);
delay(500);
myservo.write(180);
delay(1500);
}
Code language: Arduino (arduino)Arduinoで複数のサーボモーターを制御する
/*
Controlling multiple servo motors with Arduino
by Dejan, https://howtomechatronics.com
*/
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
void setup() {
servo1.attach(8);
servo2.attach(9);
servo3.attach(10);
servo4.attach(11);
servo5.attach(12);
}
void loop() {
// move all servos to position 0
servo1.write(0);
servo2.write(0);
servo3.write(0);
servo4.write(0);
servo5.write(0);
delay(2000);
// move all servos to position 90
servo1.write(90);
servo2.write(90);
servo3.write(90);
servo4.write(90);
servo5.write(90);
delay(2000);
// move all servos to position 180
servo1.write(180);
servo2.write(180);
servo3.write(180);
servo4.write(180);
servo5.write(180);
delay(2000);
}
Code language: Arduino (arduino)ArduinoおよびPCA9685PWM/サーボドライバー
ArduinoおよびPCA9685コード
/*
Servo Motor Control using Arduino and PCA9685 Driver
by Dejan, https://howtomechatronics.com
Library: https://github.com/NachtRaveVL/PCA9685-Arduino
*/
#include <Wire.h>
#include "PCA9685.h"
PCA9685 driver;
// PCA9685 outputs = 12-bit = 4096 steps
// 2.5% of 20ms = 0.5ms ; 12.5% of 20ms = 2.5ms
// 2.5% of 4096 = 102 steps; 12.5% of 4096 = 512 steps
PCA9685_ServoEvaluator pwmServo(102, 470); // (-90deg, +90deg)
// Second Servo
// PCA9685_ServoEvaluator pwmServo2(102, 310, 505); // (0deg, 90deg, 180deg)
void setup() {
Wire.begin(); // Wire must be started first
Wire.setClock(400000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz
driver.resetDevices(); // Software resets all PCA9685 devices on Wire line
driver.init(B000000); // Address pins A5-A0 set to B000000
driver.setPWMFrequency(50); // Set frequency to 50Hz
}
void loop() {
driver.setChannelPWM(0, pwmServo.pwmForAngle(-90));
delay(1000);
driver.setChannelPWM(0, pwmServo.pwmForAngle(0));
delay(1000);
driver.setChannelPWM(0, pwmServo.pwmForAngle(90));
delay(1000);
}
Code language: Arduino (arduino)ArduinoおよびPCA9685ドライバーで多くのサーボを制御する
/*
Servo Motor Control using Arduino and PCA9685 Driver
by Dejan, https://howtomechatronics.com
Library: https://github.com/NachtRaveVL/PCA9685-Arduino
*/
#include <Wire.h>
#include "PCA9685.h"
PCA9685 driver;
// PCA9685 outputs = 12-bit = 4096 steps
// 2.5% of 20ms = 0.5ms ; 12.5% of 20ms = 2.5ms
// 2.5% of 4096 = 102 steps; 12.5% of 4096 = 512 steps
PCA9685_ServoEvaluator pwmServo(102, 470); // (-90deg, +90deg)
// Second Servo
PCA9685_ServoEvaluator pwmServo2(102, 310, 505); // (0deg, 90deg, 180deg)
void setup() {
Wire.begin(); // Wire must be started first
Wire.setClock(400000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz
driver.resetDevices(); // Software resets all PCA9685 devices on Wire line
driver.init(B000000); // Address pins A5-A0 set to B000000
driver.setPWMFrequency(50); // Set frequency to 50Hz
}
void loop() {
driver.setChannelPWM(0, pwmServo.pwmForAngle(-90));
delay(1000);
driver.setChannelPWM(0, pwmServo.pwmForAngle(0));
delay(1000);
driver.setChannelPWM(0, pwmServo.pwmForAngle(90));
delay(1000);
}
Code language: Arduino (arduino)トラブルシューティング
サーボモーターがジッターしてArduinoボードをリセットします
サーボモーターは0度から180度までの全範囲を移動しません
myservo.attach(9,600,2300); // (pin, min, max)
Code language: Arduino (arduino)寸法と3Dモデル
SG90マイクロサーボ
MG996Rサーボモーター
結論
よくある質問(FAQ)
製造プロセス