2017年4月15日土曜日

RF Analyzer PCB

RF Analyzer安定動作の為、PCB化を行った。回路を少し変更したが、オリジナルのスケッチを変更する事無く使える。ケース(YM-150)に収納できる様、PCB(90 x 100)とした。ノイズフロア改善用に電源入力、AD8307電源入力、AD8307GNDの各所に対策用FB(フェライトビーズ)が挿入可能。




部品実装


AD9850モジュールの下側に、LPFを配置し、最短でSMAコネクタに繋いだ。AD8307 SOPを使ったので、パターン面に配置してある。ノイズフロア改善用にFB(抵抗より大きい、黒色部品)を3か所入れてあるが、効果が有ったのは、AD8307GNDとコモンGND間のみ。電源側の2か所は、気休め程度であった。







ノイズ対策


ケース収納しない状態で、フロアノイズ-73dBm(ケーブルなし)であったが、アルミケースに収納した所、約10dBm悪化した。その為、AD8307部分を鉄板を使ってシールドを施した。対策後をアルミケースに収納した完成品-74dBmである。







外観


 ケースは、タカチYM-150を使い、2.8"TFT組込んだ。電池駆動が可能なスペース(UM4 x 6本位)がある。













回路図



AD8307周辺部は、チップ部品を使った。












基板



サイズ 90 x 102   

              

2017年3月21日火曜日

RF Analyzer

何時もお世話になっている松浦OMのRF Analyzerを作った。このAnalyzerは、2.8"TFT(オリジナルは、2.2"TFT)を使用し、スタンドアーロンでSG、パワーメータ、周波数応答、アンテナアナライザなどの機能がある。今回、1ボードのユニバーサル基板で作り、ジャンクのHubケースに納めた。シールド対策を施した結果、ノイズフロアレベル-70dB(測定用ケーブルなしでの裸特性)となった。




            

AD8350とLPFを含めた回路、および、AD8307回路部に個別シールドを施した。更に、基板裏側もコネクタ部までシールドを行った。当初、アルミケースに組み込んだが、ノイズ対策後、蓋を閉めると状況が悪化した為、樹脂ケースを使う事にした。








Hub(ジャンク)のケースを流用し、余分な穴を塞いで見栄えを向上させた。







     
一部修正した回路である。オリジナル回路では、TL431が発振による動作不良の為、REF側にコンデンサを追加した。








  





2017年2月28日火曜日

スイッチング電源

2017年度クラブ製作講習会に当たり、色々検討した結果、スイッチング電源装置の試作を行う事にした。この電源は、半田付けが殆どなく、市販モジュール配線と板金加工で完成する。仕様は、固定出力13.8V(max10A)と可変出力2V~11V(max1A)を切替え、電圧・電流を表示。大きさ100x50x230、質量620g。 
固定出力(max10A)の写真。AJDスイッチをoffすると、固定出力(13.8V)となる。表示器の最大電流は10Aである為、スイッチング電源の能力に余裕が有っても、最大10A表示となる。 
可変出力(max1A)の写真。AJDスイッチをonすると、可変出力となる。可変範囲は2V~11V。
上から見た写真。小型に作った為、配線が窮屈となった。

 回路図。  

2017年1月24日火曜日

stm32duino

最近、海外サイトでstm32f103c8t6(左側)が多くなってきた。Arduino nano(右側)と比較して、少し大きい位のボードである。何故、海外で人気が有るかの理由は、性能とコストパフォーマンスの高さである。Arduino nanoが$3に対し、$2で高性能なボードが入手できるからだ。stm32f103c8t6のBlue Pill(青色基板)のスペックがFlashの公称値64kBだが、128kB(保証している訳でない)と魅力的。入手したBlue Pillの他、Red Pill(赤色基板)Black Pill(黒色基板)がある。更に、使い慣れたArduino IDEから開発が出来るstm32duinoである。



H/Wインストール(USBを使う場合)


USB規格ではD +に1.5kのプルアップ抵抗が必要だが、このボードは誤った値(R10 10kまたは、4.7k)となっている事が知られている。R10を1.5kまたは、1.8kに交換する事が必要である。但し、PCとのマージンの問題なので、通信が行えない場合のみ、改造すれば良い。



stm32duinoインストール


  • Arduino IDE 1.6.9をここでダウンロードしてインストールする。
  • IDEを実行し、ツールメニューでボードマネージャを選択し、使用可能なボードのリストからArduino Zeroを検索し、ARM CortexーM0+をインストールする。
  • STM32のZIPファイルを含むファイルをダウンロード。
  • 解凍してArduino_STM32フォルダを作成する。但し、フォルダ名は変更しない事。
  • Arduino_STM32フォルダをMy Documents / Arduino / hardwareにコピーする。     (hardwareフォルダが存在しない場合は、作成する必要がある)
インストール手順は、wikiから引用した。
Arduino IDE 1.6.9を使う様に書いて有るが、IDE 1.8.1を 使っても問題は起きてない。(但し、全ての機能を試した訳でない)

Bootloader(書込みしない)


Bootloaderとは、スケッチをマイコンボードに書込み、ロードなどを行うstm32f103c8t6のF/Wである。PCからシリアルまたは、ST-LINKを使う場合、Bootloader書込みは不要。USBを使う場合、Bootloader書込みが必要となるが、Power onまたはReset後、スケッチがロードされる迄に数秒待たなければプログラムが動作しない為、USBは使えない。
stm32f103c8t6に書き込まれたオリジナルのF/Wを使えば良い。


BOOTスイッチ(基板上のDIP SW)

 

ST-LINK V2

  BOOT0  0側
  BOOT1  0側

 書込み/Power onまたはRESET時とも同じ設定でOK。但し、シリアルモニタ機能は使えない。

シリアル

書込み時
  BOOT0 1側
  BOOT1 0側

 Power onまたはRESET時
  BOOT0 0側
  BOOT1 0側

 シリアルモニタ機能が使える。


USBアダプタ

ST-LINK V2

アダプタ               stm32f103c8t6
 2pin SWDIO           SWDIO
 4pin GND              GND
 6pin SWCLK          SWCLK
 8pin 3.3V               3.3V









シリアル
左側(CH340G)    stm32f103c8t6   
 TX                         A9     
 RX                         A10
 3.3V                       3.3V
 GND                      GND

右側(FT232RL)    stm32f103c8t6
  RX                         A9  
  TX                         A10
  3.3V                       3.3V
  GND                      GND


   

スケッチ(Lチカ)

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(PC13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(PC13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(PC13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}












2016年12月9日金曜日

バリキャップ容量測定治具

近頃バリキャップの入手が難しくなってきている。そこで、バリキャップの代替をする為に、測定治具を作った。LC meterにアダプタを付加する方式で、既存のLC meterの改造を行わない事にした。ツマミが付いた部分が、バリキャップ測定治具である。
 
測定治具は、アダプタ方式にしたので、取付/取外しが容易な構造にした。













回路図










バリキャップ代替
手持品の代替として使えそうな物の、特性を測った。





        

2016年11月17日木曜日

Nextion TFT

Nextion 3.2"TFTを入手した。 このLCDは、インテリジェントTFTで、制御機器(PC,マイコンなど)からのシリアル通信で画面コントロールが出来る。最もシンプルの構成は、Nextionのみで動作する。マイコンなどによる画面制御では、メモリ、表示速度など神経を使わなければ出来ないアプリケーションも多々ある。表示部を分散した事で、より自由度の高いプログラムングが出来るであろう。今回、スイッチ画像を作り、タッチパネル操作でLED点灯/消灯る事が出来た。
開発は、 Nextion Editor  とNextionに書き込む為の、USBアダプタ又は、マイクロSDカードが必要。SDカードは必須でなく、USBアダプタでもNextionに書込み出来る。SDカードを使う方が、書込み時間が少なく、お薦めである。
Nextion資料は、ライブラリ  、命令セット。また購入先は、こちら またはAliexpress、e-Bayなど。
 
NextionとUNOを使ったLチカ。画面をタッチすると、UNOのDIO(13)に接続のLEDが点灯/消灯する。 












スケッチ

int char1,char2;
int charflag=0;

void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}

void loop() {
 if (Serial.available()>1)
{
 if (charflag)
  {
  char2=Serial.read();
  if (char2==0) digitalWrite(13,HIGH);
  else if (char2==0x01) digitalWrite(13,LOW);
  charflag=0;
  }
  else
  {
   char1=Serial.read();
   if(char1==0x65) charflag=1;
  }
 }
}

NextionのHMIファイル、ArduinoスケッチなどダウンロードサイトのNextionフォルダからDownload可能。
    




     

2016年10月27日木曜日

si5351a_TFT_Ver3.1 VFO

JA2NKD松浦OM開発のAD9850_TFT_Ver3.1(Multi-Band対応)をsi5351aに移植した。今回、機能追加は行わなかったので、チップが異なる以外、全く同じである。このVFOは、EEPROM初期値設定を別スケッチで書込みを行っている。同OMのBlogを読んで、設定されたい。EEPROM初期値設定スケッチがバージョンアップされて齟齬が危惧される為、Download siteにvfo_v3_eepスケッチのコピーを保存した。 IDEは、1.6.12(最新版)を使った。





Arduino nano/UNO対応の回路図である。スイッチ入力がアナログポートを使ったレベルによる入力判定を行っている。












ヘッダーファイル

si5351a.hは、スケッチと同じフォルダーに入れる事。Download siteにヘッダーファイル、スケッチ、vfo_v3_eepを保存した。

////////////////////////////////////////////////////////////////////////
// Author: Hans Summers, 2015
// Website: http://www.hanssummers.com
//
// A very very simple Si5351a demonstration
// using the Si5351a module kit http://www.hanssummers.com/synth
// Please also refer to SiLabs AN619 which describes all the registers to use
//----------------------------------------------------------------------
// Addered: JA2GQP,2016/8/18
////////////////////////////////////////////////////////////////////////

#define I2C_START       0x08
#define I2C_START_RPT   0x10
#define I2C_SLA_W_ACK   0x18
#define I2C_SLA_R_ACK   0x40
#define I2C_DATA_ACK    0x28
#define I2C_WRITE       0b11000000
#define I2C_READ        0b11000001

#define SI_CLK0_CONTROL 16            // Register definitions
#define SI_CLK1_CONTROL 17
#define SI_CLK2_CONTROL 18
#define SI_SYNTH_PLL_A  26
#define SI_SYNTH_PLL_B  34
#define SI_SYNTH_MS_0   42
#define SI_SYNTH_MS_1   50
#define SI_SYNTH_MS_2   58
#define SI_PLL_RESET    177

#define SI_R_DIV_1      0b00000000  // R-division ratio definitions
#define SI_R_DIV_2      0b00010000
#define SI_R_DIV_4      0b00100000
#define SI_R_DIV_8      0b00110000
#define SI_R_DIV_16     0b01000000
#define SI_R_DIV_32     0b01010000
#define SI_R_DIV_64     0b01100000
#define SI_R_DIV_128    0b01110000

#define SI_CLK_SRC_PLL_A 0b00000000
#define SI_CLK_SRC_PLL_B 0b00100000

#define XTAL_FREQ       25000000    // Crystal frequency for Hans' board

uint8_t i2cStart(){
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWSR & 0xF8);
}

void i2cStop(){
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

  while ((TWCR & (1<<TWSTO))) ;
}

uint8_t i2cByteSend(uint8_t data){
  TWDR = data;

  TWCR = (1<<TWINT) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWSR & 0xF8);
}

uint8_t i2cByteRead(){
  TWCR = (1<<TWINT) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWDR);
}

uint8_t i2cSendRegister(uint8_t reg, uint8_t data){
  uint8_t stts;

  stts = i2cStart();
  if (stts != I2C_START)
    return 1;

  stts = i2cByteSend(I2C_WRITE);
  if (stts != I2C_SLA_W_ACK)
    return 2;

  stts = i2cByteSend(reg);
  if (stts != I2C_DATA_ACK)
    return 3;

  stts = i2cByteSend(data);
  if (stts != I2C_DATA_ACK)
    return 4;

  i2cStop();

  return 0;
}

uint8_t i2cReadRegister(uint8_t reg, uint8_t *data){
  uint8_t stts;

  stts = i2cStart();
  if (stts != I2C_START)
    return 1;

  stts = i2cByteSend(I2C_WRITE);
  if (stts != I2C_SLA_W_ACK)
    return 2;

  stts = i2cByteSend(reg);
  if (stts != I2C_DATA_ACK)
    return 3;

  stts = i2cStart();
  if (stts != I2C_START_RPT)
    return 4;

  stts = i2cByteSend(I2C_READ);
  if (stts != I2C_SLA_R_ACK)
    return 5;

  *data = i2cByteRead();

  i2cStop();

  return 0;
}

// Init TWI (I2C)
//
void i2cInit(){
  TWBR = 92;
  TWSR = 0;
  TWDR = 0xFF;
//#ifdef ARDUINO_AVR_MEGA2560
//  PRR0 = 0;
//#else
  PRR = 0;
//#endif
}

////////////////////////////////////////////////////////////////////////
// Set up specified PLL with mult, num and denom
// mult is 15..90
// num is 0..1,048,575 (0xFFFFF)
// denom is 0..1,048,575 (0xFFFFF)
///////////////////////////////////////////////////////////////////////

void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom){
  uint32_t P1;                            // PLL config register P1
  uint32_t P2;                            // PLL config register P2
  uint32_t P3;                            // PLL config register P3

  P1 = (uint32_t)(128 * ((float)num / (float)denom));
  P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
  P2 = (uint32_t)(128 * ((float)num / (float)denom));
  P2 = (uint32_t)(128 * num - denom * P2);
  P3 = denom;

  i2cSendRegister(pll + 0, (P3 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 1, (P3 & 0x000000FF));
  i2cSendRegister(pll + 2, (P1 & 0x00030000) >> 16);
  i2cSendRegister(pll + 3, (P1 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 4, (P1 & 0x000000FF));
  i2cSendRegister(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  i2cSendRegister(pll + 6, (P2 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 7, (P2 & 0x000000FF));
}

////////////////////////////////////////////////////////////////////////
// Set up MultiSynth with integer divider and R divider
// R divider is the bit value which is OR'ed onto the appropriate
// register, it is a #define in si5351a.h
////////////////////////////////////////////////////////////////////////

void setupMultisynth(uint8_t synth, uint32_t divider, uint8_t rDiv){
  uint32_t P1;                          // Synth config register P1
  uint32_t P2;                          // Synth config register P2
  uint32_t P3;                          // Synth config register P3

  P1 = 128 * divider - 512;
  P2 = 0;                               // P2 = 0, P3 = 1 forces an integer value for the divider
  P3 = 1;

  i2cSendRegister(synth + 0, (P3 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 1, (P3 & 0x000000FF));
  i2cSendRegister(synth + 2, ((P1 & 0x00030000) >> 16) | rDiv);
  i2cSendRegister(synth + 3, (P1 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 4, (P1 & 0x000000FF));
  i2cSendRegister(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  i2cSendRegister(synth + 6, (P2 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 7, (P2 & 0x000000FF));
}

////////////////////////////////////////////////////////////////////////
// Switches off Si5351a output
// Example: si5351aOutputOff(SI_CLK0_CONTROL);
// will switch off output CLK0
////////////////////////////////////////////////////////////////////////

void si5351aOutputOff(uint8_t clk){
  i2cSendRegister(clk, 0x80);           // Refer to SiLabs AN619 to see
                                        //bit values - 0x80 turns off the output stage
}

////////////////////////////////////////////////////////////////////////
// Set CLK0 output ON and to the specified frequency
// Frequency is in the range 1MHz to 150MHz
// Example: si5351aSetFrequency(10000000);
// will set output CLK0 to 10MHz
//
// This example sets up PLL A
// and MultiSynth 0
// and produces the output on CLK0
////////////////////////////////////////////////////////////////////////

void si5351aSetFrequency(uint32_t frequency){
  uint32_t pllFreq;
  uint32_t xtalFreq = XTAL_FREQ;
  uint32_t l;
  float f;
  uint8_t mult;
  uint32_t num;
  uint32_t denom;
  uint32_t divider;

  divider = 900000000 / frequency;        // Calculate the division ratio. 900,000,000 is the maximum internal
                                          // PLL frequency: 900MHz
  if (divider % 2) divider--;             // Ensure an even integer
                                          //division ratio

  pllFreq = divider * frequency;          // Calculate the pllFrequency:
                                          //the divider * desired output frequency

  mult = pllFreq / xtalFreq;              // Determine the multiplier to
                                          //get to the required pllFrequency
  l = pllFreq % xtalFreq;                 // It has three parts:
  f = l;                                  // mult is an integer that must be in the range 15..90
  f *= 1048575;                           // num and denom are the fractional parts, the numerator and denominator
  f /= xtalFreq;                          // each is 20 bits (range 0..1048575)
  num = f;                                // the actual multiplier is mult + num / denom
  denom = 1048575;                        // For simplicity we set the denominator to the maximum 1048575

                                          // Set up PLL A with the calculated  multiplication ratio
  setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
                                          // Set up MultiSynth divider 0, with the calculated divider.
                                          // The final R division stage can divide by a power of two, from 1..128.
                                          // reprented by constants SI_R_DIV1 to SI_R_DIV128 (see si5351a.h header file)
                                          // If you want to output frequencies below 1MHz, you have to use the
                                          // final R division stage
  setupMultisynth(SI_SYNTH_MS_0, divider, SI_R_DIV_1);
                                          // Reset the PLL. This causes a glitch in the output. For small changes to
                                          // the parameters, you don't need to reset the PLL, and there is no glitch
//  i2cSendRegister(SI_PLL_RESET, 0xA0);  // 2016/10/23 JA2GQP
                                          // Finally switch on the CLK0 output (0x4F)
                                          // and set the MultiSynth0 input to be PLL A
  i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
}

////////////////////////////////////////////////////////////////////////     <<  JA2GQP >>
// Power strength
// Example: SetPower(1);
// The setting range is from 1 to 4
////////////////////////////////////////////////////////////////////////

void SetPower(byte power){
  switch(power){
    case 1:
      i2cSendRegister(SI_CLK0_CONTROL,76);  // CLK0 drive strength = 2mA; power level ~ -10dB
      break;
    case 2:
      i2cSendRegister(SI_CLK0_CONTROL,77);  // CLK0 drive strength = 4mA; power level ~ -6dB
      break;
    case 3:
      i2cSendRegister(SI_CLK0_CONTROL,78);  // CLK0 drive strength = 6mA; power level ~ -3dB
      break;
    case 4:
      i2cSendRegister(SI_CLK0_CONTROL,79);  // CLK0 drive strength = 8mA; power level := 0dB
      break;
    default:
      i2cSendRegister(SI_CLK0_CONTROL,76);  // CLK0 drive strength = 2mA; power level ~ -10dB
      break;
  }
}

スケッチ

//----------------------------------------------------------------------------------
//    Multi Band DDS VFO Ver3.1      
//                         JA2NKD 2016.10.19  
//     Aruduino IDE 1.6.12
//     Arduino nano/UNO
//  
// <Rotary.h>    https://github.com/brianlow/Rotary
// <EF_AD9850.h> http://forum.arduino.cc/index.php?topic=77483.0
// "Ucglib.h"    https://github.com/olikraus/ucglib
// "si5351a.h"   https://sites.google.com/site/ja2gqp/
//---------------------------------------------------------------------------------
// si5351a transplant  2016/10/23  JA2GQP
//       (si5351a.h is original hedder file.)
//---------------------------------------------------------------------------------

//---------- Library include ----------

#include "si5351a.h"                      // 2016/10/23 JA2GQP
#include <SPI.h>
#include <EEPROM.h>
#include <Rotary.h>
//#include <EF_AD9850.h>                  // 2016/10/23 JA2GQP
#include "Ucglib.h"

/*
 * Hardware SPI Pins:
 * Arduino nano sclk=13, data=11
*/

// I/O setting

  const byte __CS=10;
  const byte __DC=9;
  const byte __RST=8;

  const byte modeout1=7;                    // 2016/10/24 JA2GQP
  const byte modeout2=12;                   //
  const byte bandout1=4;                    //
  const byte bandout2=5;                    //
  const byte bandout3=6;                    //
  const byte txsw=A3;                       //
  const byte meterin=A0;                    //
  const byte analogsw=A1;                   //

//  EF_AD9850 AD9850(ddsclock,ddsfqup,ddsreset,ddsdata);  // 2016/10/23 JA2GQP
  Rotary r=Rotary(2,3);
  Ucglib_ILI9341_18x240x320_HWSPI ucg(__DC, __CS, __RST);

//---------- Variable setting ----------

  long romf[4];
  long freq =7100000;
  long freqmax=7200000;
  long freqmin=7000000;
  long freqold=0;
  long freqrit=0;

  String freqt=String(freq);

  long ifshift = 0;
  long ifshiftLSB =8998500; // VFO>frequency USB/LSB is turn over
  long ifshiftUSB =9001500;
  long ifshiftCW  =8999200;
  long ifshiftAM  =9000000;
  long txshiftLSB =8998500;
  long txshiftUSB =9001500;
  long txshiftCW  =9000000;
  long txshiftAM  =9000000;
  long ddsfreq = 0;
  long ddsfreqb;           // 2016/10/23 JA2GQP

  char f100m,f10m,fmega,f100k,f10k,f1k,f100,f10,f1;

  int ddsstep=2;
  int rit=0;
  int fstep=100;
  int steprom=1;
  int fmode=3;
  int fmodeold=1;
  int flagrit=0;
  int fritold=0;
  int flagmode=0;
  int meterval1=0;
  int tmeterval=0;
  int romadd=0;
  int analogdata=0;
  int band=0;
  int bandmax=8;

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

void setup() {
  i2cInit();                             // I2c initialaz  2016/10/23 JA2GQP

  delay(100);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
 //ucg.begin(UCG_FONT_MODE_SOLID);
  ucg.clearScreen();
  ucg.setRotate270();

  pinMode (bandout1,OUTPUT);
  pinMode (bandout2,OUTPUT);
  pinMode (bandout3,OUTPUT);
  pinMode(txsw,INPUT_PULLUP);
  pinMode(modeout1,OUTPUT);
  pinMode(modeout2,OUTPUT);

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

//  AD9850.init();                      // 2016/10/23 JA2GQP                    
//  AD9850.reset();                     // 2016/10/23 JA2GQP

  band=EEPROM.read(0x01);
  romadd=0x010+(band*0x10);
  for (int i=0; i<3;i++){
   romf[i]=eepread((romadd+4*i));
  }
  freq = romf[0];
  freqmin = romf[1];
  freqmax = romf[2];
  fmode = EEPROM.read(romadd+12);
  steprom = EEPROM.read(romadd+13);
  if (steprom==1){fstep=10;}
  if (steprom==2){fstep=100;}
  if (steprom==3){fstep=1000;}
  if (steprom==4){fstep=10000;}
  banddataout();
  screen01();
  chlcd();
  if (fmode==0){fmode=3;}
  else{fmode=fmode-1;}
  modeset();
  steplcd();
  freqt=String(freq);
  freqlcd();
}

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

void loop() {

  analogdata=analogRead(analogsw);
//  ucg.setPrintPos(12,157);
//  ucg.setColor(255,255,255);
//  ucg.print(analogdata);
 
    if (analogdata<50){                  
      setstep();
    } else if (analogdata<300){          
      modeset();
    } else if (analogdata<600){          
      setrit();
    }else if (analogdata<750){            
      bandcall();
    }else if (analogdata<980){            
      bandwrite();
    }
  if (digitalRead(txsw)==LOW){txset();}
  if (flagrit==1){
    if (freqrit == fritold){
      meter();
    }  
    if (freqrit!=fritold){
      ddswrite();
      ritlcd();
      fritold=freqrit;
    }
  }
  else{
    if (freq == freqold){
        meter();
    }
  ddswrite();
  freqt=String(freq);
  freqlcd();
  freqold=freq;
  }
}

//----------  Function DDS set  --------------- 2016/10/23  JA2GQP      

void Fnc_Dds(long frequency){
  if(ddsfreq != ddsfreqb){
    si5351aSetFrequency(frequency);
    SetPower(1);
    ddsfreqb = ddsfreq;
  }
}

//---------- meter --------------------------

void meter(){
 meterval1=analogRead(meterin);
 meterval1=meterval1/50;
 if (meterval1>15){meterval1=15;}
  int sx1=sx1+(meterval1*17);
  sx1=sx1+41;
  int sx2=0;
  sx2=sx2+(40+((15-meterval1)*17));
  ucg.setFont(ucg_font_fub35_tr);
  ucg.setColor(0,0,0);
  ucg.drawBox(sx1,180,sx2,16);
  ucg.setPrintPos(40,200);
  for(int i=1;i<=meterval1;i++){
    if (i<=9){
      ucg.setColor(0,255,255);
      ucg.print("-");
    }
    else{
      ucg.setColor(255,0,0);
      ucg.print("-");
    }
  }
}

//---------- Encoder Interrupt -----------------------

ISR(PCINT2_vect) {
  if (flagrit==1){
  unsigned char result = r.process();
    if(result) {
      if(result == DIR_CW){
        freqrit=freqrit+fstep;
        if (freqrit>=10000){
          freqrit=10000;
        }
     }
     else{
      freqrit=freqrit-fstep;
      if (freqrit<=-10000){
        freqrit=-10000;
      }
    }
   }
  }
  else{
    unsigned char result = r.process();
      if(result) {
        if(result == DIR_CW){
          freq=freq+fstep;
          if (freq>=freqmax){freq=freqmax;}
        }
        else{
          freq=freq-fstep;
          if (freq<=freqmin){freq=freqmin;}
        }
     }
  }
}

//------------ On Air -----------------------------

void txset(){
  noInterrupts();
    if (fmode==0){ddsfreq=freq+txshiftLSB;}
    if (fmode==1){ddsfreq=freq+txshiftUSB;}
    if (fmode==2){ddsfreq=freq+txshiftCW;}
    if (fmode==3){ddsfreq=freq+txshiftAM;}

//    AD9850.wr_serial(0x00,ddsfreq);       // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                       // DDS out  2016/10/24 JA2GQP

    ucg.setPrintPos(110,140);
    ucg.setFont(ucg_font_fub17_tr);
    ucg.setColor(255,0,0);
    ucg.print("ON AIR");
    while(digitalRead(txsw) == LOW){
      meter();
    }
  ucg.setFont(ucg_font_fub17_tr);
    ucg.setColor(0,0,0);
    ucg.drawBox(100,120,250,30);  //45
    ddswrite();
    interrupts();
  }

//------------- Mode change(LSB-USB-CW-AM) ------------

void modeset(){
  ucg.setFont(ucg_font_fub17_tr);
    ucg.setPrintPos(82,82);
    ucg.setColor(0,0,0);
    ucg.print("USB");
    ucg.setPrintPos(12,82);
    ucg.print("LSB");
    ucg.setPrintPos(82,112);
    ucg.print("A M");
    ucg.setPrintPos(12,112);
    ucg.print("C W");  
  if (fmode==0){
    ifshift=ifshiftUSB;
    ucg.setColor(255,255,0);
    ucg.setPrintPos(82,82);
    ucg.print("USB");
    digitalWrite(modeout1,HIGH);
    digitalWrite(modeout2,LOW);  
  }
  if(fmode==1){
    ifshift=ifshiftCW;
    ucg.setPrintPos(12,112);
    ucg.setColor(255,255,0);
    ucg.print("C W");
    digitalWrite(modeout1,LOW);
    digitalWrite(modeout2,HIGH);
  }
  if (fmode==2){
    ifshift=ifshiftAM;
    ucg.setPrintPos(82,112);
    ucg.setColor(255,255,0);
    ucg.print("A M");
    digitalWrite(modeout1,HIGH);
    digitalWrite(modeout2,HIGH);
    }
  if (fmode==3){
    ifshift=ifshiftLSB;
    ucg.setPrintPos(12,82);
    ucg.setColor(255,255,0);
    ucg.print("LSB");
    digitalWrite(modeout1,LOW);
    digitalWrite(modeout2,LOW);
  }
  fmode=fmode+1;
  if (fmode==4){fmode=0;}
  ddswrite();
  while(analogRead(analogsw) <1000);
}

//------------ Rit SET ------------------------------

void setrit(){
  if(flagrit==0){
    flagrit=1;
    ucg.setFont(ucg_font_fub11_tr);
    ucg.setPrintPos(190,110);
    ucg.setColor(255,0,0);
    ucg.print("RIT");
    ritlcd();
  }
  else {
    flagrit=0;
    ddsfreq=freq+ifshift;

//    AD9850.wr_serial(0x00,ddsfreq);       // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                       // DDS Out  2016/10/23 JA2GQP

    freqt=String(freq);
    ucg.setFont(ucg_font_fub11_tr);
    ucg.setPrintPos(190,110);
    ucg.setColor(255,255,255);
    ucg.print("RIT");
    ucg.setColor(0,0,0);
    ucg.drawRBox(222,92,91,21,3);
    freqrit=0;
  }
  while(analogRead(analogsw) <1000);
}

//----------- Rit screen ----------------------

void ritlcd(){
  noInterrupts();
  ucg.setColor(0,0,0);
  ucg.drawBox(222,92,91,21);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(230,110);
  ucg.print(freqrit);
  interrupts();
}

//-------------- encorder frequency step set -----------

void setstep(){
  noInterrupts();
  if (fstep==10000){
    fstep=10;
  }
  else{
    fstep=fstep * 10;
  }
 steplcd();
 while(analogRead(analogsw) < 1000);
 interrupts();
}

//------------- Step Screen ---------------------------

void steplcd(){
  ucg.setColor(0,0,0);
  ucg.drawRBox(221,61,93,23,3);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(220,80);
  if (fstep==10){ucg.print("    10Hz");}
  if (fstep==100){ucg.print("   100Hz");}
  if (fstep==1000){ucg.print("    1KHz");}
  if (fstep==10000){ucg.print("  10KHz");}
}

//----------- Main frequency screen -------------------

void freqlcd(){
  ucg.setFont(ucg_font_fub35_tn);
  int mojisuu=(freqt.length());
  if(freq<100){
    ucg.setColor(0,0,0);
    ucg.drawBox(217,9,28,36);  
  }
  if(f10 !=(freqt.charAt(mojisuu-2))){
    ucg.setColor(0,0,0);
    ucg.drawBox(245,9,28,36);
    ucg.setPrintPos(245,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-2));
    f10 = (freqt.charAt(mojisuu-2));
  }
/*
  if(freq<10){
    ucg.setColor(0,0,0);
    ucg.drawBox(245,9,28,36);  
     }
  if(f1 !=(freqt.charAt(mojisuu-1))){
    ucg.setColor(0,0,0);
    ucg.drawBox(273,9,28,36);
    ucg.setPrintPos(273,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-1));  
    f1  = (freqt.charAt(mojisuu-1));
  }
*/
  if(freq<1000){
    ucg.setColor(0,0,0);
    ucg.drawBox(202,9,15,36);      
    }
  if(f100 !=(freqt.charAt(mojisuu-3))){
    ucg.setColor(0,0,0);
    ucg.drawBox(217,9,28,36);
    ucg.setPrintPos(217,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-3));
    f100 = (freqt.charAt(mojisuu-3));
  }
  if(freq>=1000){
    ucg.setPrintPos(202,45);
    ucg.setColor(0,255,0);
    ucg.print(".");
  }
  if(freq<10000){
    ucg.setColor(0,0,0);
    ucg.drawBox(146,9,28,36);  
    }
  if(f1k !=(freqt.charAt(mojisuu-4))){
    ucg.setColor(0,0,0);
    ucg.drawBox(174,9,28,36);
    ucg.setPrintPos(174,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-4));    
    f1k  = (freqt.charAt(mojisuu-4));
  }
  if(freq<100000){
    ucg.setColor(0,0,0);
    ucg.drawBox(118,9,28,36);
  }
  if(f10k !=(freqt.charAt(mojisuu-5))){
    ucg.setColor(0,0,0);
    ucg.drawBox(146,9,28,36);
    ucg.setPrintPos(146,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-5));
    f10k = (freqt.charAt(mojisuu-5));
  }
   if(freq<1000000){
    ucg.setColor(0,0,0);
    ucg.drawBox(103,9,15,36);
    }
  if(f100k !=(freqt.charAt(mojisuu-6))){
    ucg.setColor(0,0,0);
    ucg.drawBox(118,9,28,36);
    ucg.setPrintPos(118,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-6));
    f100k = (freqt.charAt(mojisuu-6));
  }
     
   if(freq>=1000000){
    ucg.setPrintPos(103,45);
    ucg.setColor(0,255,0);
    ucg.print(".");
  }
   if(freq<10000000){
     ucg.setColor(0,0,0);
    ucg.drawBox(47,9,28,36);
     }
   if(fmega !=(freqt.charAt(mojisuu-7))){
    ucg.setColor(0,0,0);
    ucg.drawBox(75,9,28,36);
    ucg .setPrintPos(75,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-7));
    fmega  = (freqt.charAt(mojisuu-7));
   }
   if(freq<100000000){
    ucg.setColor(0,0,0);
    ucg.drawBox(19,9,28,36);
       }
   if (f10m !=(freqt.charAt(mojisuu-8))){
    ucg.setColor(0,0,0);
    ucg.drawBox(47,9,28,36);
    ucg .setPrintPos(47,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-8));
    f10m = (freqt.charAt(mojisuu-8));
   }

/*
  ucg.setPrintPos(19,45);
  if(freq>=100000000){
    if(f100m !=(freqt.charAt(0))){
      ucg.setColor(0,0,0);
      ucg.drawBox(19,9,28,36);
      ucg .setPrintPos(19,45);
      ucg.setColor(0,255,0);
      ucg.print(freqt.charAt(0));
      f100m = (freqt.charAt(0));
    }
  }
*/

}
//----------- Basic Screen -------------------------

void screen01(){
  ucg.setColor(255,255,255);
  ucg.drawRFrame(1,1,314,55,5);
  ucg.drawRFrame(2,2,312,53,5);
  ucg.setColor(50,50,50);
  ucg.drawRBox(5,60,60,25,3);
  ucg.drawRBox(75,60,60,25,3);
  ucg.drawRBox(5,90,60,25,3);
  ucg.drawRBox(75,90,60,25,3);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setPrintPos(12,82);
  ucg.setColor(0,0,0);
  ucg.print("LSB");
  ucg.setPrintPos(82,82);
  ucg.print("USB");
  ucg.setPrintPos(12,112);
  ucg.print("C W");
  ucg.setPrintPos(82,112);
  ucg.print("A M");
  ucg.setColor(255,255,255);
  ucg.drawRFrame(220,60,95,25,3);
  ucg.drawRFrame(220,90,95,25,3);
  ucg.setFont(ucg_font_fub11_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(175,80);
  ucg.print("STEP");
  ucg.setPrintPos(190,110);
  ucg.setColor(255,255,255);
  ucg.print("RIT");
  ucg.setColor(100,100,100);
  ucg.setPrintPos(10,210);
  ucg.print(" S:  1-----3-------6-------9---Over--------");
  ucg.setPrintPos(10,177);
  ucg.print(" P:  1-----3-----5-----------10--------------");
  ucg.setPrintPos(10,230);
  ucg.setColor(235,0,200);
  ucg.print(" Home Blew DDS-VFO Ver3.1 JA2NKD");
  ucg.setFont(ucg_font_fub35_tr);
    ucg.setColor(0,255,0);
//    ucg.setPrintPos(19,45);
//    ucg.print("4");
//    ucg.setPrintPos(47,45);
//    ucg.print("3");
//    ucg.setPrintPos(75,45);
//    ucg.print("7");
//    ucg.setPrintPos(103,45);
//    ucg.print(".");
    ucg.setPrintPos(273,45);
    ucg.print("0");  
}

//---------- DDS Frequency write -----------

void ddswrite(){
  if (flagrit==0){
    ddsfreq=freq+ifshift;

//    AD9850.wr_serial(0x00,ddsfreq);         // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                         // DDS out  2016/10/24 JA2GQP
  }
  if(flagrit==1){
    ddsfreq=freq+ifshift+freqrit;
 //   AD9850.wr_serial(0x00,ddsfreq);         // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                         // DDS out  2016/10/24 JA2GQP
  }
}

//---------- Band data call from eeprom ----------

void bandcall(){
  band=band+1;
  if (band>(bandmax-1)){band=0;}
  romadd=0x010+(band*0x010);
 for (int i=0; i<3;i++){
   romf[i]=eepread((romadd+4*i));
  }
  freq = romf[0];
  freqmin = romf[1];
  freqmax = romf[2];
  fmode = EEPROM.read(romadd+12);
  steprom = EEPROM.read(romadd+13);
  if (fmode >=1 ){
    fmode=fmode-1;
  }else if (fmode==0){
    fmode=3;
  }
  if (steprom==1){fstep=10;}
  if (steprom==2){fstep=100;}
  if (steprom==3){fstep=1000;}
  if (steprom==4){fstep=10000;}
  modeset();
  steplcd();
  freqt=String(freq);
  freqlcd();
  banddataout();
  chlcd();
}

//---------- Band data write to eeprom ----------

void bandwrite(){
  romadd=0x010+(band*0x010);
 // for (int i=0;i<3;i++){
    eepwrite(freq,romadd);
//  }
  EEPROM.write(0x001,band);
  EEPROM.write(romadd+12,fmode);
  if (fstep==10){steprom=1;}
  if (fstep==100){steprom=2;}
  if (fstep==1000){steprom=3;}
  if (fstep==10000){steprom=4;}
  EEPROM.write(romadd+13,steprom);
  ucg.setPrintPos(110,140);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,0,0);
  ucg.print("Complete!!");
  delay (500);
  ucg.setColor(0,0,0);
  ucg.drawBox(100,120,250,30);
  //ucg.drawBox(41,145,270,16);
}

 //---------- EEPROM Write(4byte) subroutine ----------

void eepwrite(unsigned long f0,int epadd){
  for (int i=0; i<=3;i++){
  EEPROM.write(epadd+i,f0%256);
  f0=f0/256;
  }
}

//---------- EEPROM Read(4byte) subroutin ----------

unsigned long eepread(int epadd){
  unsigned long f0=0;
  for (int i=3; i >=0 ;i--){
    f0=f0*256+EEPROM.read(epadd+i);
    }
    return f0;
}

//---------- Band data output I/O ----------

void banddataout(){
  digitalWrite(bandout1,LOW);
  digitalWrite(bandout2,LOW);
  digitalWrite(bandout3,LOW);
  if (band==0){}
  if (band==1){
   digitalWrite( bandout1,HIGH);
  }
   if (band==2){
   digitalWrite(bandout2,HIGH);
  }
  if (band==3){
   digitalWrite(bandout1,HIGH);
   digitalWrite(bandout2,HIGH);
  }
  if (band==4){
   digitalWrite(bandout3,HIGH);
  }
  if (band==5){
   digitalWrite(bandout1,HIGH);
   digitalWrite(bandout3,HIGH);
  }
  if (band==6){
   digitalWrite(bandout2,HIGH);
   digitalWrite(bandout3,HIGH);
  }
  if (band==7){
   digitalWrite(bandout1,HIGH);
   digitalWrite(bandout2,HIGH);
   digitalWrite(bandout3,HIGH);  
  }
}

//----------  Band No.(Chanel No.) write to LCD ----------

void chlcd(){
ucg.setColor(0,0,0);
ucg.drawBox(5,120,80,20);
ucg.setFont(ucg_font_fub11_tr);
ucg.setPrintPos(12,137);
ucg.setColor(255,255,255);
ucg.print("CH: ");
ucg.print(band+1);
}