前回の、古い赤道儀用のモータードライバの詳細である。
このような需要がどの程度あるのか分からないが、自作するひとの参考まで。
回路は以下のとおり。
Arduino Uno互換ボード(Aitendoの「びんぼうでいいの」を使用)にA4988マクロステップMOTOR DRIVER基板を接続しただけのものである。あと、E/W方向、スピードコントロールのスイッチを接続。
A4988基板の/RESET、/SLEEP端子も接続してあるが、天文用途では、ほぼ必要ないため、Pull Upでも良いと思う。最初、この端子は内部で Pull Up されていると思い、開放にしておいたところ、誤動作したため、Arduinoに接続した。
マイクロステップのレートを設定する MS1~MS3は使用するレートをソフトで変更しないのなら、希望するところで、H/Lを設定するかDIP SWを使うことも有りだろう。
電源は、手持ちの18V2Aのものを使用した。秋葉原には、ノートPC用の15~20Vの電源が大量に安価に出回っているので、それを利用するのも手である。
Arduino の電源もこれから供給するようにする。電圧が高すぎるので、抵抗を入れて10V程度にドロップさせている。
PCとArduinoをUSBケーブルで接続したときに、PC側からも5V電源が供給されて具合が悪いので、プログラミング・デバッグのときには、+5VラインをカットしたUSBケーブルを使用する。
Arduino 用のプログラム(スケッチというらしい)は以下のとおり。本体は全部で100行くらいの簡単なものである。マイクロ秒のタイミングが必要なため、Timer1というライブラリを使用する。以下、プログラムの簡単な説明。
・setup()
変数の定義、I/Oポートやタイマーの初期設定を行って、タイマーを起動する。
初期値は、前回計算した恒星時運転 69.65Hz で、50% Duty パルスとなるように、7128 μsecごとのタイマー割り込みをセットする。
モーターのマイクロステップレートは、MS1=H、MS2=L、MS3=Lでハーフステップ 1-2相励磁モードである。
・loop()
くりかえしの動作が行われるセクション。
E/W、スピードのスイッチが接続されているポートを読み込み、それらの状態によって、駆動パルスのレート、方向を設定する。E/Wキーのときには、恒星時の2倍、FFキーと同時に押されたときには、10倍の値となるようにしてある。この値が適当かどうか、実際の望遠鏡で確認する予定。
・ISR(timer1Event)
timer1がカウントアップしたときに、割り込みが発生して、ここのプロシージャーが実行され、モーター駆動タイミングパルス、方向信号を発生させる。
再度 timer1へ書き込むとき値 Rate は、loop()でキーの状態によって設定されており、そのタイミングで運転パルスを発生させることができる。
このアルゴリズムは、PICで作ったモータードライバでも採用しており実績のあるものなのだが、処理を次の割り込みまでに終わらなければならないので、あまり早いスピードでは動作させることができない。実験では、50倍速までOKであった。
今日、散歩しているときの思いついたのだが、スピードを変更するのに、パルスレートを変更するのでなく、マイクロステップレートを変更するのが良いかも知れない。このようにすることにより、恒星時運転では、滑らかな運転、高速時にはパワーのある運転に自動的に変わる、ということが期待できそうだ。
#include <Timer1.h>
//******************************************************************
// ATmega168, ATmega328:
// - Using Timer 1 disables PWM (analogWrite) on pins 9 and 10
//******************************************************************
// Pin 13 has a LED connected on most Arduino boards
#define LED 13
#define West 12 // Port B D12 Input
#define East 11 // Port B D11 Input
#define FF 10 // Port B D10 Input
#define Reset 2 // Port D D2 Output
#define Sleep 3 // Port D D3 Output
#define MS1 4 // Port D D7 Output
#define MS2 5 // Port D D6 Output
#define Step 6 // Port D D5 Output
#define Direction 7 // Port D D4 Output
byte StepState,ReadKey;
boolean Dir;
int EastKey,WestKey,FFKey;
long Rate,BaseRate;
void setup()
{
pinMode(LED, OUTPUT);
pinMode(Step,OUTPUT);
pinMode(Direction,OUTPUT);
pinMode(MS1,OUTPUT);
pinMode(MS2,OUTPUT);
pinMode(Reset,OUTPUT);
pinMode(Sleep,OUTPUT);
pinMode(West,INPUT_PULLUP);
pinMode(East,INPUT_PULLUP);
pinMode(FF,INPUT_PULLUP);
StepState = 0;
// Disable Arduino's default millisecond counter (from now on, millis(), micros(),
// delay() and delayMicroseconds() will not work)
disableMillis();
// Prepare Timer1 to send notifications every 7.18msec
//
// Base Step Drive Clock
// Main worm gear teeth=500,Sub worm gear teeth=30,Step Step =200,Micro Step Rate=2
// Sidereal = 86146 sec
// Pulse rate = 500 x 30 x 200 x 2 / 86146 = 69.65 Hz
// For 50% Duty 7.18 msec
BaseRate = 7128;
startTimer1(BaseRate); // Set timer 7.178 msec interval
digitalWrite(MS1,HIGH);
digitalWrite(MS2,LOW);
digitalWrite(Sleep,HIGH);
digitalWrite(Reset,LOW);
digitalWrite(Reset,HIGH);
}
void loop()
{
ReadKey = PINB;
ReadKey = ReadKey & B0011100; //
switch(ReadKey){
case B00001100: // Go West
Rate = BaseRate / 2;
Dir = HIGH;
break;
case B00010100: // Go East
Rate = BaseRate / 2;
Dir = LOW;
break;
case B00001000: // Go FF West
Rate = BaseRate / 10;
Dir = HIGH;
break;
case B00010000: // Go FF East
Rate = BaseRate / 10;
Dir = LOW;
break;
default:
Rate = BaseRate;
Dir = HIGH;
}
}
// Timer Inerrupt Handler
ISR(timer1Event)
{// Reset Timer1 (resetTimer1 should be the first operation for better timer precision)
startTimer1(Rate);
resetTimer1();
digitalWrite(Direction,Dir);
// Toggle Step's state For Step Drive Pulse
StepState ^= 1;
digitalWrite(Step, StepState);
}