購入したもの
Amazonで格安のステッピングモータを購入して、とりあえず簡単に制御してみたのでその際のメモです。
購入したものは、ステッピングモータ+ 28BYJ-48 ULN2003ドライバーボード セットです。
私が購入したタイミング(2022/8/1)では699円でした。
3つ入りなので1つあたり250円弱。ドライバーボードもセットなので、ちゃんと動くのであれば格安ですね。
環境
・Arduino:私の場合はESP8266を使用しましたが、Arduinoであればピン番号だけ読み替えてもらえれば基本同じだと思います。
・端末:Windows10
物理的な接続
ULN2003ドライバーボードとESP8266は以下のように接続しました。
特に意味は無く、開発ボードの隣り合わせた4つの端子を選んだだけです。
IN1 ・・・ GPIO16
IN2 ・・・ GPIO14
IN3 ・・・ GPIO12
IN4 ・・・ GPIO13
+ ・・・ 5V電源の+
- ・・・ 5V電源の-
念のため電源は別のUSBから取りました。
使用したライブラリ
最初はStepperというライブラリを試していたのですが、なぜかうまく制御することができず、
代わりにCheapStepperというライブラリを使用しました。
ライブラリの説明にも”An Arduino library for the 28BYJ-48 stepper motor using ULN2003 driver board”と記載されていたので、ぴったりなのかなと思いました。
スケッチ
とりあえず動作させてみるスケッチ
#include <CheapStepper.h>
const int A = 16; //IN1
const int B = 14; //IN2
const int C = 12; //IN3
const int D = 13; //IN4
CheapStepper stepper (A, B, C, D);
void setup() {
stepper.setRpm(12); // sets speed (10-24 rpm, hi-low torque)
// <6 rpm blocked in code, may overheat
// 23-24rpm may skip
}
void loop() {
stepper.moveDegreesCW (60); // 時計回りに60°回転
delay(1000);
stepper.moveDegreesCCW (30); // 反時計回りに30°回転
delay(1000);
}
これだけで簡単に任意の方向に任意の角度回転させることができました。
ただし、原因は不明ですが
stepper.moveDegreesCW (180);
のように回転角を大きくすると、私の使用していたESP8266は頻繁に再起動を繰り返してしまいました。
小さい回転角を連続で繰り返す(例えば15度を12回連続動作させる)場合は問題無いので良いのですが少し気持ち悪いです。
原因の特定・対処ができれば追記します。
時計の秒針のような動きを再現する例
ステッピングモータの動作時間に影響されずに定期的なタイミングで次の動作指定ができるように少し工夫しました。
具体的には、
- 最初に、変数 $prev$ に0を代入(初期化)
- $millis()$ でArduinoの起動からの経過時間を知り、それを変数 $curr$ に代入
- $curr$ - $prev$ が目的の実行周期以上になるまで待つ
- ステッピングモータを動作させる
- $prev$ に $curr$ を代入する
- 2.に戻る
注意点として、実行周期(変数 $interval$)は、4.で指示するステッピングモータの動作に必要な時間よりも長く設定する必要があります。
#include <CheapStepper.h>
const int A = 16; //IN1
const int B = 14; //IN2
const int C = 12; //IN3
const int D = 13; //IN4
CheapStepper stepper (A, B, C, D);
unsigned long prev, next, interval;
void setup() {
stepper.setRpm(12); // sets speed (10-24 rpm, hi-low torque)
// <6 rpm blocked in code, may overheat
// 23-24rpm may skip
prev = 0; // 前回実行時刻を初期化
interval = 1000; // 実行周期を設定
}
void loop() {
unsigned long curr = millis(); // 現在時刻を取得
if ((curr - prev) >= interval) { // 前回実行時刻から実行周期以上経過していたら
stepper.moveDegreesCCW (6); // 6°(1秒分)回る
prev = curr; // 前回実行時刻を現在時刻で更新
}
}
今後
とりあえずこれで時計を作成してみようかなと思います。
できればNTP時計を作りたいのですが、ステッピングモータは現状の回転位置を知ることができないので、何か手立てを考えなければいけませんね。