ラズパイのNode.jsとPCA9685で複数サーボモーターをi2c制御してみる
前回の記事では、単体のサーボモーターをラズパイ本体のハードウェア PWM で制御してみました。
ラズパイとNode.jsでサーボモータをPWM制御してみる
以前の記事では、ポテンショメータに応じてモーターコントローラと PWM で DC モーターを回してみました。 今回は同じ PWM 信号でサーボモーターを回してみたいと思います。 ハードウェア - SG90 サーボモーターとはざっくりいうと、内部に DC モーターとギアとコントロ…
今回は同じサーボモーターを PWM モジュールで複数制御してみたいと思います。
ハードウェア - PCA9685
PWM で複数制御する場合、ラズパイでハードウェア PWM できる端子数が足りないので、このようなマルチチャンネル PWM 制御基盤を使います。これは 16 チャンネル接続できます。ラズパイからは i2c で信号を送ります。
VCC は IC 用電源、V+はサーボモーター用電源、GND はグランドにつなぎます。(中央下のねじ止めする電原接続と同じなのでどちらにつないでも OK)
SCL、SDA はラズパイのそれらの端子につなぎます。(ラズパイは I2C を有効にする必要あり)
ちなみに PCA9685 を複数接続する場合、A0 ~ A5 のどこか(又は組み合わせ)を適当にはんだ付けすると I2C のアドレスが変わるので、接続後「i2cdetect -y 1」コマンドでアドレスを確認して使用します。
ちゃんとつながっていればこんな感じで複数 ID を取得できます。
ソフトウェア - Pca9685Driver
npm に Pca9685Driver と言うこの基板専用のライブラリが転がっていたのでそれを使います。
これは i2c-bus ライブラリを使用するのでまとめてインストール。TypeScript 用定義もインストール。
npm i -S pca9685 i2c-bus
npm i -D @types/i2c-bus
以下のように使用します。以下はメインループ関数です。
注意点として、サーボの PWM は 50Hz で動作しているため、それより早い周期でメインループをぶん回すと動作がおかしくなるようです。最初それが分からなくて時間がかかりましたが、適当に sleep を入れたら問題なく動きました。
import i2c from 'i2c-bus';
import Pca9685Driver from 'pca9685';
const DEVICE_NUMBER = 1;
const PCA9685_ADDRESS = 0x40;
const PWM_FREQUENCY = 50;
export class Main {
i2cBus: i2c.I2CBus;
pca: Pca9685Driver;
constructor() {
// デバイスオープン
this.i2cBus = i2c.openSync(DEVICE_NUMBER);
// ドライバ作成
this.pca = new Pca9685Driver(
{
i2c: this.i2cBus,
address: PCA9685_ADDRESS,
frequency: PWM_FREQUENCY,
debug: false,
},
err => {
console.log(err);
}
);
}
public Frame() {
// Frameは50Hzで動作(呼び出しもとでsleep(20)を入れている)
const output1 = Math.floor(Math.sin(new Date().getTime() / 500) * 600 + 1500);
const output2 = Math.floor(Math.cos(new Date().getTime() / 500) * 600 + 1500);
this.pca.setPulseLength(14, output1);
this.pca.setPulseLength(15, output2);
}
}
最初に i2c デバイスをオープンし、それを Pca9685Driver に渡しています。
それ以降は sin 波 と cos 波を適当な波長と振幅に調整して、2 つのモーターの入力角度にしています。
(500 ~ 2500 が入力範囲なので、1500 から 600 を前後させるような計算ですね。)
テスト
ヘキサポッド的なロボットの足用に作ったパーツを付けてテスト。
いい感じです。