はじめに
ここでは,Arduino UNOを使って「EEZYbotARM mk1」を動かしてみます.
ただし,今回はラジコンサーボの角度を変化させることはなく,ニュートラル角度で固定したままです.
目次へ戻るには ここ をクリック
※本ページは実験のテキストです.
概要
前回は「 Adafruit PWM Servo Driver Library 」がインストールされていることを確認しました.
今回はこのライブラリを使って,ラジコンサーボが搭載されたロボット「EEZYbotARM mk1」を動かしてみます.
配線の接続
ACアダプタをPCA9685シールド基板に挿してください.
既にI2Cの動作テストのプログラムを書き込んであるので,暴走する危険はありません.
※注意
ACアダプタを挿すのは,Arduino UNO本体ではありません.PCA9685シールド基板の方です.
コネクタが同じなので,挿すことはできるのですが,
Arduino UNO側に電力を供給しても,ラジコンサーボに電力が供給されないのでモータが動きません...
スケッチを書き込む
では、Adafruit PWM Servo Libraryを使って,EEZYbotARMを動かしてみましょう。
メニューバーから[ファイル]-[新規ファイル]をクリックし、新しいプログラムを書く準備をしてください。
以下のプログラムを打ち込み、コンパイル/実行してみましょう。
ファイル名は 9685_servo_test.ino
としました。
// ライブラリの読み込み
#include <Wire.h> // I2C通信
#include <Adafruit_PWMServoDriver.h> // PCA9685でサーボを動かすライブラリ
// サーボのパルス幅(μs)
#define SERVO_MIN 800 // 最小パルス幅
#define SERVO_CENT 1500 // ニュートラル(センター)
#define SERVO_MAX 2200 // 最大パルス幅
// ロボットアームのピン番号
#define SERVO0_YAW 0
#define SERVO1_LINK1 1
#define SERVO2_LINK2 2
#define SERVO3_HAND 3
// サーボ制御クラスの作成
Adafruit_PWMServoDriver Servo = Adafruit_PWMServoDriver(0x40); // PCA9685のI2Cアドレスは0x40番地
// 初期化関数
void setup() {
// PWM Servoドライバを初期化する
Servo.begin();
// PWM周波数を50Hzに設定する
Servo.setPWMFreq(50);
delay(1000);
// それぞれのサーボにパルス幅(マイクロ秒)を与える
Servo.writeMicroseconds(SERVO0_YAW, 1500);
Servo.writeMicroseconds(SERVO1_LINK1, 1500);
Servo.writeMicroseconds(SERVO2_LINK2, 1500);
Servo.writeMicroseconds(SERVO3_HAND, 1500);
delay(100); // 待ち時間
}
// ループ関数
void loop() {
// 今回はなにもしない
}
動作テスト
Arduinoに書き込みが終わると,ロボットアームに力が入って動きます.
今回は全てのサーボをニュートラル位置(1500マイクロ秒)にするだけなので,連続して動くことはありません.
もし,ロボットアームが変な姿勢になっていたら,サーボがズレているかもしれないので,担当の先生に申し出てください.
プログラム解説
それではプログラムを解説していきます.
準備
まずはプログラムの冒頭部分で,
I2C通信をするためのWire.h
と,AdafruitのライブラリAdafruit_PWMServoDriver.h
をインクルードしています.
前回インストールしたライブラリは,#include
することで使えるようになるのです.
// ライブラリの読み込み
#include <Wire.h> // I2C通信
#include <Adafruit_PWMServoDriver.h> // PCA9685でサーボを動かすライブラリ
// サーボのパルス幅(μs)
#define SERVO_MIN 800 // 最小パルス幅
#define SERVO_CENT 1500 // ニュートラル(センター)
#define SERVO_MAX 2200 // 最大パルス幅
// ロボットアームのピン番号
#define SERVO0_YAW 0
#define SERVO1_LINK1 1
#define SERVO2_LINK2 2
#define SERVO3_HAND 3
// サーボ制御クラスの作成
Adafruit_PWMServoDriver Servo = Adafruit_PWMServoDriver(0x40); // PCA9685のI2Cアドレスは0x40番地
次に,サーボのパルス幅の下限値・ニュートラル値・上限値を#define
で宣言しています.
また,サーボのピン番号も#define
で宣言しています.
#define
はプログラム中で「置換」される機能です.変数の宣言ではありません.
変数は値が変化しますが,固定値で変えることのない数値を使う場合に#define
というマクロ機能を使って書くことがあります.
例えば,#define SERVO0_YAW 0
と書いてあるので,"SERVO0_YAW"という文字列があったら"0"に置き換えろ,と指示していることになります.
初期化関数の中でServo.writeMicroseconds(SERVO0_YAW, 1500);
と書いているので.
コンパイルする前にその部分が置換され,Servo.writeMicroseconds(0, 1500);
という状態に変化します.
#define
の次に書く文字列は,小文字を混ぜることもできるのですが,
「この文字列は変数じゃなくて#defineマクロだよ」と言うことを明確にするために,
ワザと全て大文字で書くプログラマが多いです.
最後にAdafruit_PWMServoDriver
クラスの実体(インスタンス)としてServo
を作っています.
その際にインスタンスの中身の初期化作業を行うため,
Servo = Adafruit_PWMServoDriver(0x40);
としてPCA9685のI2Cアドレスである0x40を引数として渡しているのがわかります.
こう書くことで,クラスが0x40番地との通信を勝手にやってくれます.
I2C通信の何たるかを理解する必要が無いので,便利です.
初期化関数
次は初期化関数です.
まずはインスタンスServo
を使って,ラジコンサーボを動かすための初期設定をしています.
Servo.begin()
は必ず最初に呼ぶ必要があります.
ラジコンサーボの信号 で解説しましたが,
サーボ信号は20ミリ秒おき,すなわち50Hzなので,
Servo.setPWMFreq(50)
でパルス周期を50Hzに設定しています.
// 初期化関数
void setup() {
// PWM Servoドライバを初期化する
Servo.begin();
// PWM周波数を50Hzに設定する
Servo.setPWMFreq(50);
delay(1000);
// それぞれのサーボにパルス幅(マイクロ秒)を与える
Servo.writeMicroseconds(SERVO0_YAW, 1500);
Servo.writeMicroseconds(SERVO1_LINK1, 1500);
Servo.writeMicroseconds(SERVO2_LINK2, 1500);
Servo.writeMicroseconds(SERVO3_HAND, 1500);
delay(100); // 待ち時間
}
初期設定が終わった後でServo.writeMicroseconds
関数を使って,
EEZYbotARM mk1の4つのサーボにパルス幅を与えています.
今回は全てのサーボを1500マイクロ秒にしました.ニュートラルの値に固定しています.
他の角度になることはありません.
ループ関数
次はループ関数です.
// ループ関数
void loop() {
// 今回はなにもしない
}
なんと今回はループ関数の中身は 空 です(^^;
繰り返して実行する作業がない場合は,今回のように空にしてしまう使い方もあるのです.
まとめ
今回は「 Adafruit PWM Servo Driver Library 」を使って「EEZYbotARM mk1」を動かしてみました.
ですが,1つの決まった姿勢になるだけでは全然面白くないですね.
各関節を自由に動かしてみたいところです.
おわりに
これでEEZYbotARMの動作テストは完了です.
次回はシリアル通信で動かしてみます.
目次 へ戻って次の作業を行ってください。