「M5Atomで作る歩行ロボット」という本の犬型ロボットの製作記です。
サーボをバッテリーを使ってマイコンM5Atomで動かすテストをしました。
バッテリーにソケットを接続
6Vバッテリー(Gecoty Ni-MHバッテリー Amazonで購入) には、充電用のUSBケーブルもついて来ましたが(写真右上)、使用するときにバッテリーにつなげられるソケットがありません。引き出しを探したところ、写真左上のような同じUSBケーブルが出てきたので、このソケット部分を利用することにしました。

下のように加工しました(切っただけ)。これで、バッテリーの使用時と充電時で取り外しができます。

電源 DCDCコンバータの調整
6Vのバッテリーは12個のサーボを動かすために、電圧が変動するとのことで直接M5Atomを動かすのではなく、いったんDCDCコンバーター LXDCSS で安定した4Vの電源を作って、供給することになります。
DCDCコンバーター LXDCSS の基板の上に取り付けた青いパーツのねじ部分を回すことで、出力の電圧を調節することができます。

テスターで出力電圧をモニターしながらねじ部分を回すことで、6Vの供給電圧に対して、4Vを出力するように調整しました。

サーボとの接続
回路をサーボモーターに接続しました。サーボモーターは12個もあるので配線がすごいです。あとはバッテリーの赤いケーブルを投げると電源が投下されます。

サーボの動作確認のためのマイコンのプログラム
12個ものサーボをマイコン(M5Atom Matrix)で直接動かすことができないために、サーボドライバー(PCA9685)を使います。
マイコンからサーボドライバーには、I2Cで通信します。
サーボドライバー用のライブラリーにはいろいろあるようなのですが、本で紹介している秋月電子通商のものがなぜか使えなかったので(zipファイルを追加時にエラーが出る、ファイルが違っている?)、Adafruit-PWM-Servo-Driver-Library というものを使いました。
これは、Arduion IDEのライブラリマネージャーに登録されているので、簡単にインストールできました。
これを使って、1番目の端子につなげたサーボを10度の幅で動かすことができました。
#include "M5Atom.h"
#include <Wire.h> // I2C setting
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 104 //Min pulse width (12bit 500μs)
#define SERVOMAX 512 //Max pulse width (12bit 2500μs)
#define DIGMIN -9000 // -90deg x 100
#define DIGMAX 9000 // 90deg x 100
void setup()
{
Wire.begin(19, 22); //SDA-19, SCL-22
pwm.begin(); //initial setting (for 0x40) (PCA9685)
pwm.setPWMFreq(50); //PWM 50Hz (for 0x40) (PCA9685)
M5.begin(true, true, true);
delay(50);
M5.dis.drawpix(0, 0x00ff00); // LED green
Serial.begin(19200);
}
int count = 0;
int dir = 1;
void loop()
{
// count を0から10まで増加させ、0まで減少させるを繰り返す
count += dir;
if (count >= 10) {
dir = -1;
M5.dis.drawpix(0, 0x0000ff); // LED blue
} else if (count <= 0) {
dir = 1;
M5.dis.drawpix(0, 0x000000); // LED black
}
servo_set(0, count * 1.0);
delay(100);
}
void servo_set(int i, float angle)
{
int srv_ang = map(100 * angle, DIGMIN, DIGMAX, SERVOMIN, SERVOMAX);
pwm.setPWM(i, 0, srv_ang);
}
Code language: C++ (cpp)
これを拡張して、12個のサーボを同時に動かすことも次のプログラムでできました。
#include "M5Atom.h"
#include <Wire.h> // I2C setting
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 104 //Min pulse width (12bit 500μs)
#define SERVOMAX 512 //Max pulse width (12bit 2500μs)
#define DIGMIN -9000 // -90deg x 100
#define DIGMAX 9000 // 90deg x 100
int SrvAng[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float TARGET_JOINT_POSITIONS[12] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
float TRIM[12] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
void setup()
{
Wire.begin(19, 22); //SDA-19, SCL-22
pwm.begin(); //initial setting (for 0x40) (PCA9685)
pwm.setPWMFreq(50); //PWM 50Hz (for 0x40) (PCA9685)
M5.begin(true, true, true);
delay(50);
M5.dis.drawpix(0, 0xff0000); // LED
Serial.begin(19200);
}
int count = 0;
int dir = 1;
void loop()
{
// count を0から10まで増加させ、0まで減少させるを繰り返す
count += dir;
if (count >= 10) {
dir = -1;
M5.dis.drawpix(0, 0x0000ff);
} else if (count <= 0) {
dir = 1;
M5.dis.drawpix(0, 0x000000);
}
// JOINT の単位が度だとする
for (int i = 0; i <= 11; i++){
TARGET_JOINT_POSITIONS[i] = count * 1.0;
}
servo_set();
delay(50);
}
void servo_set()
{
for (int i; i <= 11; i++) {
int srv_ang = 100 * (TARGET_JOINT_POSITIONS[i] + TRIM[i]);
SrvAng[i] = map(srv_ang, DIGMIN, DIGMAX, SERVOMIN, SERVOMAX);
pwm.setPWM(i, 0, SrvAng[i]);
}
}
Code language: C++ (cpp)
こんな感じに動きました。
コメントを残す