以前に報告した、赤道儀用のモータードライバであるが、望遠鏡を東西に移動させるときに恒星時運転から、ステップレートを変えるには、タイマーのレートを変更して行っている。この方法は、20年以上も前に、M6800マイコンでモータードライバを製作したときから採用している実績あるやりかたである。
モータードライバのICがマイコン側からマイクロステップの分割モードを変更できるように配線したので、タイマーレートを一定にして、マイクロステップ分割モードの変更により、ステッピングモーターの速度を変更する方法を試してみた。
再度、必要とされるパルスレートを検討してみると、
・平均恒星時 86146秒
・メインウォームギア歯数 500
・サブウォームギア歯数 30
・Motor Step数 200
として、ステップモーターを ドライバIC A4988のMAX マイクロステップ 1/16で駆動するものとすると、
500×30×200×16 ÷ 86146 = 557.19 Hz
すなわち、周期 1.7947msのパルスとなる。
このレートで運転して、微動のコマンドの時には、マイクロステップレートを1/8に設定すれば、倍速で動作し、早送りのときには、ステップレートを1/1にすることにより、16倍のスピードでモーターを駆動することができる。
この方法の良いところは、恒星時運転を動作の細かな 1/16マイクロステップで動作させることができることだ。また、FF時にはより強いパワーでMOTORを回すことができる。設定レートが限られてしまうが、タイマーセッティングと併用すれば、希望の速度で駆動することができるが、実際にはそんなに必要ないと思う。
変更した回路図は以下のとおり。
IOポートの接続がきれいな並びでないのは、配線変更の容易さを優先したため。あと、SLEEP端子は、Pullupとした。
これにあわせて変更した Arduino のスケッチ(プログラム)は以下のとおり。
簡単に解説すると、
・setup()
タイマーやIOポート割付、初期設定を行っている
・loop()
KeyPadの状態を読み込んで、Keyに対応した、移動方向、スピードの設定を行っている。スピードは、モータードライバのMS1~MS3を設定することで行う。
・ISR(timer1Event)
タイマー割り込み処理ルーチンで、Stepパルスの発生、タイマーの再設定を行っている。ルーチンのTOPでパルスを出力するように変更した。
//****************************************************************
#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 MS1 4 // Port D D4 Output
#define MS2 5 // Port D D5 Output
#define MS3 3 // Port D D3 Output
#define Step 6 // Port D D6 Output
#define Direction 7 // Port D D7 Output
byte StepState,ReadKey;
int EastKey,WestKey,FFKey;
long BaseRate;
void setup()
{
pinMode(LED, OUTPUT);
pinMode(Step,OUTPUT);
pinMode(Direction,OUTPUT);
pinMode(MS1,OUTPUT);
pinMode(MS2,OUTPUT);
pinMode(MS3,OUTPUT);
pinMode(Reset,OUTPUT);
pinMode(West,INPUT_PULLUP);
pinMode(East,INPUT_PULLUP);
pinMode(FF,INPUT_PULLUP);
// Disable Arduino's default millisecond counter (from now on, millis(), micros(),
// delay() and delayMicroseconds() will not work)
disableMillis();
StepState = 0; // Set Step Pulse LOW
digitalWrite(MS1,HIGH); // Microstep Rate = 1/16
digitalWrite(MS2,HIGH);
digitalWrite(MS3,HIGH);
digitalWrite(Reset,LOW); // Rest Motor Driver
digitalWrite(Reset,HIGH);
// Base Step Drive Clock
// Main worm gear teeth = 500 , Sub worm gear teeth = 30 , Step Step = 200 , Micro Step Rate = 16
// Sidereal = 86146 sec
// Pulse rate = 500 x 30 x 200 x 16 / 86146 = 557.19 Hz ( 1.7947 msec )
// For 50% Duty 897 usec
BaseRate = 897;
startTimer1(BaseRate); // Set timer 7.178 msec interval
}
void loop()
{ // Sens Key Pad and Set Data
ReadKey = PINB; // Read Key Pad data
ReadKey = ReadKey & B0011100; // Mask anather bit
switch(ReadKey){
case B00001100: // Go West Guide
digitalWrite(MS1,LOW); // Microstep Rate = 1/8
digitalWrite(MS2,HIGH);
digitalWrite(MS3,HIGH);
digitalWrite(Direction,HIGH);
break;
case B00010100: // Go East Guide
digitalWrite(MS1,LOW); // Microstep Rate = 1/8
digitalWrite(MS2,HIGH);
digitalWrite(MS3,HIGH);
digitalWrite(Direction,LOW);
break;
case B00001000: // Go FF West
digitalWrite(MS1,LOW); // Microstep Rate = 1/1
digitalWrite(MS2,LOW);
digitalWrite(MS3,LOW);
digitalWrite(Direction,HIGH);
break;
case B00010000: // Go FF East
digitalWrite(MS1,LOW); // Microstep Rate = 1/1
digitalWrite(MS2,LOW);
digitalWrite(MS3,LOW);
digitalWrite(Direction,LOW);
break;
default: // Normal West
digitalWrite(MS1,HIGH); // Microstep Rate = 1/16
digitalWrite(MS2,HIGH);
digitalWrite(MS3,HIGH);
digitalWrite(Direction,HIGH);
}
}
// Timer Inerrupt Handler
ISR(timer1Event)
{ // Reset Timer1 (resetTimer1 should be the first operation for better timer precision)
digitalWrite(Step, StepState); // Set Step Pulse
startTimer1(BaseRate); // Restart Timer
resetTimer1();
StepState ^= 1; // Toggle Step's state For Step Drive Pulse
}