2022/02/19

G-5500DCコントローラーを作ってみた

G-5500DCを便利に使うべく、インターフェースボックスを作りました。

できること

  • 角度のデジタル表示
  • AZ/ELのプリセット動作
  • PCからのコントロール (SatPC32)

今までは、リグだけはPC任せで、ペン、パドル、EL、AZの操作をしてましたが、
手放し/目線を反らさずSat通信ができるようになりました😃

動画をTwitterに投稿したところ・・・、


回路図/ソフトを希望されている方から返信をいただきました。


趣味が仕事になると楽しくなくなるので、無料で公開します。
ハードを作って、Arduino IDEでソースを書き込んでもらえば動きます。

  • シリアル通信はPC→本機の方向の通信のみで、PCへのデータ送信はありません。
  • 必要に応じてソースの改造をしてみてください。
  • ハード故障や事故には対応しません。自己責任でお願いします。

中身 (ケースはYM-150)


回路図


ソース (Arduino IDEにコピペして書き込んでください。)

//
//  G-5500DC controller V1.1 - (c) JM2FCJ 2022
//  1.0 -> 1.1
//  シリアル実装
//

#include <Wire.h>
#define OLED_ADRS 0x3C

// OLED command
int DisplayON = 0x0F;
int ClearDisplay = 0x01;
int ReturnHome = 0x02;
int CursoleOff = 0x0C;

// DIO
int s4Pin = 5;      // 黒スイッチ:   no assign
int s2Pin = 3;      // 白1スイッチ:  Flip Mode
int s3Pin = 4;      // 白2スイッチ:  Remote Mode
int s1Pin = 2;      // 赤スイッチ:   ALL STOP
int s5Pin = 6;      // Presetスイッチ
int s5LEDPin = 7;   // PresetスイッチのLED
int ELDownPin = 8;  // G-5500DC EL down
int ELUpPin = 9;    // G-5500DC EL up
int AZCCWPin = 10;  // G-5500DC AZ CCW
int AZCWPin = 11;   // G-5500DC AZ CW

// ADC
int ELVRPin = 0;    // ADC EL VR
int AZVRPin = 1;    // ACD AZ VR
int ELPOSPin = 2;   // ADC G-5500DC EL
int AZPOSPin = 3;   // ADC G-5500DC AZ

int ELVR = 0;
int AZVR = 0;
int ELPOS = 0;
int AZPOS = 0;

int SerTargetEL = 0;
int SerTargetAZ = 0;

int FlipMode = 0;
int RemoteMode = 0;
int PresetMode = 0;
char* GotoEL = "   ";
char* GotoAZ = "   ";

char L1[20] = "";   // OLED 1行目
char L2[20] = "";   // OLED 2行目


void setup() {
  pinMode(s1Pin, INPUT);
  pinMode(s2Pin, INPUT);
  pinMode(s3Pin, INPUT);
  pinMode(s4Pin, INPUT);
  pinMode(s5Pin, INPUT);
  pinMode(s5LEDPin, OUTPUT);
  pinMode(ELDownPin, OUTPUT);
  pinMode(ELUpPin, OUTPUT);
  pinMode(AZCCWPin, OUTPUT);
  pinMode(AZCWPin, OUTPUT);

  Wire.begin();   // I2C init
  init_oled();

  Serial.begin(9600);
  Serial.setTimeout(100);

  attachInterrupt(0, allstop, FALLING);
}


void loop() {
  char SerAZ[3];
  char SerEL[3];
  
  ELVR = analogRead(ELVRPin) * 180.0 / 1023.0;
  AZVR = analogRead(AZVRPin) * 450.0 / 1023.0;
  ELPOS = (analogRead(ELPOSPin) - 27) * 180.0 / 890.0;
  AZPOS = (analogRead(AZPOSPin) - 13) * 450.0 / 907.0;

  delay(100);

  if(RemoteMode == 1){
    PresetMode = 0;
    digitalWrite(s5LEDPin, LOW);
    
    FlipMode = 0;
    
    if(Serial.findUntil("W", "W")){
      delay(10);
      SerAZ[0] = Serial.read();
      delay(1);
      SerAZ[1] = Serial.read();
      delay(1);
      SerAZ[2] = Serial.read();
      delay(1);
      SerEL[0] = Serial.read(); // スペースを読み飛ばすため必要
      delay(1);
      SerEL[0] = Serial.read();
      delay(1);
      SerEL[1] = Serial.read();
      delay(1);
      SerEL[2] = Serial.read();

      if(SerAZ[0] != 0){
        SerTargetAZ = (SerAZ[0]-48) * 100 + (SerAZ[1]-48) * 10 + (SerAZ[2]-48) * 1;
        SerTargetEL = (SerEL[0]-48) * 100 + (SerEL[1]-48) * 10 + (SerEL[2]-48) * 1;
      }
      else{
        SerTargetAZ = 0;
        SerTargetEL = 0;
      }

      sprintf(L1, "ELr %3d  AZr %3d ", SerTargetEL, SerTargetAZ);
      writeCommand(0x80);
      for(int i=0; i<20; i++){
        writeData(L1[i]);
      }
    }
  }
  
  if(digitalRead(s2Pin) == LOW){
    delay(50);
    if(FlipMode == 0){
      FlipMode = 1;
    }
    else{
      FlipMode = 0;
    }
  }

  if(digitalRead(s3Pin) == LOW){
    delay(50);
    if(RemoteMode == 0){
      RemoteMode = 1;

      SerTargetEL = ELPOS;
      SerTargetAZ = AZPOS;
      
      sprintf(L1, "Waiting for Data ");
      writeCommand(0x80);
      for(int i=0; i<20; i++){
        writeData(L1[i]);
      }
    }
    else{
      RemoteMode = 0;
    }
  }

  if(digitalRead(s5Pin) == LOW){
    delay(50);    // 1回押しなら、PresetMode1 角度があってもPresetを継続
    if(PresetMode == 0){
      RemoteMode = 0;
      PresetMode = 1;
      digitalWrite(s5LEDPin, HIGH);
    }
    else{
      RemoteMode = 0;
      PresetMode = 0;
      digitalWrite(s5LEDPin, LOW);
    }
    delay(1000);    // 長押しなら、PresetMode2にする 角度があったらPreset終了
    if(digitalRead(s5Pin) == LOW){
      RemoteMode = 0;
      PresetMode = 2;
      digitalWrite(s5LEDPin, HIGH);
      delay(100);
      digitalWrite(s5LEDPin, LOW);
      delay(100);
      digitalWrite(s5LEDPin, HIGH);
      delay(100);
      digitalWrite(s5LEDPin, LOW);
      delay(100);
      digitalWrite(s5LEDPin, HIGH);
      delay(100);
      digitalWrite(s5LEDPin, LOW);
      delay(100);
      digitalWrite(s5LEDPin, HIGH);
    }
  }

  if((PresetMode == 1) || (PresetMode == 2)){
    if((ELVR - ELPOS) > 0){
      digitalWrite(ELDownPin, LOW);
      digitalWrite(ELUpPin, HIGH);
      GotoEL = "Up ";
    }
    else if((ELVR - ELPOS) < 0){
      digitalWrite(ELUpPin, LOW);
      digitalWrite(ELDownPin, HIGH);
      GotoEL = "Dwn";
    }
    else{
      digitalWrite(ELUpPin, LOW);
      digitalWrite(ELDownPin, LOW);
      GotoEL = "   ";
      if(PresetMode == 2){
        if(((AZVR - AZPOS) > 1 ) || ((AZVR - AZPOS) < -1 )){    // AZがまだあっていないときはPreset継続
          ;
        }
        else{   // AZがあっていたらPresetを抜ける
          PresetMode = 0;
          digitalWrite(s5LEDPin, LOW);
        }
      }
    }
    
    if((AZVR - AZPOS) > 1){
      digitalWrite(AZCCWPin, LOW);
      digitalWrite(AZCWPin, HIGH);
      GotoAZ = "CW ";
    }
    else if((AZVR - AZPOS) < -1){
      digitalWrite(AZCWPin, LOW);
      digitalWrite(AZCCWPin, HIGH);
      GotoAZ = "CCW";
    }
    else{
      digitalWrite(AZCWPin, LOW);
      digitalWrite(AZCCWPin, LOW);
      GotoAZ = "   ";
      if(PresetMode == 2){
        if(((ELVR - ELPOS) > 0 ) || ((ELVR - ELPOS) < 0 )){   // ELがまだあっていないときはPreset継続
          ;
        }
        else{   // ELがあっていたらPresetを抜ける
          PresetMode = 0;
          digitalWrite(s5LEDPin, LOW);
        }
      }
    }
  }
  else if(RemoteMode == 1){
    if((SerTargetEL - ELPOS) > 0){
      digitalWrite(ELDownPin, LOW);
      digitalWrite(ELUpPin, HIGH);
      GotoEL = "Up ";
    }
    else if((SerTargetEL - ELPOS) < 0){
      digitalWrite(ELUpPin, LOW);
      digitalWrite(ELDownPin, HIGH);
      GotoEL = "Dwn";
    }
    else{
      digitalWrite(ELUpPin, LOW);
      digitalWrite(ELDownPin, LOW);
      GotoEL = "   ";
    }
    
    if((SerTargetAZ - AZPOS) > 1){
      digitalWrite(AZCCWPin, LOW);
      digitalWrite(AZCWPin, HIGH);
      GotoAZ = "CW ";
    }
    else if((SerTargetAZ - AZPOS) < -1){
      digitalWrite(AZCWPin, LOW);
      digitalWrite(AZCCWPin, HIGH);
      GotoAZ = "CCW";
    }
    else{
      digitalWrite(AZCWPin, LOW);
      digitalWrite(AZCCWPin, LOW);
      GotoAZ = "   ";
    }
  }
  else{
    digitalWrite(ELDownPin, LOW);
    digitalWrite(ELUpPin, LOW);
    digitalWrite(AZCCWPin, LOW);
    digitalWrite(AZCWPin, LOW);
    GotoEL = "   ";
    GotoAZ = "   ";
  }

  if(FlipMode == 0){
    sprintf(L1, "EL  %3d  AZ  %3d ", ELVR, AZVR);
    if((ELPOS < -3) && (AZPOS < -3)){
      sprintf(L2, "Rotor - offline  ");
      RemoteMode = 0;
    }
    else{
      sprintf(L2, "%s %3d  %s %3d ", GotoEL, ELPOS, GotoAZ, AZPOS);
    }
  }
  else{
    if(AZPOS < 180){
      AZPOS = AZPOS + 180;
    }
    else{
      AZPOS = AZPOS - 180;
    }
    
    if(AZVR < 180){
      AZVR = AZVR + 180;
    }
    else{
      AZVR = AZVR - 180;
    }
    
    sprintf(L1, "EL* %3d  AZ* %3d ", -(ELVR - 180), AZVR);
    if(((ELPOS - 180) < -3) && ((AZPOS - 180) < -3)){
      sprintf(L2, "Rotor - offline  ");
    }
    else{
      sprintf(L2, "%s %3d  %s %3d ", GotoEL, -(ELPOS -180), GotoAZ, AZPOS);
    }
  }

  if(RemoteMode == 0){
    writeCommand(0x80);
    for(int i=0; i<20; i++){
      writeData(L1[i]);
    }
  }

  writeCommand(0x20+0x80);
  for(int i=0; i<20; i++){
    writeData(L2[i]);
  }

  contrast_max();
}


void allstop(){
  RemoteMode = 0;
  PresetMode = 0;
  FlipMode = 0;
  
  digitalWrite(s5LEDPin, LOW);
  
  digitalWrite(ELDownPin, LOW);
  digitalWrite(ELUpPin, LOW);
  digitalWrite(AZCCWPin, LOW);
  digitalWrite(AZCWPin, LOW);
}


void writeData(byte t_data)
{
  Wire.beginTransmission(OLED_ADRS);
  Wire.write(0x40);
  Wire.write(t_data);
  Wire.endTransmission();
  delay(1);
}


void writeCommand(byte t_command)
{
  Wire.beginTransmission(OLED_ADRS);
  Wire.write(0x00);
  Wire.write(t_command);
  Wire.endTransmission();
  delay(1);
}


void contrast_max()
{
  writeCommand(0x2a);
  writeCommand(0x79);
  writeCommand(0x81);
  writeCommand(0xFF);
  writeCommand(0x78);
  writeCommand(0x28);
  delay(1);
}


void init_oled()
{
  delay(100);
  writeCommand(ClearDisplay);
  delay(20);
  writeCommand(ReturnHome);
  delay(20);
  writeCommand(DisplayON);
  delay(20);
  writeCommand(ClearDisplay);
  delay(20);
  writeCommand(CursoleOff);
  delay(20);
}  

0 件のコメント:

コメントを投稿

AO-109の思い出

少し前に大気圏に再突入したAO-109の思い出を少し。 調べてみたら、2 QSOしかしてません。 一回目のQSOは、2021/12/18にJK1AFZさんとFT4にて。 AO-109 QSO FT4 JM2FCJ. TNX!! やっと!AO-109で初めてQSO出来た!FCJさん...