2012年8月4日土曜日

EM200B 導入支援装置自作(5) -Arduinoプログラミング-

先日Arduinoを購入したのには、プログラミングがしやすそうなことと、もう既にArduinoをつかって導入支援装置を作っている方がおり、そのプログラムが公開されているからです。
Arduinoのプログラムはsetup()とloop()がエントリーポイントとして用意されており、setup()で初期化、loop()でループ処理を書けばOKです。しかし、ロータリーエンコーダの変化の取得は当然ながら割り込みで処理すべきであり、公開されている方のソースもそのように書かれています。

まずはこのプログラムを利用させてもらい、エンコーダのパルスを拾ってみます。
// DSC01
#include 
#include 

const int    RA_enc_A  = 6;     // digital pin 6 = PD6
const int    RA_enc_B  = 7;     // digital pin 7 = PD7
const int    DEC_enc_A = 9;     // digital pin 9 = PB1
const int    DEC_enc_B = 10;    // digital pin 10 = PB2
const double RA_RES    = 500 * 2 * 44.0 / 11.0; // RA  500P/R * 4(A/B相) * (大プーリ歯数) / (小プーリ歯数)
const double DEC_RES   = 500 * 2 * 40.0 / 11.0; // DEC 500P/R * 4(A/B相) * (大プーリ歯数) / (小プーリ歯数)
long         DEC_pos   = DEC_RES/2; // initial position of encoders(DEC)
long         RA_pos    = RA_RES/2; // initial position of encoders(RA)

void setup()
{
  Serial.begin(9600);
  // initialize the encoder inputs
  pinMode(DEC_enc_A, INPUT);
  pinMode(DEC_enc_B, INPUT);
  pinMode(RA_enc_A , INPUT);
  pinMode(RA_enc_B , INPUT);

  // Pin change interrupt control register - enables interrupt vectors
  //  Bit 2 = enable PC vector 2 (PCINT23..16)
  //  Bit 1 = enable PC vector 1 (PCINT14..8)
  //  Bit 0 = enable PC vector 0 (PCINT7..0)
  PCICR |= (1 << PCIE2);
  PCICR |= (1 << PCIE0);

  // Pin change mask registers decide which pins are enabled as triggers
  PCMSK2 |= (1 << PCINT23);  // arduino pin 7 = PD7 = RA  encoder A
  PCMSK0 |= (1 << PCINT1);   // arduino pin 9 = PB1 = DEC encoder A 

  // enable interrupts
  interrupts();
}

void loop()
{
  delay(500);
  Serial.print(RA_pos, DEC) ; Serial.print(" "); Serial.println(DEC_pos, DEC);
}

ISR(PCINT2_vect){ 
  if (digitalRead(RA_enc_A) == digitalRead(RA_enc_B)) {
    --RA_pos;
    if (RA_pos < 0) {
      RA_pos = RA_RES - 1;
    }
  }
  else {
    ++RA_pos;
    if (RA_pos >= RA_RES) {
      RA_pos = 0;
    }
  } 
}

ISR(PCINT0_vect){
  if (digitalRead(DEC_enc_A) == digitalRead(DEC_enc_B))
  {
    ++DEC_pos;
    if (DEC_pos >= DEC_RES) {
      DEC_pos = 0;
    }
  }
  else
  {
    --DEC_pos;
    if (DEC_pos < 0) {
      DEC_pos = DEC_RES - 1;
    }
}

これで、500ms間隔にSerialPortに対してRA/DECのパルスカウントを表示するはずです。

おっと、このプログラムを走らせるために組んだ回路を公開するのを忘れていました。また次回にでも回路を公開します。

最終的には、Stellariumのプラグインまで作成しし、Stellarium上に現在望遠鏡が向いている方向のレチクル表示が出来ればいいのですが、結構面倒です。一旦キャリブレーションさえ出来れば、あとは単体だけでRA/DECの表示が出来ればそれでも十分なので、座標表示のためのLCDと時刻取得のためにRTCを搭載する予定です。

0 件のコメント:

コメントを投稿