デジタルが一応完成しましたが、さらに改良をくわえました。その2で開示したスケッチは変更しましたので、削除しました。

 

改良点

  1. 表示周波数のずれの補正は、バンドごとでしたが、モードによってキャリヤ周波数(水晶発振子)ことなりますので、ずれの値が異なります。よって、CWモードとUSB,LSBのそれぞれで補正し、メモリ格納し,表示する際にに加減算しますす。操作法は変更なく、現表示バンドモード・について記憶します。設定したのち、「Save」するか、電源offでEEPROMに転送します、
  2. すべての周波数、補正値を初期化できるようにしました。電源をOFFの状態で、「LOCK」SWを押すと,初期化します。表示周波数は下限になりますので、オフバンドに注意が必要です。
  3. Step 設定ですが、OFF→10Hz→100Hz→1kHz→10KH→→OFFとロータリー式に変化しますが、途中でStepSWをピッと鳴るまで長押しするとOFFになります。スケッチの変更部分は次の通りです。
/*****************************************************/
/*      changes the frequency change step            */
/*    10Hz~1kHz まで,トグル動作                */
/*    長押しでOFF                        */
/*****************************************************/
 void Fnc_Step()
 {
int n = 0;
// 長押しでOFF
    while( (digitalRead(SW_STEP) == LOW )){
        if( Flag_Step  == 1){
             delay(100);
            n++;
            if(n > 10){
                beep();
                while( (digitalRead(SW_STEP) == LOW)){ ;
                }
            }
        }
    }
    if (n >10){
        step = 1;
        Flag_Step = 0;
        display_step();
    }else{

        step *= 10;
        Flag_Step = 1;
        if( step > 10000){
            step = 1;
            Flag_Step = 0;
        }
        delay(10);
        display_step();
    }
}

=2024/4/17 追記=



 

スケッチ 
 テキストを貼り付けておきます。

/******************************************************/
// Digtal_VFO_V4R0     T.Nakagawa    2024-02-525
//   CPU : ATmega4809 / 328
//2024/3/20
//    1.V3.0を継承して、CPUを4089用との互換
//    2.バンド、モードのロータリーSWをやめて、プッシュSWによりソフトウエア処理。
//2024/3/22
//    3.Push SWによるアップダウン バンド切り替えと Mode切り替えOK。データメモリは[5]
//    4.4089を換装した。不具合がおおい。再コンパイル必要、
//24/3/23
//    5.3.5,7 bandはLSB,その他はUSBに自動設定。
//24/3/26
//    6. EEPROM アクセス方法簡素化EOPROM.put/get 
//24/4/1 Ver 4.1
//    7.表示周波数補正、バンドのみならず、モードも対応
//    8.memory,EEPROM 初期化(Lock key )
//    9.
/*******************************************************/
#include <avr/sleep.h>
#include "Rotary.h"
#include "si5351.h"
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

#define F_MIN        5000000L    // Lower frequency limit
#define F_MAX         6500000L    

#define DialLock        4     //Memory Return
#define SW_MW        5     //Memory Write
#define SW_MR        6     //Memory Read
#define SW_TX        7   
#define SW_BAND_UP    8    //BAND  切り替えUP
#define SW_BAND_DWN    9    //BAND  切り替えDWN
#define SW_MODE    10    //MODE 切り替え
  
#define    BZ        13    // beep
#define    WakeUp        14    //A0 Wakeup
#define    SW_STEP    15    //A1 ステップの切り替え
#define    SW_RIT        16    //A2 Rit on/off 
#define    SleepMode    17    //A3 Sleep 

/*    ヘテロダイン周波数        */
#define         Ht80        12395000L
#define         Ht40        15895000L
#define         Ht20        22895000L
#define         Ht15        29895000L
#define         Ht10        36895000L
/*    キャリヤー周波数            */
#define         CAR_CW        3395000L
#define        CAR_USB    3396500L
#define         CAR_SB        3393500L

/*     PLL周波数レンジ (CW 時)        */
#define         Edg80Low    5425000L    //3.575
#define         Edg80Upr    5510000L    //3.500
#define         Edg40Low    5300000L    //7.200
#define         Edg40Upr    5510000L    //7.000
#define         Edg20Low    5150000L    //14.350
#define         Edg20Upr    5510000L    //14.000
#define         Edg15Low    5050000L    //21.450
#define         Edg15Upr    5510000L    //212.00
#define         Edg10Low    5000000L    //28.500
#define         Edg10Upr    5510000L    //28.000
//const int EEPadd = 0;        //EEPROM address
const int LOW_RIT = -990;
const int HI_RIT = +990;

// const Rotary Intr Pin
const int A_pin = 2;
const int B_pin = 3;

byte    Flag_Rit = 0;
byte    Flag_Tx = 0;
byte    Flag_Step =0;        // Step が on
byte    Flag_DialLock =0;        //

//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7);     //  LCD  0x27:スレーブアドレス
/*2004:LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows)*/
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
Si5351 si5351;
Rotary r = Rotary(A_pin,B_pin);
/*     キャリヤー周波数廃列        */
volatile    uint32_t        Carrier[3] = {3395000L,3396500L,3393500L};
/*     ヘテロダイン周波数廃列        */
volatile uint32_t         HT[5] = {12395000L,15895000L,22895000L,29895000L,36895000L};    
/*     標示VFO周波数廃列 CW時     */
volatile uint32_t         LowVFO[5] = {5510000L,5510000L,5510000L,5510000L,5510000L};    
volatile uint32_t        ADJ[5][3]={0};         // 表示周波数の補正値[BandStat][ModeStat]
volatile uint32_t         step = 1;                   //  1step の周波数(Hz)

String         strMode = "USB";        // modo文字;
int         RitFreq = 0;
int        BandStat = 0;        // 0,1,2,3,4  80m~10m
int        ModeStat = 0;        // 0,1,2  CW,SSB, LSB
/**************************************************************************************/
/*        SetUp                                        */
/**************************************************************************************/
void setup()
{
//  Serial.begin(19200);
  Serial.begin(9600);
  lcd.setBacklightPin(3, POSITIVE);  
  lcd.setBacklight(LOW);            
  lcd.begin(20,4);                // 表示のカラム×行

  lcd.clear();
  Wire.begin();

 pinMode(A_pin, INPUT_PULLUP);        // 2 RE A
 pinMode(B_pin, INPUT_PULLUP);        // 3  RE B
  pinMode(DialLock, INPUT_PULLUP);      // 4 D.LOCK
  pinMode(SW_MW, INPUT_PULLUP);      // 5 Save
  pinMode(SW_MR, INPUT_PULLUP);       // 6 Load
  pinMode(SW_TX, INPUT_PULLUP);        // 7 TX
  pinMode(SW_BAND_UP, INPUT_PULLUP);    // 8  Band SW 
  pinMode(SW_BAND_DWN, INPUT_PULLUP);    // 9  Band SW 
  pinMode(SW_MODE, INPUT_PULLUP);    // 10 Mode SW

  pinMode(BZ, OUTPUT);            // 13beep
  pinMode(WakeUp, OUTPUT);         // 14 A0 Wakeup;Relay on
  pinMode(SW_STEP, INPUT_PULLUP);    // 15 A1 step
  pinMode(SW_RIT, INPUT_PULLUP);    // 16 A2 Rit
  pinMode(SleepMode, INPUT_PULLUP);    // 17 A3  SleepMode
                    // 18 I2C SDA
                    // 19 I2C SCL
  /*Start serial and initialize the Si5351*/
  si5351.init(SI5351_CRYSTAL_LOAD_8PF);

  /*Set CLK0 to output 5.5MHz with a fixed PLL frequency (VFO_DAT)*/
  si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);

//  vfo_dat= vfo;        // 初期値をPLLデータへ
// si5351.set_freq(vfo_dat, SI5351_PLL_FIXED, SI5351_CLK0);     // 24/2/4 CLK0へ変更

  /*drive can be 2, 4, 6, or 8MA*/
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_6MA);

  /*initialize interrupts on pins 2 and 3*/
 attachInterrupt(digitalPinToInterrupt(A_pin), RotaryEncoder, CHANGE);
 attachInterrupt(digitalPinToInterrupt(B_pin), RotaryEncoder, CHANGE);
// attachInterrupt(digitalPinToInterrupt(SleepMode), SleepIntr,LOW); // only Every 

digitalWrite(WakeUp,HIGH);        // リレー ON

// memory ,EEPROM Initialoize
if ((digitalRead(DialLock) == LOW)){
    initialize();
    FreqDataWrite();
    lcd.setCursor(18,2);
    lcd.print("*_");
}
FreqDataRead();                // 電源 ON時,保存されたデーターを読み出す。

 lcd.setCursor(1,0);
 lcd.print("(    )");                // Mode
    display_mode();            // USB/LSB Mode Disp 
 lcd.setCursor(8,0);
     lcd.print("-VFO- JA5ZZ");        // 
 lcd.setCursor(4,2);
     lcd.print(" step ");
 lcd.setCursor(12,2);
     lcd.print(" rit ");            // 
 lcd.setCursor(1,3); 
     lcd.print("__");            // TX
 lcd.setCursor(15,1); 
     lcd.print("____");            // lock
 beep();
 sei();
}
/***************************************************/
/*   Main program                        */
/***************************************************/
 void loop()
 {


/* 周波数表示    */
    display_frequency    ();        // Frequency disp

/* ダイヤルロック*/
    if ((digitalRead(DialLock) == LOW)){
        Flag_DialLock = (Flag_DialLock ?  0 : 1);
        lcd.setCursor(15,1);
        if(Flag_DialLock ==1){
            lcd.print("lock");    
        }else{
            lcd.print("____");    
        }
        beep();
        while(digitalRead(DialLock) == LOW){
            delay(10);
        }
    }

/* Sleep,Power Down処理*/
    if (digitalRead(SleepMode) == LOW){
        beep();
        PowerDown();    
    }

/* STEP 設定*/
    if (digitalRead(SW_STEP) == LOW) {
        beep();
        Fnc_Step();
    }

/* RIT 設定*/
    if (digitalRead(SW_RIT) == LOW) {
        beep();
        Fnc_Rit();
     }
    Fnc_Rit_Disp();

/* EPROMへセーブ */
    if (digitalRead(SW_MW) == LOW) {
        beep();
        if (digitalRead(SW_MW) == LOW){
            FreqDataWrite();
        }
        while(digitalRead(SW_MW) == LOW){
            delay(10);
        }

    }

/* EPROMからロード */
    if (digitalRead(SW_MR) == LOW) {
        beep();
        if(digitalRead(SW_MR)== LOW){
            FreqDataRead(); 
        }
        while(digitalRead(SW_MR) == LOW){
            delay(10);
        }
    }


/* 送信チェック */
    if (digitalRead(SW_TX) == LOW){
        delay(10);
        Flag_Tx = 1;
        lcd.setCursor(1,3);
        lcd.print("TX");
        delay(10);
        while(digitalRead(SW_TX) == LOW){
        }
    }else{
        Flag_Tx = 0;
        lcd.setCursor(1,3);
        lcd.print("__");
    }    
/* PLL  Freq data set */
    Fnc_Dds();

/* Band UP  SW */
    if (digitalRead(SW_BAND_UP) == LOW) {
        beep();
        Fnc_Band_UP();
    }
/* Band DWN  SW */
    if (digitalRead(SW_BAND_DWN) == LOW) {
        beep();
        Fnc_Band_DWN();
    }

/* Mode SW */
    if (digitalRead(SW_MODE) == LOW){
        beep();
        Fnc_Mode();        // USB/LSB Mode Dis 
    }
 }
/**********************************************************/
/*          Power \down Sleep                 */
/*      Freq Data ,BandStat,ModeSTatを EEPROM に退避する        */
/**********************************************************/
void     PowerDown()
{
/* 割り込み要因 SleepMode not use */
    sleep_enable();
    FreqDataWrite();
    delay(100);
    lcd.noDisplay();
    lcd.noBacklight();
    digitalWrite(WakeUp,LOW);  // 電源リレー OFF  以下は実行されない
    sleep_cpu();
     while (1){
    ;
    }
}
/**********************************************************/
/*        周波数データ EPROM からロード                */
/*       4byte(long値)× 5 Field ×2 Recode + 2Byte            */
/**********************************************************/
void FreqDataRead()
{
//VFO 周波数 load
    for(int n=0;n<5;n++){
        EEPROM.get(n *4,LowVFO[n]);
    }
//ADJ値Load 
    int adr=20;
    for(int n=0;n<5;n++){
        for(int m=0; m<3; m++){
            EEPROM.get(adr,ADJ[n][m]);
            adr +=4;
        }
    }
// BandStat & ModeStat Load 1byte
    BandStat = EEPROM.read(60);
    ModeStat = EEPROM.read(61);

    lcd.setCursor(18,3);
    lcd.print("*L");
}
/**********************************************************/
/*        周波数データ EPROM へセーブ                */
/*       4byte(long値)× 5 Field ×2 Recode    + 2byte            */
/**********************************************************/
void FreqDataWrite()
{
// 周波数データ save
    for(int n=0;n<5;n++){
        EEPROM.put(n *4,LowVFO[n]);
    }
    
//ADJ値Save  Each Baand & Mode
    int adr=20;
    for(int n=0;n<5;n++){
        for(int m=0;m<3;m++){
            EEPROM.put(adr,ADJ[n][m]);
            adr +=4;    // adr  (20+n*4+m*4) NG ?    
        };
    }
// BandStat & ModeStat Save 1byte
    EEPROM.write(60, BandStat);
    EEPROM.write(61, ModeStat);

    lcd.setCursor(18,2);
    lcd.print("*S");
}
/**********************************************************/
/*     Interrupt service routine for  encoder               */
/*      frequency change     ISR(PCINT2_vect)            */
/**********************************************************/
void RotaryEncoder()
 {
 unsigned char result = r.process();
    if (!Flag_DialLock && !Flag_Tx){
        if (result == DIR_CW) {    // 右回り 増加
             if ((Flag_Rit == 1) &&  (digitalRead(SW_TX) == HIGH)) {
                RitFreq = RitFreq - 1;
            } else {
                if (Flag_Step){
                    LowVFO[BandStat] = LowVFO[BandStat]-step;
                }else{
                    LowVFO[BandStat] = LowVFO[BandStat]-1;
                }
            }
         } else {
            if (result == DIR_CCW) {        // 左回り 減
                if ((Flag_Rit == 1) &&  (digitalRead(SW_TX) == HIGH)) {
                    RitFreq = RitFreq + 1;
                } else {
                    if (Flag_Step){
                        LowVFO[BandStat] = LowVFO[BandStat] + step;
                    }else{
                        LowVFO[BandStat] = LowVFO[BandStat] +1;
                    }
                }
            } 
        }
        RitFreq = constrain(RitFreq, LOW_RIT, HI_RIT);
        LowVFO[BandStat] = constrain(LowVFO[BandStat], 4900000L, 5510000L);
    }
}
/**********************************************************/
/*     Displays the frequency                    */
/*      local memory 32Bit                    */
/**********************************************************/
 void display_frequency()
 {
  uint32_t     f, f1, f2,f3,f4;
  char buff[6];

    // テロダインf-(vfo+キャリヤー) = 送受信周波数、表示周波数はADJで補正    
      f = (HT[BandStat] - LowVFO[BandStat] - Carrier[ModeStat]) +( ADJ[BandStat][ModeStat]);
//    Serial.println(ADJ[BandStat][ModeStat]);
//    Serial.println(f);
    f1 = f / 1000000;        //**MHz
    f2 = f % 1000000;
    f3 = f2 /  1000;          //f3=***kHz
    f4 = f2 % 1000;        //f4=***Hz
//     LCD表示
    lcd.setCursor(1,1);
    sprintf(buff,"%2d,",f1);
    lcd.print(buff);
    sprintf(buff,"%03d,",f3);
    lcd.print(buff);
    sprintf(buff,"%03dHz",f4);
    lcd.print(buff);
}
/**********************************************************/
/*      changes the frequency change step                */
/*    10Hz~1kHz まで,トグル動作                */
/**********************************************************/
 void Fnc_Step()
 {
    step *= 10;
    Flag_Step =-1;
    if( step > 10000){
        step = 1;
        Flag_Step = 0;
    }
    delay(10);
    display_step();
    while (digitalRead(SW_STEP) == LOW) {
        delay(10);
    }
 }
/**********************************************************/
/*      changes the Band UP                    */
/*    80m~10m まで,トグル動作                */
/**********************************************************/
 void Fnc_Band_UP()
 {
    if( (BandStat += 1) >4){
        BandStat = 0;
    }
    if(BandStat == 0 ||  BandStat ==1){
        ModeStat = 2;        // LSB
    }else{
        ModeStat = 1;        // USB
    }
 
    while (digitalRead(SW_BAND_UP) == LOW) {
        delay(10);
    }
    display_frequency();
      display_mode();        // USB/LSB Mode Dis 
}
/**********************************************************/
/*      changes the Band Down                    */
/*    80m~10m まで,トグル動作                */
/**********************************************************/
 void Fnc_Band_DWN()
 {
    if( (BandStat -= 1)  < 0){
        BandStat = 4;
    }
    if(BandStat == 0 || BandStat ==1){
        ModeStat = 2;        // LSB
    }else{
        ModeStat = 1;        // USB
    }

    while (digitalRead(SW_BAND_DWN) == LOW) {
        delay(10);
    }
    display_frequency();
     display_mode();        // USB/LSB Mode Dis +
}
/**********************************************************/
/*      changes the Mode                        */
/*    CW,USB, LSB まで,トグル動作                */
/**********************************************************/
 void Fnc_Mode()
 {
    ModeStat += 1;
    if( ModeStat > 2){
        ModeStat = 0;
    }
    while (digitalRead(SW_MODE) == LOW) {
        delay(10);
    }
     display_mode();        // USB/LSB Mode Dis 
}
/**********************************************************/
/*     Step 周波数表示                        */
/*     Displays the frequency change step                 */
/**********************************************************/
void display_step()
{
char strStep[8] ;

    switch (step)    {
        case 1:
            sprintf(strStep,"      ");
            break;
        case 10:                    // 10Hz
            sprintf(strStep,"%4dHz",step);
            break;
        case 100:                // 100Hz
            sprintf(strStep,"%4dHz",step);
            break;
        case 1000:                // 1kHz
            sprintf(strStep,"%3dkHz",step/1000);
            break;
        case 10000:                // 10kHz
            sprintf(strStep,"%3dkHz",step/1000);
            break;
    }
    lcd.setCursor(4, 3);
    lcd.print(strStep);
}
/**********************************************************/
/*    RIT 設定                            */
/*        RIT                            */
/**********************************************************/
 void Fnc_Rit()
 {
    if (Flag_Rit == 1) {
        Flag_Rit = 0;
    } else {
        Flag_Rit = 1;
    }
    delay(10);
    Fnc_Rit_Disp();
    while (digitalRead(SW_RIT) == LOW) {
        delay(10);
    }
 }
/**********************************************************/
/*    RIT 表示    & 周波数補正                    */
/*     Rit_Disp    &                        */
/**********************************************************/
 void Fnc_Rit_Disp() 
 {
 int n=0;
 char Rit_F[8];
    if (Flag_Rit == 1) {
            sprintf(Rit_F,"%4dHz", RitFreq*-1);
    } else {
// 長押しで補正 adj
        while( (digitalRead(SW_RIT) == LOW)){
             delay(100);
            n++;
            if(n > 10){
                beep();
                while( (digitalRead(SW_RIT) == LOW)){ ;
                }
            }
        }
        if (n >10){
            RitFreq =RitFreq*-1;
            ADJ[BandStat][ModeStat] += RitFreq;
        } else {
            sprintf(Rit_F,"%s","      " ); 
            RitFreq = 0;
        }
    }
    lcd.setCursor(12,3);
    lcd.print(Rit_F);
 }
/**********************************************************/
/*    Dds out                            */
/*     Rit on RX時のみ加算する。step は RE intraで加算されている    */ 
/**********************************************************/
 void Fnc_Dds() 
{
 uint32_t   n = 0;
    
    if (!Flag_Rit && !Flag_Tx){
        si5351.set_freq(LowVFO[BandStat], SI5351_PLL_FIXED, SI5351_CLK0);
        n=LowVFO[BandStat];
    }else{
        si5351.set_freq((LowVFO[BandStat])+ RitFreq, SI5351_PLL_FIXED, SI5351_CLK0);
        n=LowVFO[BandStat]+RitFreq;
    }
//    Serial.println(n);
}  

/**********************************************************/
/*      Mode_Display                        */
/**********************************************************/
 void display_mode() 
 {
    switch    (ModeStat){
        case    0:
            strMode =  "CW ";
            break;
        case    1:
            strMode = "USB";
            break;
        case    2:
            strMode = "LSB";
            break;
        default:
            break;
    }
     lcd.setCursor(2, 0);
    lcd.print(strMode);
}
/**********************************************************/
/*    beep                            */
/**********************************************************/
void beep()
{
    digitalWrite(BZ,HIGH);
    delay(10);
    digitalWrite(BZ,LOW);
}
/**********************************************************/
/*    memori    イニシャライズ                    */
/**********************************************************/
void    initialize()
{
// 周波数データ
    for(int n=0;n<5;n++){
        LowVFO[n]= 5510000L;
    }
//ADJ値
    for(int n=0;n<5;n++){
        for(int m=0;m<3;m++){
            ADJ [n][m]=0L;
        }
    }
// BandStat & ModeStat 
     BandStat=0;
     ModeStat=0;
}
/********************** end of Program ***********************/