Windows10のブルースクリーンエラーがでて、書いていたブログが消えてしまいました。30分以上かかっていたので、がっくりです。前のヤフーのブログでは、今回のような時も途中のデータまでの文章が残っていますと表示されるような素晴らしい機能がありましたが、今回は全く、書いたものすべてが消えています。とまあ、頭にきたのですが、そうもばかリ言っておられません。

風が吹いている内に、という事で、Arduino UNOを使い、Si5351A使用3ch出力クロックジェネレータモジュールでのTS-820用VFOを考えています。Si5351AはSILICON LABS社製で、I2C接続で使い、2.5KHz~200MHzの周波数を出力することができるクロックジェネレータモジュールです。秋月の通販で3個購入してあります。実は、1個購入して、最初うまく動作せず、壊したかと思い、後から2個追加で購入したのですが、スケッチの書き間違いとかの単純ミスで、動かなかっただけで、最初の1個目のSi5351も結局は問題ありませんでした。Aruduino UNOでのスケッチサンプルがWebで結構ありました。今回VFO用に今回参考にさせていただいたのは、JA2GQP局のブログとダウンロードサイトのスケッチや、ライブラリです。ほぼ丸ごとコピーで動作確認から最初やってみました。再現性は100%でした。私が使わせせていただいたのは、下記の2つのスケッチと対応するライブラリです。
https://sites.google.com/site/ja2gqp/

Si5351_oled(128x32) 
Si5351_oled(128x64)

の2つです。
TS-820のVFOに改良するDDSサンプルはoled(128x32)にすることにしました。
また、oled(128x32)は使用しないで、手持ちの1602の液晶ディスプレー用に、インクルードファイルと、液晶部のコードを全部書き換えました。

”//” で以下の部分のコードをコメント化します。
インクルードファイルでは,ヘッダーの保管場所も変えて簡単に記載できるように直しています。

//#include "src/Rotary.h"               // http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
#include "Rotary.h"               // http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
//#include "src/si5351.h"               // https://github.com/etherkit/Si5351Arduino, v2.1.0
#include "si5351.h"               // https://github.com/etherkit/Si5351Arduino, v2.1.0
//#include "src/SSD1306AsciiAvrI2c.h"   // https://github.com/greiman/SSD1306Asc
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

////////////////////////////////
// Set Device
////////////////////////////////
Rotary r = Rotary(2, 3);
Si5351 si5351(0x60);                 // Si5351 I2C address
   //SSD1306AsciiAvrI2c oled;
LiquidCrystal_I2C lcd(0x27,16,2);

他コード中のoledのコードはコメント化して、新たな1602用のコードで書き換えで対応できました。

液晶上の送受切替表示、モード表示、周波数表示、ステップ表示、Sメータ表示、コールサインはこんな感じに配置しました。
CIMG8091

もともとの仕様で送受切替SW、ステップ切替SW、バンド切替SWの3つのSWがありますが、最終的には状況で対応します。VFOの機能はまだ深く考えていません。とにかく最初なので、5.500.00~5.000.00MHz(7.000.00~7.500.00MHz)までロータリーエンコーダーで可変できれば良しとします。
その前に、TS-820のVFOの周波数と実際のバンドの対応を見ると、5.5MHzで7.000MHz エッヂの5.000MHzでは7.500MHzとVFOの周波数は下がる方向で7MHzの送受信周波数は上がるので、通常のDDSでは周波数を上げていくと、7.5MHzから下がっていくことになり、具合が悪い動作になってしまします。
先ずは、これを解決する必要があります。TS-820のサービスマニュアルをWEBでダウンロードしてあったので、PLLとVCO辺りを確認してみました。以下の関係がありました。

TRX-FREQ    7.000MHz       7.500MHz
VCO-FREQ  15.830MHz     16.330MHz
VFO-FREQ    5.500MHz        5.000MHz
IF-FREQ        8.830MHz        8.830MHz

HET_FREQ = TRX-FREQ + VFO-FREQ
HET_FREQ=  12.500MHz

このHET-FREQより発振するVFO周波数が得られることがわかります。
DDSで発振する周波数をFREQとするとVFOの発振周波数は

FREQ =(HET_FREQ-FREQ) 

になります。
7.000MHzでは
FREQ=(12.500MHz-7.000MHz) より5.500MHzがVFOのデータとなり、これを送ればよいとなります。
7.200MHzでは
FREQ=(12.500MHz-7.200MHz) より5.300MHz がVFOのデータとなり、これを送ればよいとなります。

上記の理屈から以下の2か所のsi5351Aへの周波数設定部分を次の様に書き換えました


①void loop ()内の周波数設定箇所 


if(Flg_Over == 0){                      // Within transmittable range?
      si5351.output_enable(SI5351_CLK0, 1); // VFO enable
      if(Flg_Vfo == 1){
        //si5351_set_freq(Vfo_Dat + TX_IF);
        si5351_set_freq(HET_FREQ-(Vfo_Dat + TX_IF));      // 2019/sep/22 7Mhz Tx;
        Flg_Vfo = 0;
      }
    }

②si5351 PLL Outputルーチン内の周波数設定箇所の書き換え
//----------  si5351 PLL Output  ---------------------------------------
void si5351_set_freq(uint32_t frequency) {
  //frequency = frequency + awase;
  frequency = HET_FREQ-(frequency + awase); //TS-820 VFO freq set
  Serial.print(frequency);
  Serial.print("\n");
  si5351.set_freq(frequency * SI5351_FREQ_MULT, SI5351_CLK0);
}

①と②のTX_IF やRX_IF、awase 他は宣言で設定します。
送信と受信のオフセットは例では、受信が10.7MHzのオフセットとなっています。自分の装置のIFに合わせて設定できるのでこの機能はとても便利ということですね。
今回は送信も受信も使わないので、設定値は0です。
使うのはHET_FREQの12.500MHzです。

//---- IF offset -------
//const unsigned long RX_IF = 10700000;
const unsigned long RX_IF = 0;
const unsigned long TX_IF = 0;
const unsigned long HET_FREQ = 12500000;  //TS-820 VFO 2019/sep/22
const int awase=40;    //frequency 周波数補正


サンプルのTS-820用外部VFO用の書き換えは以上ですが、他にも変更した箇所があります。アナログポートを一部デジタルポートへ変更しました。
単純に空いているデジタルポートへすれば良いわけではなく、スケッチをよく見てみると、既にデジタルポートの void setup()内でpinModeにて設定済み(割り当て済み)は使えない事になります。
9,10,11,12,13のデジタルポートは使えません。
なので、8,7,4に変更しました。
void setup() {
  Serial.begin(9600);
  pinMode(SW_STEP, INPUT_PULLUP); //INPUT 4
  pinMode(SW_TX, INPUT_PULLUP);   //INPUT 8
  pinMode(SW_BAND, INPUT_PULLUP);  //INPUT 7
  pinMode(9, OUTPUT);                 // Band1         
  pinMode(10, OUTPUT);                //     2         
  pinMode(11, OUTPUT);                //     3          
  pinMode(12, OUTPUT);                // LOW=none, HOGH=CW
  pinMode(13, OUTPUT);                // LOW=USB,  HIGH=LSB         
  attachInterrupt(0, rotary_encoder, CHANGE);
  attachInterrupt(1, rotary_encoder, CHANGE);


下記のSW類です。
入力ポートとして、使えそうなのでA0,A1,A2,を空けました。A3はSメータ入力ポートで使用済み, A4,A5はsi5351のI2C接続で使用済み
もともとのA7はArduino UNOにはないので(miniにはある?手持ちにまだないので?)、入力ポートA3に変更して使用しました。
////////////////////////////////
// I/O Port
////////////////////////////////
//const byte SW_BAND = A0;              // Band SW
//const byte SW_STEP = A1;              // STEP SW
// const byte SW_TX = A2;                // TX/RX
//const byte AD_SM = A7;                // S-meter AD

const byte AD_SM = A3;   // s-meter AD
const byte SW_TX = 8;           // TX/RX
const byte SW_STEP = 7;         // STEP SW
const byte SW_BAND = 4;         //Band SW


他にSメータの表示があります。数値にしてディスプレーに表示してますがが、検討の余地があります。
ほか、オリジナルのスケッチにバンドの下限と上限データがありTX時に範囲外では発振停止という面白いフィーチャーがありました。とても使えます。VFOでは受信も送信もRX状態で使用するので使えませんが、送信機機能のTXスイッチを使用するときは利用できます。(オフバンド考慮)

下限が7.000.00MHz 上限が7.200.00MHzにしておけば、VFOも下限上限を外れると送信時に発振しません。
以上、LEDチカから飛躍のDDSへトライでしたが、スケッチが素晴らしい為、すんなりとVFOが出来そうな感じになりました。まだいろいろと検討が必要なところがあります。Sメータの入力回路(倍電圧整流等)、DDS出力のローパスフィルター、バンド毎のHET_FREQへの自動対応(ハイレベル?)
ヤルことはいっぱいありますが、どれから手をつけていきましょうか?

つづく?