2014年12月29日月曜日

Arduino AD9834 DDS VFO

 AD9850 DDS VFOの移植版。LCDはI2Cによる通信方式を採用。秋月電子のArduino用ユニバーサル基板で組んでみたが、使い勝手がとても良かった。また、プログラムは、7Mhz用としたので、AD9850の表示と全く同じ。(写真は割愛)
AD9834の出力は、バッファアンプ付とした。出力は、  7Mhz 3mW、17Mhz 1.8mW で、次段ドライブには十分。ArduinoのDC端子電圧は、8V位が適正値。(電圧が高い場合、Arduinoのレギュレター発熱大)












Program

Arduino AD9850 DDS VFOと基本的に同じだが、LCD表示のI2C化、AD9834固有部分の変更修正を行った。DDS通信部Fnc_ddsは、MSBFIRSTへの変更とdigitalWrite(SCLK,HIGH)の追加である。特に、SCLK HIGHが無いと全く通信しないので、要注意だ。また、機能はAD9850版と同一。

//////////////////////////////////////////////////////////////////////
//  AD9834 DDS VFO Premixed type program ver.1.0
//
//    Copyright(C)2014.JA2GQP.All rights reserved.
//
//      7.000MHz to 7.200MHz Limitted.
//      (Target frequency = IF frquency + frequency)
//                                                  2014/12/29
//                                                  JA2GQP
//--------------------------------------------------------------------
//  Function
//    1.Upper Heterodyne(Target Frequency = IF Frequency + Frequency)
//    2.RIT Operation(-50kHZ to 50kHZ)
//    3.STEP(100k,10k,1k,100,10)
//    4.Memory Operation is Push RIT
//      (Frequency and Step)
//    5.Protection Operation At The Time Of Transmission
//    6.Channel Memory.Main Channel(Ch0) + 3 Channel(Ch1,Ch2,Ch3)
//    7.Split Operation(7.00MHz to 7.20MHz Limited!)
//
//////////////////////////////////////////////////////////////////////

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <rotary.h>
#include <EEPROM.h>

//----------  LCD Pin Assign  ------------------

LiquidCrystal_I2C lcd(0x27,16,2);     // set the LCD address to 0x27 for
                                           // a 16 chars and 2 line display

//----------  Define Constant Value   ----------
                                               
const byte  ENC_A = 2;                     // Encorder A
const byte  ENC_B = 3;                     //          B
const byte  SDATA = 4;                    // AD9834 SDATA
const byte  SCLK = 5;                      //        SCLK
const byte  FSYNC = 6;                    //        FSYNC
const byte  SW_STEP = 7;                 // STEP Sw
const byte  SW_RIT = 8;                    // RIT Sw
const byte  SW_SPLIT = 9;                // SPLIT Sw
const byte  SW_CH1 = 10;                 // Channel 1
const byte  SW_CH2 = 11;                 //         2
const byte  SW_CH3 = 12;                 //         3
const byte  SW_TX = 13;                   // TX Sw

const long  IF_FRQ = 9996500L;             // IF Frequency
const long  LW_FRQ = 7000000L;            // Lower Limit
const long  HI_FRQ = 7200000L;             // Upper Limit
const long  DEF_FRQ = 7050000L;          // Init Frequency
const long  DEF_STP = 1000L;               // Init STEP
const long  LW_RIT = -50000L;              // RIT Lower Limit
const long  HI_RIT = 50000L;                //     Upper Limit
const long  LW_VFO = IF_FRQ + LW_FRQ;    // Vfo Lower Limit
const long  HI_VFO = IF_FRQ + HI_FRQ;       //     Upper Limit
const long  DEF_VFO = IF_FRQ + DEF_FRQ;   // Vfo Default Frequency

const unsigned long  DDS_CLK = 56000000L;  // AD9834 Clock 56Mhz
const unsigned long  TWO_E28 = 268435456L; // 2^28

//----------  EEPROM Memory Address   ----------

const byte  Frq_Eep0 = 0x00;               // Frequency Ch0
const byte  Frq_Eep1 = 0x04;               //           Ch1                                              
const byte  Frq_Eep2 = 0x08;               //           Ch2
const byte  Frq_Eep3 = 0x0c;               //           Ch3

const byte  Stp_Eep0 = 0x10;               // STEP Ch0
const byte  Stp_Eep1 = 0x14;               //      Ch1                                              
const byte  Stp_Eep2 = 0x18;               //      Ch2
const byte  Stp_Eep3 = 0x1c;               //      Ch3

//----------  Encorder Pin Assign(INT)  --------

Rotary r = Rotary(ENC_A,ENC_B);            // 2 = ENC_A,3 = ENC_B

//----------  Memory Assign  -------------------

long Vfo_Dat = 0;                            // VFO Data
long Dds_Dat = 0;                            // DDS Data
long Rit_Dat = 0;                            // RIT Data
long Rit_Datb = 0;                        // RIT Data Old
long Enc_Stp = 0;                         // STEP
long Lng_Wk1 = 0;                         // Long Work1
long Lng_Wk2 = 0;                         // Long Work2

char *Lcd_Dat = "           ";            // Lcd Display Buffer

byte Byt_Chn = 0;                         // Channel SW
byte Byt_Chnb = 0;                        // Channel SW Old
byte Flg_Rit = 0;                         // RIT Flag
byte Flg_Ritb = 0;                        // RIT Flag Old
byte Flg_Tx = 0;                          // TX Flag
byte Flg_Spl = 0;                         // SPLIT Flag

//----------  Initialization  Program  ---------------

void setup(){
  lcd.init();                            // initialize the lcd
  lcd.backlight();                       // LCD backlight on

  pinMode(SW_STEP,INPUT_PULLUP);
  pinMode(SW_RIT,INPUT_PULLUP);
  pinMode(SW_SPLIT,INPUT_PULLUP);
  pinMode(SW_TX,INPUT_PULLUP);
  pinMode(SW_CH1,INPUT_PULLUP);
  pinMode(SW_CH2,INPUT_PULLUP);
  pinMode(SW_CH3,INPUT_PULLUP);

  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();                                     // INT Enable

  pinMode(FSYNC,OUTPUT);
  pinMode(SCLK,OUTPUT);
  pinMode(SDATA,OUTPUT);

  Flg_Tx = 0;
  Flg_Rit = 0;
  Flg_Spl = 0;
 
  lcd.clear();
  Fnc_Chsw();                                // Channel Sw Read
  Byt_Chnb = Byt_Chn;
  Fnc_Eep_Rd();                              // EEPROM Read
}

//----------  Main program  ---------------

void loop() {
  if(Flg_Tx == 0){                          // Tx off?
    if(digitalRead(SW_STEP) == LOW){        // STEP Sw On?
      Fnc_Stp();                            //     Yes,STEP proc.
    }
    if(digitalRead(SW_RIT) == LOW){         // RIT Sw On?
      Fnc_Rit();                            //     Yes,RIT proc.
    }
    if(digitalRead(SW_SPLIT) == LOW){       // SPLIT Sw On?
      Fnc_Spl();                            //     Yes,SPLIT proc.
    }
    Fnc_Chsw();                             // Channel Sw read
   
    if(Byt_Chnb != Byt_Chn){                // Channnel SW Chenge?
      if(Byt_Chnb == 0){                    // Channnel 0?    
        Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);     //   Yes,Vfo_Dat Save
        Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);     //       Enc_Step Save
        Flg_Ritb = Flg_Rit;
        Rit_Datb = Rit_Dat;
        Flg_Rit = 0;
        Flg_Spl = 0;
        Rit_Dat = 0;
      }
     
      if(Byt_Chnb != 0){                    // Other(Ch1-Ch3) Channnel?
        Flg_Rit = 0;
        Flg_Spl = 0;
        if((Byt_Chn == 0) && (Flg_Ritb == 1)){
          Flg_Rit = 1;
          Rit_Dat = Rit_Datb;
        }
      }
       
      Byt_Chnb = Byt_Chn;
      Fnc_Eep_Rd();
    }
  }
  if(digitalRead(SW_TX) == LOW){            // Tx On?
    Flg_Tx = 1;                             //    Yes,Flg_Tx Set
  }
  else{                                    
    Flg_Tx = 0;                            //     No,Flg_Tx Reset              
  }

  if(Flg_Rit == 1){                        // RIT?
    Dds_Dat = Vfo_Dat + Rit_Dat;           //    Yes,Dds_Dat Set
  }
  else{
    Dds_Dat = Vfo_Dat;                     //    No,Dds_Dat Set
  }

  if(Flg_Tx == 1){                         // Tx?
    if(Flg_Spl == 1){                      // SPLIT?
      Dds_Dat = Vfo_Dat + Rit_Dat;         //    Yes,Dds_Dat Set
    }
      else{
        Dds_Dat = Vfo_Dat;                 //    No,Dds_Dat Set
      }
  }
  Fnc_Dds(Dds_Dat);                        // AD9850 DDS Out
  Fnc_Lcd();                               // LCD Display
  delay(100);
}

//----------  Encorder procedure(INT)  ---------------

ISR(PCINT2_vect) {
  unsigned char result = r.process();

  if(Flg_Tx == 0){
    if(result) {  
      if(result == DIR_CW){
        Lng_Wk1 = Vfo_Dat + Enc_Stp;
        Lng_Wk2 = Rit_Dat + Enc_Stp;
      }
      else{
          Lng_Wk1 = Vfo_Dat - Enc_Stp;
          Lng_Wk2 = Rit_Dat - Enc_Stp;
      }      
      if((Flg_Rit == 1) || (Flg_Spl == 1)){
        Rit_Dat = Lng_Wk2;
      }
      else{
        Vfo_Dat = Lng_Wk1;
        Rit_Dat = 0;
      }
      Vfo_Dat = constrain(Vfo_Dat,LW_VFO,HI_VFO);

      if(Flg_Spl == 1){
        Rit_Dat = constrain(Rit_Dat,(LW_VFO - Vfo_Dat),(HI_VFO - Vfo_Dat));
      }
      else{
        Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);
      }
    }
  }
}

//----------  Function DDS set  ---------------

void Fnc_Dds(double frquency){
  unsigned long wrk = frquency * TWO_E28 / DDS_CLK;
  unsigned int wrk1,wrk2,wrk3;
 
  wrk1 = 0x2000;
  wrk2 = wrk & 0x3fff;
  wrk2 = wrk2 | 0x4000;
  wrk3 = wrk >> 14;
  wrk3 = wrk3 & 0x3fff;
  wrk3 = wrk3 | 0x4000;

  digitalWrite(SCLK,HIGH);                       // Added 2014/12/29
  digitalWrite(FSYNC,LOW);

  shiftOut(SDATA,SCLK,MSBFIRST,(wrk1 >> 8));
  shiftOut(SDATA,SCLK,MSBFIRST,wrk1);

  shiftOut(SDATA,SCLK,MSBFIRST,(wrk2 >> 8));
  shiftOut(SDATA,SCLK,MSBFIRST,wrk2);

  shiftOut(SDATA,SCLK,MSBFIRST,(wrk3 >> 8));
  shiftOut(SDATA,SCLK,MSBFIRST,wrk3);

  digitalWrite(FSYNC,HIGH);
}

//----------  Function Encorder STEP  ---------

void Fnc_Stp(){
  if(Enc_Stp == 10){                      // Step = 10Hz ?
    Enc_Stp = 100000;                     //   Yes,100khz set
    }
    else{
      Enc_Stp = Enc_Stp / 10;             // Step down 1 digit
      }
  delay(250);
  Fnc_Step_Disp();
  Fnc_Lcd();
  while(digitalRead(SW_STEP) == LOW)
    ;
  delay(250);
}

//----------  Function STEP Display  ----------

void Fnc_Step_Disp(){
  lcd.setCursor(0,1);
  lcd.print("    ");                    // Clear step display
  lcd.setCursor(0,1);
  if(1 <= (Enc_Stp / 1000)){            // kiro?        
    lcd.print(Enc_Stp / 1000);          //   Yes,Convert kiro
    lcd.print("k");
    }
    else{
      lcd.print(Enc_Stp);
      }
}

//----------  Function String Dot Edit  --------
   
char *Fnc_Dot_Edit(char *str,long n){
  int  i = 0;                           // Write the number
  char *p = str;
  unsigned long  u = abs(n);

  do{
    *p++ = "0123456789"[u % 10];
    u = u / 10;
    i++;
    if((0 != u) && (0 == (i % 3)))
      *p++ = '.';
    }
  while( 0 != u );

  if ( n < 0 )
     *p++ = '-';
   *p = '\0';
   Fnc_Revr( str );
   return str;
}

//----------  Function String Reverse  ---------

void Fnc_Revr(char *str){
  int i,n;
  char c;

  n=strlen(str);
  for(i = 0;i < n / 2;i++){
    c=str[i];
    str[i]=str[n - i - 1];
    str[n - i - 1]=c;
  }
}

//----------  Function Save EEPROM 2byte  ---------

void Fnc_Eep_Sav2(unsigned int value,int address){
  address += 1;
  for(int i = 0;i < 2;i++){
    byte toSave = value & 0xFF;
    if(EEPROM.read(address) != toSave){
      EEPROM.write(address,toSave);
      }
    value = value >> 8;
    address--;
  }
}

//----------  Function Save EEPROM 4byte  ---------

void Fnc_Eep_Sav4(long value,int address){
  address += 3;
  for(int i = 0;i < 4;i++){
    byte toSave = value & 0xFF;
    if(EEPROM.read(address) != toSave){
      EEPROM.write(address,toSave);
      }
    value = value >> 8;
    address--;
  }
}

//----------  Function Load EEPROM 2byte  ---------

unsigned int  Fnc_Eep_Lod2(int address){
  unsigned int value = EEPROM.read(address);
  value = value << 8;
  return value | EEPROM.read(address + 1);
}

//----------  Function Load EEPROM 4byte  ---------

long Fnc_Eep_Lod4(int address){
  long value = 0;
  for(int i = 0;i < 4;i++){
    value = value | EEPROM.read(address);
    if( i < 3){
      value = value << 8;
      address++;
      }
  }
  return value;
}

//----------  Function LCD Display  ---------

void Fnc_Lcd(){
  if(Flg_Tx == 1){
    lcd.setCursor(0,0);
    lcd.print("T");
  }
  else{
    lcd.setCursor(0,0);
    lcd.print(Byt_Chn);
  }
 
  Fnc_Step_Disp();

  if(Flg_Rit == 1){
    lcd.setCursor(5,1);
    lcd.print("R:          ");
    Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
    lcd.setCursor(7,1);
    lcd.print(Lcd_Dat);
    if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
     lcd.print("k");
    }
  }

  if(Flg_Spl == 1){
    lcd.setCursor(5,1);
    lcd.print("X:          ");
    Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
    lcd.setCursor(7,1);
    lcd.print(Lcd_Dat);
    if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
      lcd.print("k");
    }
  }

  if((Flg_Rit == 0) && (Flg_Spl == 0)){
    Fnc_Dot_Edit(Lcd_Dat,Vfo_Dat - IF_FRQ);
    lcd.setCursor(1,0);
    lcd.print(":              ");
    lcd.setCursor(3,0);
    lcd.print(Lcd_Dat);
    lcd.print("MHz");

    lcd.setCursor(5,1);
    lcd.print("     JA2GQP");
  }
}
 

//----------  Function Rit  ---------

void Fnc_Rit(){
  if(Flg_Rit == 0){
    Rit_Dat = 0;
    Flg_Rit = 1;
    Flg_Spl = 0;
    switch(Byt_Chn){
      case 1:
        Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
        Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
        break;
      case 2:
        Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
        Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
        break;
      case 3:
        Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
        Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
        break;
      default:
        Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
        Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
        break;
    }
  }
  else{
    Flg_Rit = 0;
  }
  while(digitalRead(SW_RIT) == LOW)
    ;
  delay(250);
}
 
//----------  Function Channel SW Check  ---------

void Fnc_Chsw(){
  if(digitalRead(SW_CH1) == LOW){
    Byt_Chn = 1;
  }
  else if(digitalRead(SW_CH2) == LOW){
    Byt_Chn = 2;
  }
  else if(digitalRead(SW_CH3) == LOW){
    Byt_Chn = 3;
  }
  else{
    Byt_Chn = 0;
  }
}

//----------  Function EEPROM Read  ---------

void Fnc_Eep_Rd(){
  if(Fnc_Eep_Lod4(Frq_Eep0) <= LW_VFO){
    Vfo_Dat = DEF_VFO;
    Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
    Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
    Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
    Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
  }
  else{
    switch(Byt_Chn){
      case 1:
        Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep1);
        break;
      case 2:
        Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep2);
        break;
      case 3:
        Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep3);
        break;
      default:
        Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep0);
        break;
    }
  }
  if(Vfo_Dat <= 0){
    Vfo_Dat = DEF_VFO;
  }
  if(Fnc_Eep_Lod4(Stp_Eep0) <= 0){
    Enc_Stp = DEF_STP;
    Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
    Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
    Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
    Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
  }
  else{
    switch(Byt_Chn){
      case 1:
        Enc_Stp = Fnc_Eep_Lod4(Stp_Eep1);
        break;
      case 2:
        Enc_Stp = Fnc_Eep_Lod4(Stp_Eep2);
        break;
      case 3:
        Enc_Stp = Fnc_Eep_Lod4(Stp_Eep3);
        break;
      default:
        Enc_Stp = Fnc_Eep_Lod4(Stp_Eep0);
        break;
    }
  }
  if(Enc_Stp <= 0){
    Enc_Stp = DEF_STP;
  }
}

//----------  Function Split  ---------

void Fnc_Spl(){
  if(Flg_Spl == 0){
    Flg_Spl = 1;
    Flg_Rit = 0;
    Rit_Dat = 0;
  }
  else{
    Flg_Spl = 0;
  }
  while(digitalRead(SW_SPLIT) == LOW)
    ;
  delay(250);
}




       

2014年12月7日日曜日

EMOTO 103LB Display

 EMOTOのローテータ表示部が壊れたため、Arduino UNOで表示部を製作した。モータコントロール部は、正常動作していたので、コントロール機能はなく、位置表示のみとした。LCDは、公開済のI2C制御方式とし、配線量を減らした。故障した103LBの機械式表示部は、全て取り外し、電源とコントロールスイッチのみ流用。
 コントローラ内部写真である。機械式表示器で使っていた、PCB、歯車、ポテンションメータなどを外し、Arduino UNOとPower PCBを組み込んだ。
   全体の回路図。I2Cを含め書いて有るので見通しが良いと思う。













Program

ローテータの位置情報(600Ωのポテンションメータ)をADCで読み、角度変換のみである。個体差が有る所は、AD値のRock to Rock(0~360°で1023~171)である。現物合わせ的な処理となっている。(やっつけ仕事)

//////////////////////////////////////////////////////////////////////
//  EMOTO 103LB control display program ver.1.0
//
//    Copyright(C)2014.JA2GQP.All rights reserved.
//
//                                                  2014/12/5
//                                                  JA2GQP
//////////////////////////////////////////////////////////////////////

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for
                                        // a 16 chars and 2 line display
int val=0;
int ang=0;
float wk1,wk2,wk3;

void setup()
{
  lcd.init();                          // initialize the lcd
  lcd.backlight();                    // LCD backlight on
  lcd.setCursor(5,1);
  lcd.print("JA2GQP");
}

void loop()
{
// analog read
  val=analogRead(0);               // Current position read
  delay(100);

// 0-360 degree convert
  wk1=val;
  wk1=1023.0-wk1;                 // AD max
  wk2=360.0/(1023.0-171.0);      // Per 1 degree resolution
  wk3=wk1*wk2;
  ang=wk3;

// angle display
  lcd.setCursor(3,0);
  lcd.print("    ");
  lcd.setCursor(3,0);
  lcd.print(ang);

// Orientation check
  switch(val){
      case 169:
      case 170:
      case 171:
      case 172:
      case 173:
        lcd.setCursor(0,0);
        lcd.print("N");
        break;
      case 276:
      case 277:
      case 278:
      case 279:
      case 280:
        lcd.setCursor(0,0);
        lcd.print("NW");
        break;
      case 382:
      case 383:
      case 384:
      case 385:
      case 386:
        lcd.setCursor(0,0);
        lcd.print("W");
        break;
      case 489:
      case 490:
      case 491:
      case 492:
      case 493:
        lcd.setCursor(0,0);
        lcd.print("SW");
        break;
      case 595:
      case 596:
      case 597:
      case 598:
      case 599:
        lcd.setCursor(0,0);
        lcd.print("S");
        break;
      case 702:
      case 703:
      case 704:
      case 705:
      case 706:
        lcd.setCursor(0,0);
        lcd.print("SE");
        break;
      case 808:
      case 809:
      case 810:
      case 811:
      case 812:
        lcd.setCursor(0,0);
        lcd.print("E");
        break;
      case 915:
      case 916:
      case 917:
      case 918:
      case 919:
        lcd.setCursor(0,0);
        lcd.print("NE");
        break;
      case 1023:
        lcd.setCursor(0,0);
        lcd.print("N");
        break;
      default:
        lcd.setCursor(0,0);
        lcd.print("   ");
  }
 
// Limit check
  switch(val){
      case 169:
      case 170:
      case 171:    
        lcd.setCursor(11,0);
        lcd.print("R-OVR");           // Right over
        break;
      case 1023:
        lcd.setCursor(11,0);
        lcd.print("L-OVR");           // Left over
        break;
      default:
        lcd.setCursor(11,0);
        lcd.print("     ");
  }

}


2014年11月11日火曜日

STM32F0 DISCOVER Case

program writerと使うべく、STM32F0ボードをケースに収納した。ケースは、秋月電子 P-00358 95x65x23である。書込み用I/Fケーブルと押しボタンSWの穴がある。
基板固定は、ホットボンドのみ。
背面の様子。    

2014年10月25日土曜日

SoftRock RxTx Ensemble Kit(2)

送信部の組み立ても終わり、自作ケースに収納した。プリント基板を使い、オリジナルを模造して艶消しの黒色塗装をした。ケースで注意すべき所は、アースによるループを作らない事だ。全てアースから浮かせてある。(オリジナルと同じ)


Softrock RxTx Ensemble 40m/30m/20mを実装した様子。

送信部組み立て後、不具合が発生し回収。
不具合
 1.PA段のバイアス電流が43mA。
    (基準値 55mA)
 2.g4zfqサイトの試験は、7.05Mhz
   500mW。(期待値 1W以上)  
不具合回収
 1.バイアス電流55mAに調整。
  (R41に100オーム並列に接続した)
 2.T3コイル巻き直し。
  (メガメコアの巻き方による)

メガネコアの巻き方


エッジを十分取り除く。
 
線を通す
 
楊枝で線を固定しながら、必要回数巻く
(前段階が省略してある)
この方法で巻けば、線を穴に密着させられるので、余裕を持って巻くことが出来る。 

結果

パワーが出なかった主原因であるT3コイル交換後、7.05Mhz 2.06W(1W位に抑えて使うのが良いと思う)であった。バイアス電流について色々議論が有るが、精神安定上、55mA±10%位の範囲内に入れば良いだろう。

2014年10月6日月曜日

SoftRock RxTx Ensemble Kit

 SDR Transceiver Kitを購入した。購入理由は、安価な事とSoftRockが多く出回っている為である。このKitをパソコンと組み合わせる事で、オールモード 1W トランシーバーとなる。Kitは、送料を含め$102.55(日本までの送料)である。支払いは、PayPal。注文して手元に届くまで、8日間であった。郵便物追跡は、US postのみ確認(国内追跡出来なかった)できた。PCB写真は、受信部まで組立てた状態(製作途中)。
 トランシーバー全体の構成。PCのサウンドボードは、入出力ともステレオ対応が条件。マイクとスピーカ用ドングルは、特に条件は無い(まだ、総合結線してないので、何とも云えないが)。この結線の通りであれば、PTTは画面のボタン操作。実用的な物とするには、多少、手を加える事も必要かと思う。












PCB処理ブロックは、この様になっている。製作に関するドキュメントは、細かく書いた物がHPにある。製作ドキュメントを読んでも、勉強になる。


2014年9月12日金曜日

Arduino I2C Module

LCDのパラレル通信をI2C通信に変換するModuleである。また、LCD自体にI2C機能を含めたModuleも販売されている様だ。I2Cを使えば、配線の省力化、I/Oポートの削減に有効である。Arduinoから簡単に使う事が出来る。BASCOMでも使えるが、FREE版ではメモリー制限によって厳しいかも知れない。入手先は、AliexpressでLCD I2Cで検索すれば、見つかる筈だ。価格は、US$1.2/piece位。 
Arduino UNOで試験をした。ライブラリー入手先が販売サイトに書かれてある。無論、Arduinoサイトからも入手できるが、販売サイトに書いて有る所から入手した。ダウンロードしたファイルに、回路図も含まれているが、入手したModuleと異なる。 
I2C Moduleから回路図にした。アドレス設定は、A0、A1、A2のパットで行う。初期値は、A0、A1、A2が全てOPENの為、27Hである。     












PROGRAM

ダウンロードしたプログラムに書いて有るアドレスは、20Hである。I2C Moduleにジャンパーをしない限り、プログラムを書き直さなければ、動作しない。この為、アドレスを27Hに書き換えた。

//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd

  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
}


2014年8月24日日曜日

50MHz AM TRX ケース

50MHz AM TRX Ver2基板をケースに収納。ケース本体は生基板で、上板と底板がアルミを使った。底板のアルミ板以外、廃材を活用。上板の共板としてPP板を使っているが、パンチングメタル材ではケースをエンクローズ出来ない為、PP板を使う事で、音質改善を行った。 
実装での問題は、マイクコードにRF回り込みが発生。基板のマイク入力部とマイクコネクタにパスコン(セラミックコンデンサ103)を追加した。この様な対策は、実装技術なので、回路図に現れなく、ビギナーを悩ませるかも知れないが、定石なので知っていても損はない。 

2014年8月2日土曜日

50MHz AM TRX Ver.2

50MHz AM TRXである。2012/12/17公開のTRXバージョンアップ版で、AD9850 DDS VFOを使い、1ボード化した物である。VFOは、7月公開したもので、LCDレス。受信部は、TA7853+LA1600ダブルスーパー。送信部は、TA7358を使い低電力変調し、RD06HVF1により最大キャリア4W(AM変調時 1Wキャリア出力)を得ている。送信部のバッファ段(2SC2053)出力側にT型フィルタを入れているが、スプリアス低減とQRPP対応(ファイナル段スキップ)である。バッファ段の出力は、最大キャリア出力(無変調)200mW~300mWあるので、AM変調時50mW~75mWである。VFOは、6m AMロールコールで使える様、チャンネルスイッチに50.55MHzと50.60MHzを設定した。VFOにLCDが無いが、何ら問題は起きてない。PCBは、数回トリミングした結果、ジャンパーが多いのが唯一不満。 
回路図である。終段RD06HVF1は、TS-590Sバッファ段を参考にし、ID=350mAで調整。NFB回路(470Ω+103)を入れているが、無しでも問題なく動作する筈だ。プロトタイプは、NFBなしで試験した。 
PCBサイズ 103×102。中央下の6φ穴で、7805をケースに固定(放熱)している。    

2014年7月8日火曜日

50MHz AM VFO


 FRQ+10.7MHzの50MHz帯AM用VFO。、公開済みAD9850 50MHz AM VFOのPCBを小型化した物で、製作中 1ボードTRXのVFO部分。LCDレスでも、プロトタイプのテスト、試験用LOとして十分かと思う。






AD9850 DDSモジュールを外した状態。

         
レギュレータ 7805は、裏側に取り付け、ケースに放熱。
回路図。IOポートは、PCBパターン引き回し都合で、変更。













PCB 42 x 67













program

AD9850 50MHz AM VFOのプログラムをLCD関連、RIT関連を削除した。これにより、メモリー機能がない。周波数データは、EEP ROMに保存しているので、メモリー機能の追加は、簡単。

'********************************************************
'AD9850 DDS VFO program ver.1.0
'  50.500Mhz to 50.700Mhz Limitted!
'  Copyright (C)2014.JA2GQP.All rights reserved.
'                                       2014/7/7
'                                           JA2GQP
' BASCOM AVR 2.0.7.5(DEMO version) Compiled
'--------------------------------------------------------
'  Function
'     1.Lower heterodyne
'     2.FRQ + 10.7MHz
'     3. Protection operation at the time of transmission
'     4.Channel ch0(50.60MHz),ch1(50.55MHz)
'********************************************************

$regfile = "m88adef.dat"
$crystal = 1000000                                          '1Mhz clock

'--- config port ---

Config Portb.0 = Output                                     'STEP LED 1k
Config Portb.1 = Input                                      'ENC B
Config Portb.2 = Input                                      'ENC A
Config Portb.3 = Input                                      'ch1
Config Portb.4 = Input                                      'STEP
Config Portb.5 = Input                                      'TX

Config Portd.0 = Output                                     'W_CLK .
Config Portd.1 = Output                                     'FQ_UD
Config Portd.2 = Output                                     'DATA
Config Portd.5 = Output                                     'Frq LED Mid .
Config Portd.6 = Output                                     'Frq LED Low
Config Portd.7 = Output                                     'Frq LED Hi

'--- port pullup ---

Portb = &B00111110                                          'Bit 1-5 pull up

'--- debounce set ---

Config Debounce = 1

'---Frequency Parameter(50.500Mhz to 50.700Mhz Limitted!)

Const If_frq = 10700000                                     'IF frequency
Const Lw_frq = 50500000                                     'Lower limit operation frequency
Const Hi_frq = 50700000                                     'Upper limit operation frequency
Const Def_frq =(lw_frq + Hi_frq) / 2                        'Operation center frequency
Const Def_frq1 = 50550000                                   'ch1=50.55MHz
Const Def_frq2 = 50600000                                   'ch0=50.60MHz

'--- constant data ---

Const Lw_vfo = Lw_frq - If_frq                              'VFO lower limit(RX)
Const Hi_vfo = Hi_frq - If_frq                              'VFO upper limit(RX)
Const Def_vfo = Def_frq - If_frq                            'VFO ch0
Const Def_vfo1 = Def_frq1 - If_frq                          'VFO ch1
Const Scal = 34.35973837                                    '2^32/125.000Mhz
Const Dds_cmd = &B00000000                                  'DDS command

'--- define subrutine ---

Declare Sub Enc_sub                                         'Encorder
Declare Sub Dds_sub                                         'DDS
Declare Sub Stp_sub                                         'STEP
Declare Sub Rx_sub                                          'RX
Declare Sub Tx_sub                                          'TX
Declare Sub Chsw_sub                                        'Channel SW check
Declare Sub Eep_rd_sub                                      'EEP read

'--- define memory ---

Dim Vfo_dat As Long                                         'VFO freqency data
Dim Dds_dat As Long                                         'DDS frequency data
Dim Sng_wrk As Single                                       'main channel
Dim Lng_wrk As Long                                         'Long work1
Dim Enc_stp As Integer                                      'Encorder step
Dim Flg_tx As Byte                                          'TX flag
Dim Frq_eep0 As Eram Long                                   'EEP frequency ch0
Dim Frq_eep1 As Eram Long                                   '              ch1
Dim Stp_eep0 As Eram Integer                                'EEP STEP ch0
Dim Stp_eep1 As Eram Integer                                '         ch1
Dim Flg_enc As Byte                                         'Encorder dir flag
Dim Byt_cmd As Byte                                         'DDS command
Dim Byt_wrk As Byte                                         'Byte work
Dim Byt_chn As Byte                                         'Channel

'--------------
'Main roution
'--------------

Main:
   Flg_tx = 0                                               'TX flag reset

   Call Chsw_sub                                            'Channel SW check
   Byt_wrk = Byt_chn
   Call Eep_rd_sub                                          'EEP initial

   Do
      If Flg_tx = 0 Then
         Debounce Pinb.2 , 0 , Enc_sub , Sub                'Encorder
         Debounce Pinb.4 , 0 , Stp_sub , Sub                'Step
         Call Chsw_sub                                      'Channel SW check

         If Byt_wrk <> Byt_chn Then
            Byt_wrk = Byt_chn
            Call Eep_rd_sub                                 'EEP load
            End If

         If Vfo_dat =< Lw_vfo Then                          'VFO lower limit check
            Vfo_dat = Lw_vfo
            Portd.6 = 1                                     'Frq LED Low on
            Else
               Portd.6 = 0
               End If

         If Vfo_dat = Def_vfo Then                          'VFO Def Frq check
            Portd.5 = 1                                     'Frq LED Mid on
            Else
               Portd.5 = 0
               End If

         If Vfo_dat >= Hi_vfo Then                          'VFO upper limit check
            Vfo_dat = Hi_vfo
            Portd.7 = 1                                     'Frq LED Hi on
            Else
               Portd.7 = 0
               End If

         If Enc_stp = 1000 Then                             'STEP LED 1k check
            Portb.0 = 1                                     'LED on
            Else
               Portb.0 = 0
               End If

         End If

      Debounce Pinb.5 , 1 , Rx_sub , Sub                    'RX
      Debounce Pinb.5 , 0 , Tx_sub , Sub                    'TX

      Dds_dat = Vfo_dat
      Call Dds_sub
   Loop
End

'-----------------------------
'Encoder check,Create DDS data
'-----------------------------

Sub Enc_sub
   If Pinb.1 = 1 Then
      Vfo_dat = Vfo_dat + Enc_stp
      Else
         Vfo_dat = Vfo_dat - Enc_stp
         End If

   If Vfo_dat =< Lw_vfo Then                                'VFO lower limit check
      Vfo_dat = Lw_vfo
      End If

   If Vfo_dat >= Hi_vfo Then                                'VFO upper limit check
      Vfo_dat = Hi_vfo
      End If
End Sub

'-----------------------------
'AD9850(DDS) Data write
'-----------------------------

Sub Dds_sub
   Sng_wrk = Dds_dat
   Lng_wrk = Sng_wrk * Scal
   Byt_cmd = Dds_cmd                                        'DDS command

   Reset Portd.1
   Shiftout Portd.2 , Portd.0 , Lng_wrk , 3
   Shiftout Portd.2 , Portd.0 , Byt_cmd , 3
   Set Portd.1
End Sub

'-----------------------------
'Step
'-----------------------------

Sub Stp_sub
   Select Case Enc_stp
      Case 10000:
         Enc_stp = 1000                                     '1k
      Case 1000:
         Enc_stp = 10000                                    '10k
         Vfo_dat = Vfo_dat + 5000                           'round 10k
         Vfo_dat = Vfo_dat \ 10000
         Vfo_dat = Vfo_dat * 10000
      Case Else:
         Enc_stp = 10000                                    '10k(initial)
         End Select
End Sub

'-----------------------------
'RX
'-----------------------------

Sub Rx_sub
   If Flg_tx = 1 Then
      Flg_tx = 0                                            'TX flag rest
      End If
End Sub

'-----------------------------
'TX
'-----------------------------

Sub Tx_sub
   If Flg_tx = 0 Then
      Flg_tx = 1                                            'TX flag set
      End If
End Sub

'-----------------------------
'Channel SW check
'-----------------------------

Sub Chsw_sub
   If Pinb.3 = 0 Then
      Byt_chn = 1
      Else
         Byt_chn = 0
         End If
End Sub

'-----------------------------
'EEP set
'-----------------------------

Sub Eep_rd_sub
   If Frq_eep0 =< 0 Then                                    'EEP VFO data check
      Vfo_dat = Def_vfo                                     'Initialize VFO data
      Frq_eep0 = Def_vfo
      Frq_eep1 = Def_vfo1
      Else                                                  'Restore VFO data
        Select Case Byt_chn
            Case 1:
               Vfo_dat = Frq_eep1
            Case Else:
               Vfo_dat = Frq_eep0
               End Select
            End If

   If Stp_eep0 =< 0 Then                                    'EEP STEP data check
      Enc_stp = 10000
      Stp_eep0 = Enc_stp                                    'Initialize STEP data
      Stp_eep1 = Enc_stp
      Else                                                  'Restore STEP data
        Select Case Byt_chn
            Case 1:
               Enc_stp = Stp_eep1
            Case Else:
               Enc_stp = Stp_eep0
               End Select
            End If

End Sub











                                                                                                                                                                                                                                                                                                                                                                                                                     

2014年6月15日日曜日

AD9850 50MHz AM VFO

50MHz AM用(Frq + 10.7MHzプリミックス)AD9850 DDS VFOである。マンマシーンI/Fを見直した為、LCDレス構成も可能。写真は、全てのデバイスで構成。特徴は、チャンネル切替とVFOを組合わせた方式。LCDレス構成でも問題なく操作できる様、VFO中心周波数とLower Limit、Upper Limitの表示用LEDを追加。STEP 10kHZ/1kHZ(LED表示あり)で10kHZとした時、VFO周波数を10kHZ台で丸めた。この事により、10kHzチャンネル切替式の様に操作出来る。お薦めは、メモリー機能が無いが、LCDとRITなしの構成。 
回路図である。全てのデバイスが含まれているので、必要に応じ、構成すれば良い。 

PCB寸法 54 x 55。既に公開の物と同じ。  



















Program
AD9850 DDS VFO Ver1.1aをベースとしたが、チャンネル切替スイッチのメインメモリー(ch0)保持機能は、BASCOMのメモリー制限により、割愛した。ch1 50.55MHz、ch2 50.60MHzで初期化した。

'********************************************************
'AD9850 DDS VFO program ver.1.0
'  50.500Mhz to 50.700Mhz Limitted!
'  Copyright (C)2014.JA2GQP.All rights reserved.
'                                       2014/6/15
'                                           JA2GQP
' BASCOM AVR 2.0.7.5(DEMO version) Compiled
'--------------------------------------------------------
'  Function
'     1.Lower heterodyne
'     2.RIT operation(-10khz to +10khz)
'     3.STEP(1k,10k)
'     4.Memory operation is push RIT
'       (Frequency and Step)
'     5. Protection operation at the time of transmission
'     6.Channel memory ch0(main channel),ch1,ch2
'********************************************************

$regfile = "m88adef.dat"
$crystal = 800000                                           '0.8Mhz clock

'--- config port ---

Config Portb.0 = Input                                      'TX
Config Portb.1 = Output                                     'STEP LED 1k
Config Portb.2 = Input                                      'STEP
Config Portb.3 = Input                                      'RIT
Config Portb.4 = Input                                      'ENC A
Config Portb.5 = Input                                      'ENC B

Config Portc.0 = Output                                     'DATA
Config Portc.1 = Output                                     'FU_UD
Config Portc.2 = Output                                     'W_CLK
Config Portc.3 = Input                                      'ch1
Config Portc.4 = Input                                      'ch2
Config Portc.5 = Input                                      'none

Config Portd.1 = Output                                     'Frq LED Mid .
Config Portd.3 = Output                                     'Frq LED Low
Config Portd.4 = Output                                     'Frq LED Hi

'--- port pullup ---

Portb = &B00111101                                          'Bit 0,Bit 1-4 pull up
Portc = &B00111000                                          'Bit 3-5 pull up


'--- debounce set ---

Config Debounce = 1

'---LCD port assign ---

Config Lcdpin = Pin , Db7 = Portd.6 , Db6 = Portd.5
Config Lcdpin = Pin , Db5 = Portb.7 , Db4 = Portb.6
Config Lcdpin = Pin , E = Portd.2 , Rs = Portd.0
Config Lcd = 16 * 2

'---Frequency Parameter(50.500Mhz to 50.700Mhz Limitted!)

Const If_frq = 10700000                                     'IF frequency
Const Lw_frq = 50500000                                     'Lower limit operation frequency
Const Hi_frq = 50700000                                     'Upper limit operation frequency
Const Def_frq =(lw_frq + Hi_frq) / 2                        'Operation center frequency
Const Def_frq1 = 50550000                                   'ch1=50.55MHz
Const Def_frq2 = 50600000                                   'ch2=50.60MHz

'--- constant data ---

Const Lw_vfo = Lw_frq - If_frq                              'VFO lower limit(RX)
Const Hi_vfo = Hi_frq - If_frq                              'VFO upper limit(RX)
Const Def_vfo = Def_frq - If_frq                            'VFO ch0
Const Def_vfo1 = Def_frq1 - If_frq                          'VFO ch1
Const Def_vfo2 = Def_frq2 - If_frq                          'VFO ch2
Const Lw_rit = -10000                                       'RIT lower limit
Const Hi_rit = 10000                                        'RIT upper limit
Const Scal = 34.35973837                                    '2^32/125.000Mhz
Const Dds_cmd = &B00000000                                  'DDS command

'--- define subrutine ---

Declare Sub Enc_sub                                         'Encorder
Declare Sub Dds_sub                                         'DDS
Declare Sub Lcd_sub                                         'LCD
Declare Sub Stp_sub                                         'STEP
Declare Sub Rit_sub                                         'RIT
Declare Sub Rx_sub                                          'RX
Declare Sub Tx_sub                                          'TX
Declare Sub Chsw_sub                                        'Channel SW check
Declare Sub Eep_rd_sub                                      'EEP read

'--- define memory ---

Dim Vfo_dat As Long                                         'VFO freqency data
Dim Dds_dat As Long                                         'DDS frequency data
Dim Str_frq As String * 10                                  'String frequency
Dim Dsp_frq As String * 10                                  'Display frequency
Dim Sng_wrk As Single                                       'main channel
Dim Lng_wk1 As Long                                         'Long work1
Dim Lng_wk2 As Long                                         'Long work2
Dim Wrd_wk1 As Word                                         'Word work1
Dim Wrd_wk2 As Word                                         'Word work2
Dim Wrd_wk3 As Word                                         'Word work3
Dim Enc_stp As Integer                                      'Encorder step
Dim Rit_dat As Integer                                      'RIT data
Dim Rit_datb As Integer                                     'RIT data old
Dim Int_wrk As Integer                                      'Integer work
Dim Flg_rit As Byte                                         'RIT flag
Dim Flg_ritb As Byte                                        'RIT flag old
Dim Flg_tx As Byte                                          'TX flag
Dim Frq_eep0 As Eram Long                                   'EEP frequency ch0
Dim Frq_eep1 As Eram Long                                   '              ch1
Dim Frq_eep2 As Eram Long                                   '              ch2
Dim Stp_eep0 As Eram Integer                                'EEP STEP ch0
Dim Stp_eep1 As Eram Integer                                '         ch1
Dim Stp_eep2 As Eram Integer                                '         ch2
Dim Flg_enc As Byte                                         'Encorder dir flag
Dim Byt_cmd As Byte                                         'DDS command
Dim Byt_wrk As Byte                                         'Byte work
Dim Byt_chn As Byte                                         'Channel

'--------------
'Main roution
'--------------

Main:
   Flg_tx = 0                                               'TX flag reset
   Flg_rit = 0                                              'RIT flag reset

   Cursor Off
   Cls

   Call Chsw_sub                                            'Channel SW check
   Byt_wrk = Byt_chn
   Call Eep_rd_sub                                          'EEP initial

   Call Lcd_sub

   Do
      If Flg_tx = 0 Then
         Debounce Pinb.4 , 0 , Enc_sub , Sub                'Encorder
         Debounce Pinb.2 , 0 , Stp_sub , Sub                'Step
         Debounce Pinb.3 , 0 , Rit_sub , Sub                'RIT
         Call Chsw_sub                                      'Channel SW check

         If Byt_wrk <> Byt_chn Then
            Byt_wrk = Byt_chn
            Call Eep_rd_sub                                 'EEP load
            End If

         If Vfo_dat =< Lw_vfo Then                          'VFO lower limit check
            Vfo_dat = Lw_vfo
            Portd.3 = 1                                     'Frq LED Low on
            Else
               Portd.3 = 0
               End If

         If Vfo_dat = Def_vfo Then                          'VFO Def Frq check
            Portd.1 = 1                                     'Frq LED Mid on
            Else
               Portd.1 = 0
               End If

         If Vfo_dat >= Hi_vfo Then                          'VFO upper limit check
            Vfo_dat = Hi_vfo
            Portd.4 = 1                                     'Frq LED Hi on
            Else
               Portd.4 = 0
               End If

         If Enc_stp = 1000 Then                             'STEP LED 1k check
            Portb.1 = 1                                     'LED on
            Else
               Portb.1 = 0
               End If

         End If

      Debounce Pinb.0 , 1 , Rx_sub , Sub                    'RX
      Debounce Pinb.0 , 0 , Tx_sub , Sub                    'TX

      If Flg_rit = 1 Then
         Dds_dat = Vfo_dat + Rit_dat
         Else
            Dds_dat = Vfo_dat
            End If

      If Flg_tx = 1 Then
         Dds_dat = Vfo_dat
         End If


      Call Dds_sub
   Loop
End

'-----------------------------
'Encoder check,Create DDS data
'-----------------------------

Sub Enc_sub
   If Pinb.5 = 1 Then
      Flg_enc = 0                                           'Up
      Else
         Flg_enc = 1                                        'down
         End If

   If Flg_enc = 0 Then
      Lng_wk1 = Vfo_dat + Enc_stp                           'Up
      Lng_wk2 = Rit_dat + Enc_stp
      Else
         Lng_wk1 = Vfo_dat - Enc_stp                        'down
         Lng_wk2 = Rit_dat - Enc_stp
         End If

   If Flg_rit = 1 Then
      Rit_dat = Lng_wk2
      Else
         Vfo_dat = Lng_wk1
         Rit_dat = 0
         End If

   If Vfo_dat < Lw_vfo Then                                 'VFO lower limit check
      Vfo_dat = Lw_vfo
      End If

   If Vfo_dat > Hi_vfo Then                                 'VFO upper limit check
      Vfo_dat = Hi_vfo
      End If

   If Rit_dat < Lw_rit Then                                 'RIT lower limit check
      Rit_dat = Lw_rit
      End If

   If Rit_dat > Hi_rit Then                                 'RIT upper limit check
      Rit_dat = Hi_rit
      End If

   Call Lcd_sub
End Sub

'-----------------------------
'AD9850(DDS) Data write
'-----------------------------

Sub Dds_sub
   Sng_wrk = Dds_dat
   Lng_wk1 = Sng_wrk * Scal
   Byt_cmd = Dds_cmd                                        'DDS command

   Reset Portc.1
   Shiftout Portc.0 , Portc.2 , Lng_wk1 , 3
   Shiftout Portc.0 , Portc.2 , Byt_cmd , 3
   Set Portc.1
End Sub

'-----------------------------
'LCD Data write
'-----------------------------

Sub Lcd_sub
   Locate 1 , 1
   Lng_wk1 = Vfo_dat + If_frq
   Str_frq = Str(lng_wk1)
   Str_frq = Format(str_frq , "00.000000")
   Dsp_frq = Left(str_frq , 3) + Mid(str_frq , 4 , 3) + "." + Mid(str_frq , 7 , 3)
   Lcd Byt_chn ; ":" ; Dsp_frq ; "MHz"
   Locate 2 , 1
   Lcd "S:     "
   Locate 2 , 3
   Int_wrk = Enc_stp / 1000
   Lcd Int_wrk ; "k"

   If Flg_rit = 1 Then
      Locate 2 , 8
      Lcd "R:       "
      Str_frq = Str(rit_dat)
      Str_frq = Format(str_frq , "00.000")
      Locate 2 , 10
      Lcd Str_frq
      Else
         Locate 2 , 8
         Lcd "   JA2GQP"
         End If
End Sub

'-----------------------------
'Step
'-----------------------------

Sub Stp_sub
   Select Case Enc_stp
      Case 10000:
         Enc_stp = 1000                                     '1k
      Case 1000:
         Enc_stp = 10000                                    '10k
         Vfo_dat = Vfo_dat + 5000                           'round 10k
         Vfo_dat = Vfo_dat \ 10000
         Vfo_dat = Vfo_dat * 10000
      Case Else:
         Enc_stp = 10000                                    '10k(initial)
         End Select

   Call Lcd_sub
End Sub

'-----------------------------
'RIT
'-----------------------------

Sub Rit_sub
   If Flg_rit = 0 Then
      Rit_dat = 0
      Flg_rit = 1

      Select Case Byt_chn
         Case 1:
            Frq_eep1 = Vfo_dat                              'Save VFO1 data
            Stp_eep1 = Enc_stp                              'Save STEP1 data
         Case 2:
            Frq_eep2 = Vfo_dat                              'Save VFO2 data
            Stp_eep2 = Enc_stp                              'Save STEP2 data
         Case Else:
            Frq_eep0 = Vfo_dat                              'Save VFO0 data
            Stp_eep0 = Enc_stp                              'Save STEP0 data
            End Select
      Else
         Flg_rit = 0
         End If

   Call Lcd_sub
End Sub

'-----------------------------
'RX
'-----------------------------

Sub Rx_sub
   If Flg_tx = 1 Then
      Flg_tx = 0                                            'TX flag rest
      Locate 1 , 1
      Lcd Byt_chn
      End If
End Sub

'-----------------------------
'TX
'-----------------------------

Sub Tx_sub
   If Flg_tx = 0 Then
      Flg_tx = 1                                            'TX flag set
      Locate 1 , 1
      Lcd "T"
      End If
End Sub

'-----------------------------
'Channel SW check
'-----------------------------

Sub Chsw_sub
   If Pinc.3 = 0 Then
      Byt_chn = 1
      Elseif Pinc.4 = 0 Then
         Byt_chn = 2
         Else
            Byt_chn = 0
            End If

   Locate 1 , 1
   Lcd Byt_chn
End Sub

'-----------------------------
'EEP set
'-----------------------------

Sub Eep_rd_sub
   If Frq_eep0 =< 0 Then                                    'EEP VFO data check
      Vfo_dat = Def_vfo                                     'Initialize VFO data
      Frq_eep0 = Def_vfo
      Frq_eep1 = Def_vfo1
      Frq_eep2 = Def_vfo2
      Else                                                  'Restore VFO data
        Select Case Byt_chn
            Case 1:
               Vfo_dat = Frq_eep1
            Case 2:
               Vfo_dat = Frq_eep2
            Case Else:
               Vfo_dat = Frq_eep0
               End Select
            End If

   If Stp_eep0 =< 0 Then                                    'EEP STEP data check
      Enc_stp = 10000
      Stp_eep0 = Enc_stp                                    'Initialize STEP data
      Stp_eep1 = Enc_stp
      Stp_eep2 = Enc_stp
      Else                                                  'Restore STEP data
        Select Case Byt_chn
            Case 1:
               Enc_stp = Stp_eep1
            Case 2:
               Enc_stp = Stp_eep2
            Case Else:
               Enc_stp = Stp_eep0
               End Select
            End If

   Call Lcd_sub
End Sub