4つのモーターで水平昇降
4軸のステッピングモーターで昇降できるウィンチを作ることにしました。
なぜ普通のブラシモーターを使わないかというとステッピングモーターってトルクが強く、静止時にギアがなくても保持していることができて、比較的ゆっくり回せるからです。
巷には3Dプリンターのおかげで出回っています。
こんな感じで作ります。
Arduinoで細かい制御をして、Raspberry Piからのコマンドで動くことにします。
と、ん?
こういうボードはどっかで見たよな。
あ、あれだ。
CNCマシン用のボード。
とくにArduinoに乗っけるピンが完備したボードを”シールド”と呼ぶ風習があります・
このボードはCNCマシンのキットに使われていて、GRBLというオープンソースで駆動します。
何年か前にさんざんいじってたヤツ。
とてもポピュラーで、ボードは激安で売られています。
とりあえず4個モーターがついたキットを購入。モーターは4401タイプなのだそうだ。
ボードのバージョンは無印のV3.0です。
ボードチューニング
4401は12Vで200カウントで一回転する。最大電流は1.7Aです。
モータードライブモジュールはA4988という最大で2A程度がドライブできます。Arduino Uno R3もコネクターは12Vまでサポートしているので電源は12Vで決まりです。
ドローン基盤から取れるということですね。どうするかは未定だけど。
A4988ボードはのっかっている極小のボリュームで最大出力電流をコントロールできます。
GNDとボリュームの中心にテスターをあて、電圧を測ります。もっとも右にまわして1.5Vくらいのはずです。
最大にすると結構発熱するので、4401モーターを使っている限りにおいては、中間(0.7Vくらい?)にしておいたほうがいいと思います。
MS0, MS1, MS2はドライブの精度をあげる場合に設定しますが、今回は回転数で数えるくらいの精度でいいので全部LOWにします。
なお、すべてのロジックは5V仕様となります。
ドローン系(Raspberry PI)は3.3V仕様ですから、接続時に5V-3.3Vのレベルコンバーターを挟む必要がありますが、以下のようにUSBインターフェースを使えば、そんな悩みはないです。
GRBL使っていた時にはArduinoとコントローラーのボードのピン配列なんか考えずに、言われたとおり繋いでいればよかったんですが、自分でコード書くならばそうもいきません。
とはいってもシールドのピンレイアウトは比較的どうでもいいです。
大事なものはこれ。
ここEnable, Direction, Stepが重要なピンです。
しかし!ここにはX,Y,ZしかなくAドライブについてはポートがありません!
それはこの動画(https://www.youtube.com/watch?v=UZcyh9qgwyQにあるとおり、
とジャンパーすればXドライブと同じようにAドライブは動くのです。
Aドライブはあくまでもフォロワーとして動くのですね。
なお、モーターケーブルの差し込みはこのとおり。
モーターテスト
ボードに12V電源を繋いで、
Arduinoプログラムでのピンの定義
const int stepXPin = 2; //X-軸 ステップ
const int stepYPin = 3; //Y.軸 ステップ
const int stepZPin = 4; //Z.軸 ステップ
const int dirXPin = 5; // X-軸 方向 1-CW 0-CCW
const int dirYPin = 6; // Y-軸 方向
const int dirZPin = 7; // z-軸 方向
const int enPin=8; // スピンドル エネイブル
とりあえずX軸用モーターが回るプログラム
const int stepXPin = 2; //X-軸 ステップ
const int stepYPin = 3; //Y.軸 ステップ
const int stepZPin = 4; //Z.軸 ステップ
const int dirXPin = 5; // X-軸 方向 1-CW 0-CCW
const int dirYPin = 6; // Y-軸 方向
const int dirZPin = 7; // z-軸 方向
const int enPin=8; // スピンドル エネイブル
const int stepsPerRev=200; // 200カウントで1回転
int pulseWidthMicros = 100; // microseconds パルス幅
int millisBtwnSteps = 1000; // 動作待ち時間
boolean direction = HIGH;
void setup() {
Serial.begin(9600);
pinMode(stepXPin, OUTPUT);
pinMode(stepYPin, OUTPUT);
pinMode(stepZPin, OUTPUT);
pinMode(dirXPin, OUTPUT);
pinMode(dirYPin, OUTPUT);
pinMode(dirZPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
Serial.println("End of Initialization");
}
void loop() {
// directionのロジックはわかりやすくするためダサダサです。
if (direction == HIGH){
digitalWrite(dirXPin, HIGH); // CW
direction = LOW;
} else {
digitalWrite(dirXPin, LOW);
direction = HIGH;
}
delay(100);
for (int i = 0; i < stepsPerRev; i++) {
digitalWrite(stepXPin, HIGH);
delayMicroseconds(pulseWidthMicros);
digitalWrite(stepXPin, LOW);
delayMicroseconds(millisBtwnSteps);
}
delay(1000);
}
高度化させるためにいろいろなステッピングモーターコントロールプログラムを調べました。
困ったことにオープンソースの3DプリンターやCNCはモーターを一時点でひとつしか動かさないようで、stepperdriverやAccelStepperといったライブラリーは連続してモーターを回せない(360度回すと一瞬止まる)し動きがカクカク、同時に複数のモーターを動かせないようです。(なにか方法があるかもしれません。)
単なる昇降なので、自前でコードを書くほうがわかりやすく安心です。
単体ドライブのコードとの違いはdelayです。delaymaicrosecondsで待つと、モーター4台が同時に回りません。おかしな動きをします。
上の方法を拡張した次をみてください。
/* * X,Y,Z stepper Motor test * A Stepper should be controlled by jumper pins. * by Tsukasa Takao 2023 */ const int stepXPin = 2; //X-軸 ステップ const int stepYPin = 3; //Y.軸 ステップ const int stepZPin = 4; //Z.軸 ステップ const int dirXPin = 5; // X-軸 方向 1-CW 0-CCW const int dirYPin = 6; // Y-軸 方向 const int dirZPin = 7; // z-軸 方向 const int enPin=8; // スピンドル エネイブル const int stepsPerRev=200; // 200カウントで1回転 int pulseWidth = 3; // ミリで十分。microsecondsは駄目 void setup() { Serial.begin(9600); pinMode(stepXPin, OUTPUT); pinMode(stepYPin, OUTPUT); pinMode(stepZPin, OUTPUT); pinMode(dirXPin, OUTPUT); pinMode(dirYPin, OUTPUT); pinMode(dirZPin, OUTPUT); pinMode(enPin, OUTPUT); digitalWrite(enPin, LOW); Serial.println("End of Initialization"); } void rotate(int count){ Serial.println("Start Rotation"); for (int i = 0; i < stepsPerRev*count; i++) { digitalWrite(stepXPin, HIGH); digitalWrite(stepYPin, HIGH); digitalWrite(stepZPin, HIGH); delay(pulseWidth); digitalWrite(stepXPin, LOW); digitalWrite(stepYPin, LOW); digitalWrite(stepZPin, LOW); delay(pulseWidth); } Serial.println("End Rotation"); } void moveDown(){ digitalWrite(dirXPin, HIGH); digitalWrite(dirYPin, LOW); digitalWrite(dirZPin, HIGH); rotate(10); } void moveUp(){ digitalWrite(dirXPin, LOW); digitalWrite(dirYPin, HIGH); digitalWrite(dirZPin, LOW); rotate(10); } void loop() { moveDown(); delay(1000); moveUp(); delay(1000); }
いろいろ調べても同時にステッピングモーターを回したい人はあまりいないらしく、おかしな動きも自己解決するしかありませんでした。
*長いので続きは次の投稿で