2019年3月20日水曜日

6m AM VFO

  
周辺デバイスコントロールにI2C使用のVFO PCBを作った。このVFO PCBは、拡張性を高める為、多くのI/O端子を引出した。PCBパターン引き回し上、アナログ専用ポートのA6を入力ポートに割り付けてしまった。正常動作させる為、アナログ専用ポートA6からアナログ/デジタルのA2に再割り当てを行った。また、PCB動作確認用に6m AMチャンネル切替式VFOスケッチを作り、H/Wチェックを行った。








回路図


回路図である。I/O端子を殆ど使ってないので、拡張用予備端子になっている。
  





PCB部品面

PCB小型化(50x50)の為、Arduinoボードとsi5351aボードで隠れた所迄、部品を実装している。左側のランドは、未使用のI/O端子である。














Arduinoとsi5351aユニット実装

標準高さのピンソケットにArduino nanoとsi5351aユニットを実装した様子である。半固定抵抗は、Sメータレベル調整用である。














A6からA2へ改造


Arduino nanoには、A6,A7端子があるがアナログ専用となっている。その為、PCB裏面(操作面側)のA6パターンをカットし、ジャンパーでA2に改造した。今回は、この方法で対応する事にしたが、アナログ信号を読み取って、しきい値判断によるデジタル化による判断方式などがある。   
    








スケッチ     

PCBチェックの為にスケッチを書いた。簡単で実用的な6m AMチャンネル切替式VFOにした。チャンネルは、50.500、50.550、50.600、50.620の切替式で、現在のチャンネルのメモリーする。使ったOLED128x32と小型だが、Sメータ表示が出来る。必要なファイルは、si5351 VFOフォルダからダウンロードできる。

//////////////////////////////////////////////////////////////////////
//  si5351a 6m AM VFO program ver.1.0
//    Copyright(C)2019.JA2GQP.All rights reserved.
//
//                                                2019/3/19
//                                                  JA2GQP
//////////////////////////////////////////////////////////////////////

#include "src/si5351.h"              // https://github.com/etherkit/Si5351Arduino, v2.1.0
#include "src/SSD1306AsciiAvrI2c.h"  // https://github.com/greiman/SSD1306Ascii
#include <EEPROM.h>

//---------- Set I/O Device ---------------------

Si5351 si5351(0x60);                 // Si5351 I2C address
SSD1306AsciiAvrI2c oled;

//----------  Define Constant Value   ----------
                                                
#define   SW_CH     A0                // CH SW
#define   SW_TX     A2                // TX SW
#define   PIN_SM    A7                // S-meter voltage input

////////////////////////////////
// Channel Frequency
////////////////////////////////
#define  CH1_FRQ    50500000L         // Channel 1 Frequency
#define  CH2_FRQ    50550000L         //         2
#define  CH3_FRQ    50600000L         //         3
#define  CH4_FRQ    50620000L         //         4

////////////////////////////////
// etc
////////////////////////////////
#define  CH1        1                 // Channel 1
#define  CH2        2                 // Channel 2
#define  CH3        3                 // Channel 3
#define  CH4        4                 // Channel 4

#define  MAX_CHN    4                 // Max Channel
#define  INT_END    73                // Initial end code
#define  IF_FRQ     10700000L         // IF Frequency 10.7MHz
#define  OLED_ADR   0x3C              // OLED Address

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

#define  EEP_INT    0x00              // Eep Init(1byte*1)
#define  EEP_CHN    0x01              // Channel(1byte*1)

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

unsigned long Vfo_Dat = 0;            // VFO Data
unsigned long Vfo_Datb = 0;           //          old
unsigned long If_Dat;                 
unsigned long Frq_Dat;                // Frequency Data                 

byte Byt_Chn = CH1;                   // Channel SW
byte Flg_Tx = 0;                      // TX Flag
byte Flg_Txb = 1;                     //         old

unsigned int Val_SM = 0;              // S-Meter Data
unsigned int Val_SMb = 0;             //              old


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

void setup(){
  si5351.init(SI5351_CRYSTAL_LOAD_8PF,0,0);//crystal 25.000 MHz, correction 0
  si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_4MA);//Drive lebel 4mA set 
  
  oled.begin(&Adafruit128x32, OLED_ADR);

  pinMode(SW_TX,INPUT_PULLUP);
  pinMode(SW_CH,INPUT_PULLUP);

  if(EEPROM.read(EEP_INT) != INT_END){    // Eep initialaz
    delay(10);
    Eep_Init();
  }

  Byt_Chn = EEPROM.read(EEP_CHN);         //     Channel

  CH_Set();
  Disp_Comm1();
}

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

void loop() {
  if(digitalRead(SW_TX) == HIGH){          // RX ?
    if((digitalRead(SW_CH) == LOW)){       // CH SW On?
      CH_Switch();
      CH_Set();                                   
    }
    Flg_Tx = 0;
    If_Dat = IF_FRQ;
  }
  else{                                   // TX 
    Flg_Tx = 1;                           // Yes,TX Flag set
    If_Dat = 0;                           //     If_Dat 0 set
  }

  Vfo_Dat = Frq_Dat + If_Dat;
  
  if(Vfo_Dat != Vfo_Datb){                  // Frequency update?
    si5351.set_freq(Vfo_Dat * SI5351_FREQ_MULT,SI5351_CLK0);
    Vfo_Datb = Vfo_Dat;
  }

  if(Flg_Tx != Flg_Txb){
    Disp_Comm1();
    Flg_Txb = Flg_Tx;
  }

  Val_SM = analogRead(PIN_SM);
  if ((abs(Val_SM - Val_SMb)) > 3) {  // if needed draw S-meter
    Disp_SM();
    Val_SMb = Val_SM;
  }

}  


//----------  Channel Data Set & Display Frequency  ---------

void CH_Set(){
  oled.setFont(lcdnums14x24);
  oled.setCursor(1, 0);

  switch(Byt_Chn){
    case CH1:
      Frq_Dat = CH1_FRQ;
      oled.print("01:50.500");      
      break;
    case CH2:
      Frq_Dat = CH2_FRQ;
      oled.print("02:50.550");      
      break;
    case CH3:
      Frq_Dat = CH3_FRQ;
      oled.print("03:50.600");      
      break;
    case CH4:
      Frq_Dat = CH4_FRQ;
      oled.print("04:50.620");      
      break;
    default:
      break;
  }
  EEPROM.write(EEP_CHN,Byt_Chn);
}

//----------  Display Common1(TX/RX)  ---------

void Disp_Comm1(){
  oled.setCursor(2, 3);
  oled.setFont(labels);

  if(Flg_Tx == 1)
    oled.print("2");                // "2" is "TX" in labels.h
  else
    oled.print("1");                // "1" is "RX" in labels.h
}

//----------  CH SW Check  ----------------------

void CH_Switch(){
  Byt_Chn++;
  while(digitalRead(SW_CH) == LOW)
    ;
  if(Byt_Chn > MAX_CHN)
    Byt_Chn = CH1;
}

//----------  Display S-Meter  -------------------

void Disp_SM() {
  uint8_t a = 0;
  uint8_t m = 0;

  a = (Val_SM + 3) / 113;            // 1024 / 9 characters for S = 1,3,5,7,8,9,+10,+20,+30
  oled.setFont(pixels);
  oled.setCursor(25, 3);
  for (m = 0; m < a; m++)
    if (m < 6)
      oled.print('7');               // '5' - hollow rectangle, 6px
    else
      oled.print('8');               // '6' - filled rectangle, 6px
  for (m = a; m < 9; m++)
    oled.print('.');                 // '.' 1px
}

//---------- EEProm Initialization -----------------

void Eep_Init(){
  EEPROM.write(EEP_INT,INT_END);                  // Init end set(73)  
  EEPROM.write(EEP_CHN,CH1);                      // Init end set(73)  
}