domingo, 31 de maio de 2026

DDS VFO 10kHz 225MHz Júlio Cesar Atualizado 2026.

Vocês, que curte e gosta dos projetos do blog, por gentileza olhem às propagandas e click para maiores detalhes no que interessar, desta forma vocês estarão ajudando o blog. Muito obrigado por acessar e ajudar o blog, conto com vocês muito agradecido.
Olá amigos radioamadores e entusiastas da eletrônica, estou compartilhando modificações que fiz no conhecido projeto código livre no excelente trabalho de autoria do Sr. Júlio Cesar (CesarSound), meus sinceros agradecimentos pelo desenvolvimento e divulgação deste projeto o famoso 10 kHz a 225 MHz versão 2. a quem tem ajudado centenas ou milhares de colegas a desenvolverem seus equipamentos. Este de 2021 é mais famoso, até copiado pelos Chineses, mais publicado e modificado esboço DDS VFO com Arduíno Nano da década. Tive a ousadia, e para mim que sou iniciante e aprendiz é um privilégio em perder tempo para fazer algumas atualizações neste esboço que roda o mundo. Não tenho muito que escrever sobre este conhecido programa, as minhas atualizações que fiz desde o começo deste mês de Abril, tive como objetivo melhorar a operação diária do equipamento e adaptar algumas funções ás minhas necessidades. Tive que gravar mais de 30 vezes no meu pobre Arduíno Nano Atmega 328P laboratório que faço minhas experiências e atualizo os esboços escolhidos. Ano passado pesquisando este esboço, descobrir o site wokwi.com, onde podemos simular alguns projetos com Arduíno, não conseguir fazer nada por lá, partir para prática em contato com os componentes físicos. Queria que todos que acessam nosso blog, canal no YouTube, soubesse de meu interesse em incentivar a todos fazerem modificações em projetos eletrônicos como: Receptores, transmissores, transceptores, transverteres, outros, e agora em esboços DDS VFO com Arduíno Oled. Não é fácil, mas se você não tentar, persistir, ter força de vontade, tudo na sua vida será difícil. Posso dá meu exemplo, pois há um ano atrás eu não sabia nem como era para instalar um esboço no Arduíno. Melhor eu não sabia nem o que era esboço e sketch, não sabia a diferença, e ás bibliotecas não sabia para que servia, era uma confusão esboço, sketch, bibliotecas, mas fui pesquisando e hoje já consigo fazer o que trago para vocês, não sou um programador, sou apenas um simples amante da eletrônica antiga e que está vivendo com esta nova eletrônica digital, tenho que pegar o bonde andando, pois a tecnologia não para e se eu ficar olhando perderei o bonde e ficarei desatualizado na vida. 
Modificações realizadas nestes esboços:
Ajuste no STEP 1HZ até 2 MHz com melhor deslocamento 
máximo e mínima nas frequências. Desenvolvido em comentários pelo autor Sr. Júlio Cesar.

Alterações no S/Meter para obter leitura visual mais agradável e melhor distribuição da escala S1 a +30dB estilo Cobra 148 GTL. Pesquisada outros esboços e desenvolvida por Waldir Cardoso.

Implementação da tecla D10 para melhor seleção e avanço das bandas operação rápida e indutiva. Pesquisada outros esboços e desenvolvida por Waldir Cardoso.

Implementação da EEPROM: Para memorizar última visualização e apresentação total em todo display. Pesquisada outros esboços e desenvolvida por Waldir Cardoso.

Espero que estas atualizações neste projeto possam ajudar outros colegas que estejam desenvolvendo seus próprios transceptores ou personalizando seus próprios projetos, e mês que vem continuarei com mais atualização para AM, LSB, USB neste mesmo esboço.
Agradeço mais uma vez ao Sr. Júlio Cesar (CesarSound) pelo excelente trabalho original e a todos amigos que acessam compartilham meu canal no YouTube e blog.

Primeiro esboço no display  S/Meter com escala total até +30dB, muito melhor e com sensibilidade reduzida a escala gráfica medição começando no "SIG", coloquei nas bandas D10 para subir Ex: 16m pressionando o botão passa para 19m, o original desce ás bandas e sobe frequência. E o que eu mais queria a EEPROM, conseguir colocar nos dois esboços. Porem no STEP se vocês quiserem que sempre inicialize cada banda em 10 kHz, faça: No final de void setup, desabilite só load_memory(); e habilite ás: stp = 5;fstep = 10000;
Fica assim abaixo.
//load_memory();
//Para iniciar sempre em 10kHz habilite ás duas funções abaixo.
  stp = 5;
  fstep = 10000;
  tunegen();
}
No ganho do S/Meter o autor já fez uma tabela de ganho em definir: //#define S_GAIN 303, desabilitei essa que tem mais ganho e habilitei: #define S_GAIN 505, com menos ganho. Porem eu fiz uma atualização ou modificação com filtro contra ruídos e redução de sensibilidade. No final do esboço, abaixo de'  void sgnalread() 
Ajuste a sensibilidade como quiser do S/Meter com a entrada de sinal colocando 2 resistores e um capacitor para GND negativo, no esboço logo acima ou nas etapas do esboço final. Ajuste pelo seu transceptor, ou com Manual serviço cobra 148 GTL. em português.
Em todos esboços onde estiver // comentário poderá ser ou não habilitada se for do interesse.
Vejam ás fotos abaixo, não é tão fácil assim, mas todos podem fazer suas próprias modificações ou atualizações em um esboço escolhido para seu transceptor, receptor ou gerador RF. 

A inicialização como todos vai este.
Já havia feito alguns testes para S/Meter, vejam que estou ajustando para ver como vai ficar.
Estou tentando colocar os traços a cada números que não tem. 
 Já adicionei IF CLK1, estou tentando ajustar tudo.
Assim está melhor vou procurar ajustar o IF subir um pouco, S/Meter que fica melhor no rodapé.
Agora acho que está bom, vamos ver se faço algo mais.
Acho que o S/Meter está bem próximo da linha acima, vou subir mais a linha e tudo.
Ainda resta subir mais o 11m, RX, e subir um pouco mais a escala S/Meter.
Agora sim está bom, o RX dá para subir mais um pouco, veja o S/Meter funcionando com barras começando depois do SIG. Vou ver se consigo juntar mais ás barras.
O S/Meter acima ficou show de bola, agora partir para outro S/Meter, ainda estou ajustando.
Tá um pouco difícil, este S/Meter não é original do Júlio Cesar, peguei de outro sketch.
É tá difícil, mas eu vou conseguir, se meu Arduino ainda gravar eu consigo.
Agora sim conseguir, ai está o S/Meter de barras juntas e melhor.
Veja agora com um tracinho de picos, vejam que já centralizei os caracteres nomes e números.
Agora com IF CLK1, devido a interferências do próprio programa e componentes na montagem ele está sensível, está muito bom vou reduzir sua sensibilidade em 50%.
Esquema atualizado periféricos DDS VFO 10kHz a 225MHz 2026.
Selecione todo sketch, copie e cole. Abra Arduino IDE vá em "Arquivo" depois "Novo", ou ícone ao lado da seta para "Carregar ou Compilar, abra um novo delete todas ás linhas e cole este sketch, renomeei com final .ino se preferir e salve em uma pasta. adicione todas ás bibliotecas. Lembre-se que muitas bibliotecas para o mesmo arquivo pode causar conflitos e provocar erros na compilação. 
Primeiro sketch abaixo.
/**********************************************************************************************************
  10kHz to 225MHz VFO / RF Generator with Si5351 and Arduino Nano, with Intermediate Frequency (IF) offset
  (+ or -), RX/TX Selector for QRP Transceivers, Band Presets and Bargraph S-Meter. See the schematics for
  wiring and README.txt for details. By J. CesarSound - ver 2.0 - Feb/2021.
***********************************************************************************************************/
// Sketch 10kHz to 225MHz autor Júlio Cesar, modificado por Waldir Cardoso Blog:https://projetosetransceptores.blogspot.com/
// Este sketch está com CLK0 em RX 34.765 Mhz, TX em 26.965 Mhz.
// STEP 1Hz 10Hz 1kHz 10kHz 100kHz 1MHz 1.5MHz 2MHz.
// Bandas + - sobe pino D10 banda desce pino A1. 
// S/Meter menos sensível e contra ruídos escala Cobra 148 GTL começo final SIG.
// EEPROM Memoria total ao desligar salva última apresentação no display.
// O sketch usa 26982 bytes (87%) de armazenamento (34%) memória dinâmica com biblioteca PU2REO_Si5351Lite.h.

//Libraries
#include <EEPROM.h>
#include <Wire.h>                 //IDE Standard
#include <Rotary.h>               //Ben Buxton https://github.com/brianlow/Rotary
#include <SPI.h>
//#include "PU2REO_Si5351Lite.h"    //https://github.com/PU2REO/PU2REO_Si5351Lite
#include <si5351_lite.h>
//#include <si5351.h>               //Etherkit https://github.com/etherkit/Si5351Arduino
#include <Adafruit_GFX.h>         //Adafruit GFX https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h>     //Adafruit SSD1306 https://github.com/adafruit/Adafruit_SSD1306

//User preferences
//------------------------------------------------------------------------------------------------------------
#define IF         7800      //Enter your IF frequency, ex: 455 = 455kHz, 10700 = 10.7MHz, 0 = to direct convert receiver or RF generator, + will add and - will subtract IF offfset.
#define BAND_INIT  15        //Enter your initial Band (1-21) at startup, ex: 1 = Freq Generator, 2 = 800kHz (MW), 7 = 7.2MHz (40m), 11 = 14.1MHz (20m). 
#define XT_CAL_F   18000     //Si5351 calibration factor, adjust to get exatcly 10MHz. Increasing this value will decreases the frequency and vice versa.
//#define S_GAIN     303       //Adjust the sensitivity of Signal Meter A/D input: 101 = 500mv; 202 = 1v; 303 = 1.5v; 404 = 2v; 505 = 2.5v; 1010 = 5v (max).
#define S_GAIN     505       //Adjust the sensitivity of Signal Meter A/D input: 101 = 500mv; 202 = 1v; 303 = 1.5v; 404 = 2v; 505 = 2.5v; 1010 = 5v (max).
#define tunestep   A0        //The pin used by tune step push button.
#define band       A1        //The pin used by band selector push button.
#define rx_tx      A2        //The pin used by RX / TX selector switch, RX = switch open, TX = switch closed to GND. When in TX, the IF value is not considered.
#define adc        A3        //The pin used by Signal Meter A/D input.
#define band_dn    10        //Banda - D10 botão LOW, banda sobe e frequência desce.
//------------------------------------------------------------------------------------------------------------

Rotary r = Rotary(2, 3);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
Si5351 si5351(0x60); //Si5351 I2C Address 0x60

unsigned long freq, freqold, fstep;
long interfreq = IF, interfreqold = 0;
long cal = XT_CAL_F;
unsigned int smval;
byte encoder = 1;
byte stp, n = 1;
byte count, x, xo;
bool sts = 0;
unsigned int period = 100;
unsigned long time_now = 0;

//=======EEPROM============
#define EEPROM_ADDR_FREQ   0
#define EEPROM_ADDR_STEP   8
#define EEPROM_ADDR_BAND   12

unsigned long last_saved_freq = 0;
byte last_saved_step = 0;
byte last_saved_band = 0;


ISR(PCINT2_vect) {
  char result = r.process();
  if (result == DIR_CW) set_frequency(1);
  else if (result == DIR_CCW) set_frequency(-1);
}

void set_frequency(short dir) {
  if (encoder == 1) {                         //Up/Down frequency
    if (dir == 1) freq = freq + fstep;
    if (freq >= 225000000) freq = 225000000;
    if (dir == -1) freq = freq - fstep;
    if (fstep == 1000000 && freq <= 1000000) freq = 1000000;
    else if (freq < 10000) freq = 10000;
  }
  if (encoder == 1) {                       //Up/Down graph tune pointer
    if (dir == 1) n = n + 1;
    if (n > 42) n = 1;
    if (dir == -1) n = n - 1;
    if (n < 1) n = 42;
  }
}

//=======EEPROM===Salva frequencia step banda====
void save_memory() {
  if (freq != last_saved_freq) {
    EEPROM.put(EEPROM_ADDR_FREQ, freq);
    last_saved_freq = freq;
  }

  if (stp != last_saved_step) {
    EEPROM.update(EEPROM_ADDR_STEP, stp);
    last_saved_step = stp;
  }

  if (count != last_saved_band) {
    EEPROM.update(EEPROM_ADDR_BAND, count);
    last_saved_band = count;
  }
}

void load_memory() {
  EEPROM.get(EEPROM_ADDR_FREQ, freq);
  stp = EEPROM.read(EEPROM_ADDR_STEP);
  count = EEPROM.read(EEPROM_ADDR_BAND);

  if (freq < 10000 || freq > 225000000) freq = 26965000;
  if (stp < 1 || stp > 8) stp = 4;
  if (count < 1 || count > 21) count = BAND_INIT;

  // Carrega STEP sem mudar stp
  switch (stp) {
    case 1: fstep = 2000000; break;
    case 2: fstep = 1; break;
    case 3: fstep = 10; break;
    case 4: fstep = 1000; break;
    case 5: fstep = 10000; break;
    case 6: fstep = 100000; break;
    case 7: fstep = 1000000; break;
    case 8: fstep = 1500000; break;
    default:
      stp = 4;
      fstep = 1000;
      break;
  }

  last_saved_freq = freq;
  last_saved_step = stp;
  last_saved_band = count;
}

void setup() {
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.display();

  //Inicialização Cobra 148GTL
  display.clearDisplay();
  display.setTextSize(2); 
  display.setCursor(9, 10);
  display.print("Cobra 148");
  display.setCursor(45, 40);
  display.print("GTL");
  display.display(); 
  delay(2000);
  
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(tunestep, INPUT_PULLUP);
  pinMode(band, INPUT_PULLUP);
  pinMode(rx_tx, INPUT_PULLUP);
  pinMode(band_dn, INPUT_PULLUP);

  //statup_text();  //If you hang on startup, comment

  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
  si5351.set_correction(cal, SI5351_PLL_INPUT_XO);   //Correção em define Si5351 
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);  
  //si5351.drive_strength(SI5351_CLK1, SI5351_DRIVE_6MA);
  si5351.output_enable(SI5351_CLK0, 1);    //1 - Enable / 0 - Disable CLK1
  //si5351.output_enable(SI5351_CLK1, 0);    //1 - Enable / 0 - Disable CLK1

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

  load_memory();
  //Para iniciar sempre em 10kHz habilite ás duas funções abaixo.
  //stp = 5;
  //fstep = 10000;
  tunegen();
}

void loop() {

   //======SI5351========
  //si5351.output_enable(SI5351_CLK0, 1);
  //si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_6MA);  
  
  if (freqold != freq) {
    time_now = millis();
    tunegen();
    freqold = freq;
  }

  if (interfreqold != interfreq) {
    time_now = millis();
    tunegen();
    interfreqold = interfreq;
  }

  if (xo != x) {
    time_now = millis();
    xo = x;
  }

   // Botão STEP encoder
  if (digitalRead(tunestep) == LOW) {
    time_now = (millis() + 300);
    setstep();
    delay(300);
  }
   
   // Botão BAND desce banda e sobe frequência.
  if (digitalRead(band) == LOW) {
    time_now = (millis() + 300);
    inc_preset();
    delay(300);
  }
  
   // Botão + Band sobe banda e desce frequência.
  if (digitalRead(band_dn) == LOW) {
    time_now = (millis() + 300);
    dec_preset();
    delay(300);
 }

   // RX/TX
  if (digitalRead(rx_tx) == LOW) {
    time_now = (millis() + 300);
    sts = 1;
  } else sts = 0;

  if ((time_now + period) > millis()) {
    displayfreq();
    layout();
  }
  save_memory();
  sgnalread();
}

void tunegen() {
  si5351.set_freq((freq + (interfreq * 1000ULL)) * 100ULL, SI5351_CLK0);
 }

void displayfreq() {
  unsigned int m = freq / 1000000;
  unsigned int k = (freq % 1000000) / 1000;
  unsigned int h = (freq % 1000) / 1;

  display.clearDisplay();
  display.setTextSize(2);

  char buffer[15] = "";
  if (m < 1) {
    display.setCursor(41, 1); sprintf(buffer, "%003d.%003d", k, h);
  }
  else if (m < 100) {
    display.setCursor(5, 1); sprintf(buffer, "%2d.%003d.%003d", m, k, h);
  }
  else if (m >= 100) {
    unsigned int h = (freq % 1000) / 10;
    display.setCursor(5, 1); sprintf(buffer, "%2d.%003d.%02d", m, k, h);
  }
  display.print(buffer);
}

void setstep() {
  switch (stp) {
  case 1: stp = 2; fstep = 1; break;
  case 2: stp = 3; fstep = 10; break;
  case 3: stp = 4; fstep = 1000; break;
  case 4: stp = 5; fstep = 10000; break;
  case 5: stp = 6; fstep = 100000; break;
  case 6: stp = 7; fstep = 1000000; break;
  case 7: stp = 8; fstep = 1500000; break;
  case 8: stp = 1; fstep = 2000000; break;
  }
}

void inc_preset() {
  count++;
  if (count > 21) count = 1;
  bandpresets();
  save_memory();
  delay(50);
}

void dec_preset() {
  if (count <= 1) count = 21;
  else count--;
  bandpresets();
  save_memory();
  delay(50);
}

void bandpresets() {
  switch (count)  {
    case 1: freq = 100000; tunegen(); break;
    case 2: freq = 800000; break;
    case 3: freq = 1800000; break;
    case 4: freq = 3650000; break;
    case 5: freq = 4985000; break;
    case 6: freq = 6180000; break;
    case 7: freq = 7200000; break;
    case 8: freq = 10000000; break;
    case 9: freq = 11780000; break;
    case 10: freq = 13630000; break;
    case 11: freq = 14100000; break;
    case 12: freq = 15000000; break;
    case 13: freq = 17655000; break;
    case 14: freq = 21525000; break;
    case 15: freq = 26965000; break;
    case 16: freq = 28400000; break;
    case 17: freq = 50000000; break;
    case 18: freq = 100000000; break;
    case 19: freq = 130000000; break;
    case 20: freq = 144000000; break;
    case 21: freq = 220000000; break;
  }
  si5351.pll_reset(SI5351_PLLA);
  save_memory();  // Salva o STEP na memória ao desligar.
}

void layout() {
  display.setTextColor(WHITE);
  display.drawLine(0, 20, 127, 20, WHITE);   // Linha orizontal abaixo da frequência.
  display.drawLine(0, 43, 127, 43, WHITE);   // Linha orizontal abaixo do STEP.
  display.drawLine(105, 24, 105, 39, WHITE); //Linha vertical que divide RX e MHz
  display.drawLine(87, 24, 87, 39, WHITE);   //Linha vertical que divide STEP e RX
  //display.drawLine(87, 48, 87, 63, WHITE);   //Linha vertical que divide S/meter e IF
  display.drawLine(0, 55, 127, 55, WHITE);   //Linha horizontal de baixo S/Meter.
  //display.drawLine(15, 55, 82, 55, WHITE);   // Linha vertical de TU 
  display.setTextSize(1);          // Tamanho da fonte.
  display.setCursor(57, 23);       // Posição nome STEP display.
  //display.setCursor(59, 23);
  display.print("STEP");           // Imprime nome STEP display.
  display.setCursor(48, 33);       // Posição caracteres números STEP display.
  //display.setCursor(54, 33);
  if (stp == 2) display.print("   1Hz");
  if (stp == 3) display.print("  10Hz");
  if (stp == 4) display.print("  1kHz");
  if (stp == 5) display.print(" 10kHz");
  if (stp == 6) display.print("100kHz");
  if (stp == 7) display.print("  1MHz");
  if (stp == 8) display.print("1.5MHz");
  if (stp == 1) display.print("  2MHz");
  display.setTextSize(1);          // Tamanho da fonte.
  display.setCursor(0, 46);        //Posição IF caracteres nome disaplay. Acima do rodapé.
  //display.setCursor(0, 57);        //Posição IF caracteres nome disaplay. Abaixo display.
  //display.setCursor(92, 48);
  display.print("IF:");            // IF só em CLK0 RX TX.
  //display.print("IF CLK1:");       //IF e CLK1 habilitada caracteres nome no display.
  //display.setCursor(48, 44);       // Posição números Frequência IF CLK1: caracteres. Acima do rodapé.
  display.setCursor(25, 46);       // Posição números Frequência IF caracteres. Acima do rodapé.
  //display.setCursor(55, 57);       // Posição números Frequência IF caracteres. Abaixo display.
  display.print(interfreq);
  display.print("kHz");            //Caracteres nome kHz.
  display.setTextSize(1);
  display.setCursor(110, 23);
  if (freq < 1000000) display.print("kHz");
  if (freq >= 1000000) display.print("MHz");
  display.setCursor(110, 33);
  if (interfreq == 0) display.print("VFO");
  if (interfreq != 0) display.print("L O");
  display.setCursor(91, 27);
  if (!sts) display.print("RX"); if (!sts) interfreq = IF;
  if (sts) display.print("TX"); if (sts) interfreq = 0;   //0 ou IF desabilita e IF habilita IF em CLK1 em TX. 
  bandlist(); drawbargraph();
  display.display();
}

void bandlist() {
  display.setTextSize(2);
  display.setCursor(0, 24);
  if (count == 1) display.print("GEN"); if (count == 2) display.print("MW"); if (count == 3) display.print("160m"); if (count == 4) display.print("80m");
  if (count == 5) display.print("60m"); if (count == 6) display.print("49m"); if (count == 7) display.print("40m"); if (count == 8) display.print("31m");
  if (count == 9) display.print("25m"); if (count == 10) display.print("22m"); if (count == 11) display.print("20m"); if (count == 12) display.print("19m");
  if (count == 13) display.print("16m"); if (count == 14) display.print("13m"); if (count == 15) display.print("11m"); if (count == 16) display.print("10m");
  if (count == 17) display.print("6m"); if (count == 18) display.print("WFM"); if (count == 19) display.print("AIR"); if (count == 20) display.print("2m");
  if (count == 21) display.print("1m");
  if (count == 1) interfreq = 0; else if (!sts) interfreq = IF;
}

void sgnalread() {
  long soma = 0;
  // Faz média de 8 leituras (reduz sensibilidade e ruído)
  for (byte i = 0; i < 8; i++) {   //Para o original do autor.
  //for (byte i = 0; i < 16; i++) {  //Barra mais lenta e estável.
    soma += analogRead(adc);
    delayMicroseconds(200);
  }
  smval = soma / 8;    // Para o original autor. //#define S_GAIN 303 
  //smval = soma / 20; // Elimina os sinais fracos e ruídos próximos a zero.
  //smval = soma / 30; // Elimina os sinais fracos e ruídos próximos a zero.
  
  // Pequena zona morta (ignora sinais muito fracos)
  if (smval < 8) smval = 0; // Para o original autor. //#define S_GAIN 303 
  //if (smval < 20) smval = 0; // Elimina os sinais fracos e ruídos próximos a zero.
  //if (smval < 30) smval = 0; // Elimina os sinais fracos e ruídos próximos a zero.
  x = map(smval, 0, S_GAIN, 1, 36);

  if (x > 36) x = 36;
  if (x < 1) x = 1;
}  

void drawbargraph() {
  byte y = map(n, 1, 42, 1, 36);  // Começo e final da escal até 30dB
  //byte y = map(n, 1, 42, 1, 14);
  display.setTextSize(1);

  //Pointer. Ponteiro
  display.setCursor(0, 57); display.print("SIG.1.3.5.7.9...+30dB"); // Escala S/Meter rodapé.
  //display.setCursor(0, 46); display.print("SIG.1.3.5.7.9...+30dB");  //Escala S/Meter acima do rodadapé.
  //display.setCursor(0, 48); display.print("TU");

  //Bargraph
  switch (x) {       
    case 36: display.fillRect(121, 57, 2, 6, WHITE);  // Até dB final da escala.
    case 35: display.fillRect(118, 57, 2, 6, WHITE);
    case 34: display.fillRect(115, 57, 2, 6, WHITE);
    case 33: display.fillRect(112, 57, 2, 6, WHITE);
    case 32: display.fillRect(109, 57, 2, 6, WHITE);    
    case 31: display.fillRect(106, 57, 2, 6, WHITE);
    case 30: display.fillRect(103, 57, 2, 6, WHITE);
    case 29: display.fillRect(100, 57, 2, 6, WHITE);
    case 28: display.fillRect(97, 57, 2, 6, WHITE);
    case 27: display.fillRect(94, 57, 2, 6, WHITE);
    case 26: display.fillRect(91, 57, 2, 6, WHITE);
    case 25: display.fillRect(88, 57, 2, 6, WHITE);
    case 24: display.fillRect(85, 57, 2, 6, WHITE);
    case 23: display.fillRect(82, 57, 2, 6, WHITE);    
    case 22: display.fillRect(79, 57, 2, 6, WHITE); 
    case 21: display.fillRect(76, 57, 2, 6, WHITE);
    case 20: display.fillRect(73, 57, 2, 6, WHITE);
    case 19: display.fillRect(70, 57, 2, 6, WHITE);
    case 18: display.fillRect(67, 57, 2, 6, WHITE);
    case 17: display.fillRect(64, 57, 2, 6, WHITE);
    case 16: display.fillRect(62, 57, 2, 6, WHITE);
    case 15: display.fillRect(59, 57, 2, 6, WHITE);    
    case 14: display.fillRect(56, 57, 2, 6, WHITE);
    case 13: display.fillRect(53, 57, 2, 6, WHITE);
    case 12: display.fillRect(50, 57, 2, 6, WHITE);
    case 11: display.fillRect(47, 57, 2, 6, WHITE);
    case 10: display.fillRect(44, 57, 2, 6, WHITE);
    case 9: display.fillRect(41, 57, 2, 6, WHITE);
    case 8: display.fillRect(38, 57, 2, 6, WHITE);
    case 7: display.fillRect(35, 57, 2, 6, WHITE);
    case 6: display.fillRect(32, 57, 2, 6, WHITE);
    case 5: display.fillRect(29, 57, 2, 6, WHITE);
    case 4: display.fillRect(26, 57, 2, 6, WHITE);
    case 3: display.fillRect(23, 57, 2, 6, WHITE); // Inicio da escala em 1 dB.
    case 2: display.fillRect(21, 57, 2, 6, WHITE);
    //case 1: display.fillRect(15, 57, 2, 6, WHITE);
  }
}

Segundo esboço abaixo com foto, segue o mesmo do primeiro esboço porem com IF em CLK1, ou seja vocês tem a frequência da IF saíndo em CLK1, S/Meter com barras unidas, filtro contra ruídos, atenuador para sensibilidade que poderá ser no esboço ou no entrada do sinal do transceptor.
Vejam foto abaixo e esboço.
IF CLK1: 7800kHz já está um pouco abaixo atualizado no esboço.
Selecione todo sketch, copie e cole. Abra Arduino IDE vá em "Arquivo" depois "Novo", ou ícone ao lado da seta para "Carregar ou Compilar, abra um novo delete todas ás linhas e cole este sketch, renomeei com final .ino se preferir e salve em uma pasta. adicione todas ás bibliotecas. Lembre-se que muitas bibliotecas para o mesmo arquivo pode causar conflitos e provocar erros na compilação. 
Primeiro sketch abaixo.

/**********************************************************************************************************
  10kHz to 225MHz VFO / RF Generator with Si5351 and Arduino Nano, with Intermediate Frequency (IF) offset
  (+ or -), RX/TX Selector for QRP Transceivers, Band Presets and Bargraph S-Meter. See the schematics for
  wiring and README.txt for details. By J. CesarSound - ver 2.0 - Feb/2021.
***********************************************************************************************************/
// Sketch 10kHz to 225MHz autor Júlio Cesar, modificado por Waldir Cardoso Blog:https://projetosetransceptores.blogspot.com/
// Este sketch está com CLK0 em RX 34.765 Mhz, CLK1 7.800 kHz.
// STEP 1Hz 10Hz 1kHz 10kHz 100kHz 1MHz 1.5MHz 2MHz.
// Bandas + - sobe pino D10 banda desce pino A1. 
// S/Meter menos sensível e contra ruídos escala Cobra 148 GTL começo final SIG.
// EEPROM Memoria total ao desligar salva última apresentação no display.
// O sketch usa 26982 bytes (85%) de armazenamento (34%) memória dinâmica com biblioteca PU2REO_Si5351Lite.h.

//Libraries
#include <EEPROM.h>
#include <Wire.h>                 //IDE Standard
#include <Rotary.h>               //Ben Buxton https://github.com/brianlow/Rotary
#include <SPI.h>
#include "PU2REO_Si5351Lite.h"    //https://github.com/PU2REO/PU2REO_Si5351Lite
//#include <si5351_lite.h>
//#include <si5351.h>               //Etherkit https://github.com/etherkit/Si5351Arduino
#include <Adafruit_GFX.h>         //Adafruit GFX https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h>     //Adafruit SSD1306 https://github.com/adafruit/Adafruit_SSD1306

//User preferences
//------------------------------------------------------------------------------------------------------------
// EEPROM
#define EEPROM_FREQ   0
#define EEPROM_BAND   10
#define EEPROM_STEP   20

unsigned long lastSave = 0;
#define IF         7800      //Enter your IF frequency, ex: 455 = 455kHz, 10700 = 10.7MHz, 0 = to direct convert receiver or RF generator, + will add and - will subtract IF offfset.
#define BAND_INIT  15        //Enter your initial Band (1-21) at startup, ex: 1 = Freq Generator, 2 = 800kHz (MW), 7 = 7.2MHz (40m), 11 = 14.1MHz (20m). 
#define XT_CAL_F   18000     //Si5351 calibration factor, adjust to get exatcly 10MHz. Increasing this value will decreases the frequency and vice versa.
#define S_GAIN     303       //Adjust the sensitivity of Signal Meter A/D input: 101 = 500mv; 202 = 1v; 303 = 1.5v; 404 = 2v; 505 = 2.5v; 1010 = 5v (max).
#define tunestep   A0        //The pin used by tune step push button.
#define band       A1        //The pin used by band - selector push button.
#define rx_tx      A2        //The pin used by RX / TX selector switch, RX = switch open, TX = switch closed to GND. When in TX, the IF value is not considered.
//#define adc        A3        //The pin used by Signal Meter A/D input.
#define band_dn    10        //The pin D10 + used by band - selector push button..Banda + D10 botão LOW, banda sobe e frequência desce.
//------------------------------------------------------------------------------------------------------------

// Configurações do Display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     -1

Rotary r = Rotary(2, 3);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 
Si5351 si5351(0x60); //Si5351 I2C Address 0x60

// S/Meter Pino
const int sMeterPin = A3;
int smoothedSMeter = 0;
int peakHold = 0;
unsigned long peakTimer = 0;

unsigned long freq, freqold, fstep;
long interfreq = IF, interfreqold = 0;
long cal = XT_CAL_F;
unsigned int smval;
byte encoder = 1;
byte stp, n = 1;
byte count, x, xo;
bool sts = 0;
unsigned int period = 100;
unsigned long time_now = 0;

ISR(PCINT2_vect) {
  char result = r.process();
  if (result == DIR_CW) set_frequency(1);
  else if (result == DIR_CCW) set_frequency(-1);
}

void set_frequency(short dir) {
  if (encoder == 1) {                         //Up/Down frequency
    if (dir == 1) freq = freq + fstep;
    if (freq >= 225000000) freq = 225000000;
    if (dir == -1) freq = freq - fstep;
    if (fstep == 1000000 && freq <= 1000000) freq = 1000000;
    else if (freq < 10000) freq = 10000;
  }
  if (encoder == 1) {                       //Up/Down graph tune pointer
    if (dir == 1) n = n + 1;
    if (n > 42) n = 1;
    if (dir == -1) n = n - 1;
    if (n < 1) n = 42;
  }
}

//=======EEPROM==Salva frequencia, STEP Banda====
void saveMemory() {

  EEPROM.put(EEPROM_FREQ, freq);
  EEPROM.put(EEPROM_BAND, count);
  EEPROM.put(EEPROM_STEP, stp);
}

void loadMemory() {

  EEPROM.get(EEPROM_FREQ, freq);
  EEPROM.get(EEPROM_BAND, count);
  EEPROM.get(EEPROM_STEP, stp);

  // Proteção EEPROM vazia
  if (freq < 10000 || freq > 225000000) {
    count = BAND_INIT;
    bandpresets();
  }

  // EEPROM STEP 1Hz a 2MHz
  switch (stp) {
    case 1: fstep = 2000000; break;
    case 2: fstep = 1; break;
    case 3: fstep = 10; break;
    case 4: fstep = 1000; break;
    case 5: fstep = 10000; break;
    case 6: fstep = 100000; break;
    case 7: fstep = 1000000; break;
    case 8: fstep = 1500000; break;
    default:
      stp = 5;
      fstep = 10000;  
    break;
  }
}

void setup() {
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.display();

  //Inicialização Cobra 148GTL edite outros equipamentos.
  display.setTextSize(2); 
  display.setCursor(9, 10);
  display.print("Cobra 148");
  display.setCursor(45, 40);
  display.print("GTL");
  display.display(); 
  delay(2000);

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(tunestep, INPUT_PULLUP);
  pinMode(band, INPUT_PULLUP);
  pinMode(rx_tx, INPUT_PULLUP);
  pinMode(band_dn, INPUT_PULLUP);
  
  //statup_text();  //If you hang on startup, comment

  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
  si5351.set_correction(cal, SI5351_PLL_INPUT_XO);
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
  si5351.drive_strength(SI5351_CLK1, SI5351_DRIVE_6MA);
  si5351.output_enable(SI5351_CLK0, 1);                  //1 - Enable / 0 - Disable CLK
  si5351.output_enable(SI5351_CLK1, 1);
 
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();

  loadMemory();
  //interfreq = IF; 
  //tunegen();

  if (freq == 0) {
   count = BAND_INIT;
   bandpresets();
   stp = 5;
   setstep();
  }  

void loop() {
    
  if (freqold != freq) {
    time_now = millis();
    tunegen();
    freqold = freq;
  }

  if (interfreqold != interfreq) {
    time_now = millis();
    tunegen();
    interfreqold = interfreq;
  }
    
  if (xo != x) {
    time_now = millis();
    xo = x;
  }

  // Botão STEP encoder
  if (digitalRead(tunestep) == LOW) {
    time_now = (millis() + 300);
    setstep();
    delay(300);
  }

  // Botão - BAND desce banda e sobe frequência.
  if (digitalRead(band) == LOW) {
    time_now = (millis() + 300);
    inc_preset();
    delay(300);
  }

  // Botão + Band sobe banda e desce frequência.
  if (digitalRead(band_dn) == LOW) {
    time_now = (millis() + 300);
    dec_preset();
    delay(300);
  }

  // RX/TX
  if (digitalRead(rx_tx) == LOW) {
    sts = 1;
  } else {
    sts = 0;
  }

  // Leitura do S-meter
  int sMeterVal = analogRead(sMeterPin);

  // Atualização do display
  display.clearDisplay();
  displayfreq();
  layout();
  updateDisplay(sMeterVal);
  display.display();

 // Salva memória após 2 segundos sem mexer
  if (millis() - time_now > 2000) {
  if (millis() - lastSave > 5000) {
    saveMemory();
    lastSave = millis();
  }
}
  delay(50);
}

void tunegen() {

  si5351.set_freq((freq + (interfreq * 1000ULL)) * 100ULL, SI5351_CLK0);
  si5351.set_freq((IF * 1000ULL) * 100ULL, SI5351_CLK1);

  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
  si5351.drive_strength(SI5351_CLK1, SI5351_DRIVE_6MA);

  si5351.output_enable(SI5351_CLK0, 1);
  si5351.output_enable(SI5351_CLK1, 1);
}

void displayfreq() {
  unsigned int m = freq / 1000000;
  unsigned int k = (freq % 1000000) / 1000;
  unsigned int h = (freq % 1000) / 1;
  
  display.setTextSize(2);

  char buffer[15] = "";
  if (m < 1) {
    display.setCursor(41, 1); sprintf(buffer, "%003d.%003d", k, h);
  }
  else if (m < 100) {
    display.setCursor(5, 1); sprintf(buffer, "%2d.%003d.%003d", m, k, h);
  }
  else if (m >= 100) {
    unsigned int h = (freq % 1000) / 10;
    display.setCursor(5, 1); sprintf(buffer, "%2d.%003d.%02d", m, k, h);
  }
  display.print(buffer);
}

void setstep() {
  switch (stp) {
  case 1: stp = 2; fstep = 1; break;
  case 2: stp = 3; fstep = 10; break;
  case 3: stp = 4; fstep = 1000; break;
  case 4: stp = 5; fstep = 10000; break;
  case 5: stp = 6; fstep = 100000; break;
  case 6: stp = 7; fstep = 1000000; break;
  case 7: stp = 8; fstep = 1500000; break;
  case 8: stp = 1; fstep = 2000000; break;
  }
}

void inc_preset() {
  count++;
  if (count > 21) count = 1;
  bandpresets();
  saveMemory();
  delay(50);
}
  
void dec_preset() {
  if (count <= 1) count = 21;
  else count--;
  bandpresets();
  saveMemory();
  delay(50);
}

void bandpresets() {
  switch (count)  {
    case 1: freq = 100000; tunegen(); break;
    case 2: freq = 800000; break;
    case 3: freq = 1800000; break;
    case 4: freq = 3650000; break;
    case 5: freq = 4985000; break;
    case 6: freq = 6180000; break;
    case 7: freq = 7200000; break;
    case 8: freq = 10000000; break;
    case 9: freq = 11780000; break;
    case 10: freq = 13630000; break;
    case 11: freq = 14100000; break;
    case 12: freq = 15000000; break;
    case 13: freq = 17655000; break;
    case 14: freq = 21525000; break;
    case 15: freq = 26965000; break;
    case 16: freq = 28400000; break;
    case 17: freq = 50000000; break;
    case 18: freq = 100000000; break;
    case 19: freq = 130000000; break;
    case 20: freq = 144000000; break;
    case 21: freq = 220000000; break;
  }
  si5351.pll_reset(SI5351_PLLA);
  saveMemory();  // Salva o STEP na memória ao desligar.
  //stp = 5;  // Esta linha habilitada e saveMemory desabilitada o STEP inicializará 10 kHz.
  //setstep(); // Esta linha habilitada e saveMemory desabilitada o STEP inicializará 10 kHz.  
}

void layout() {     
  display.setTextColor(WHITE);
  display.drawLine(0, 18, 127, 18, WHITE);   // Linha orizontal abaixo da frequência.
  display.drawLine(0, 42, 127, 42, WHITE);   // Linha orizontal abaixo do STEP.
  display.drawLine(105, 19, 105, 41, WHITE); //Linha vertical que divide RX e MHz
  display.drawLine(87, 19, 87, 41, WHITE);   //Linha vertical que divide STEP e RX
  //display.drawLine(87, 48, 87, 63, WHITE);   //Linha vertical que divide S/meter e IF
  //display.drawLine(0, 55, 127, 55, WHITE);   //Linha horizontal de baixo S/Meter.
  //display.drawLine(15, 55, 82, 55, WHITE);   // Linha vertical de TU 
  display.setTextSize(1);          // Tamanho da fonte.
  display.setCursor(57, 22);       // Posição nome STEP display.
  //display.setCursor(59, 23);
  display.print("STEP");           // Imprime nome STEP display.
  display.setCursor(48, 32);       // Posição caracteres números STEP display.
  //display.setCursor(54, 33);
  if (stp == 2) display.print("   1Hz");
  if (stp == 3) display.print("  10Hz");
  if (stp == 4) display.print("  1kHz");
  if (stp == 5) display.print(" 10kHz");
  if (stp == 6) display.print("100kHz");
  if (stp == 7) display.print("  1MHz");
  if (stp == 8) display.print("1.5MHz");
  if (stp == 1) display.print("  2MHz");
  display.setTextSize(1);          // Tamanho da fonte.
  display.setCursor(0, 44);        //Posição nome IF CLK1: caracteres acima do S/Meter.
  //display.setCursor(0, 57);        //Posição IF caracteres nome caracteres acima do S/Meter..
  //display.setCursor(92, 48);
  //display.print("IF:");            // IF só em CLK0 RX TX.
  display.print("IF CLK1:");       //IF e CLK1 habilitada caracteres nome no display.        
  display.setCursor(48, 45);       // Posição números Frequência IF CLK1: caracteres acima do S/Meter..
  //display.setCursor(25, 44);       // Posição números Frequência IF caracteres. Acima do rodapé.
  //display.setCursor(55, 57);       // Posição números Frequência IF caracteres. Abaixo display.
  //display.print(IF);                // FIXO 7800kHz em RX e TX
  display.print(interfreq);       // Frequencia IF
  display.print("kHz");            //Caracteres nome kHz.
  display.setTextSize(1);
  display.setCursor(110, 21);    //Posição kHz KHz no display.
  if (freq < 1000000) display.print("kHz");
  if (freq >= 1000000) display.print("MHz");
  display.setCursor(110, 32);    //Posição VFO L O no display.
  display.print("VFO");
  //if (interfreq == 0) display.print("VFO");
  //if (interfreq != 0) display.print("L O");
    
  display.setCursor(91, 27);     // Posição RX TX no display.
  if (!sts) display.print("RX"); //if (!sts) interfreq = IF;
  if (sts) display.print("TX"); //if (sts) interfreq = IF;   //0 ou IF desabilita e IF habilita IF em CLK1 em TX. 
  bandlist(); 
}

void bandlist() {
 
  display.setTextSize(2);
  display.setCursor(0, 23);  // Posição caracteres números letras bandas
  if (count == 1) display.print("GEN"); if (count == 2) display.print("MW"); if (count == 3) display.print("160m"); if (count == 4) display.print("80m");
  if (count == 5) display.print("60m"); if (count == 6) display.print("49m"); if (count == 7) display.print("40m"); if (count == 8) display.print("31m");
  if (count == 9) display.print("25m"); if (count == 10) display.print("22m"); if (count == 11) display.print("20m"); if (count == 12) display.print("19m");
  if (count == 13) display.print("16m"); if (count == 14) display.print("13m"); if (count == 15) display.print("11m"); if (count == 16) display.print("10m");
  if (count == 17) display.print("6m"); if (count == 18) display.print("WFM"); if (count == 19) display.print("AIR"); if (count == 20) display.print("2m");
  if (count == 21) display.print("1m");
  //if (count == 1) interfreq = 0; else if (!sts) interfreq = IF; 
  //interfreq = IF;   // IF display sempre 7800 kHz em RX e TX
}

// S/Meter rodapé Cobra 148GTL
void updateDisplay(int sMeterVal) {

  // ===== Moldura =====
  display.drawRect(0, 53, 128, 11, WHITE);

  // ===== Fundo interno preto=====
  display.fillRect(1, 54, 126, 8, BLACK);

  // ===== Sensibilidade 100%=====
 // sMeterVal = constrain(sMeterVal, 0, S_GAIN); //100% sensibilidade

  // ===== Sensibilidade 50% menor =====
  sMeterVal = (sMeterVal * 50) / 100;  // (sMeterVal * 50) reduz 50%, (sMeterVal * 70)reduz 30%
  sMeterVal = constrain(sMeterVal, 0, S_GAIN);

  // Barra ocupando todo espaço interno e "SIG"
  //int barWidth = map(sMeterVal, 0, S_GAIN, 0, 126); //Barra do começo total da escala.
  int barWidth = map(sMeterVal, 0, S_GAIN, 0, 106);   //Barra começa depois do "SIG"

  // ===== Suavização =====
  smoothedSMeter = ((smoothedSMeter * 2) + barWidth) / 3;

  // ===== Peak Hold =====
  if (smoothedSMeter > peakHold) {
  peakHold = smoothedSMeter;
  peakTimer = millis();
  }

  // Pico mais rápido
  if (millis() - peakTimer > 15) {
  if (peakHold > 0) peakHold -= 2;
  }

  peakHold = constrain(peakHold, 0, 125);

  // ===== Barra cheia =====
  if (smoothedSMeter > 0) {
  //display.fillRect(1, 54, smoothedSMeter, 9, WHITE); // começo barra total e largura da barra 8 coloquei 9
  display.fillRect(20, 54, smoothedSMeter, 9, WHITE);  //barra começa depois do "SIG"
  }

  // ===== Linha de pico =====
  //display.drawLine(peakHold, 53, peakHold, 62, WHITE);         //Pico total escala.
  display.drawLine(peakHold + 20, 53, peakHold + 20, 62, WHITE); //Pico começa depois do "SIG"
  //=======Barra=======
  for (int i = 0; i < 126; i++) {
  if (i < smoothedSMeter)  
  //display.drawFastVLine(i + 1, 54, 9, WHITE); //Ocupa escala total e largura da barra 8 coloquei 9.
  display.drawFastVLine(i + 20, 54, 9, WHITE);  //Escala começa depois do "SIG"
  }
  
  // cor da escala branco
  display.setTextColor(WHITE);

  //====Escala para 148 GTL====
  // Barra começa por cima do "SIG"
  display.setTextSize(1);          // Fonte tamanho números
  display.setCursor(2, 55);      //Inicio nome SIG sem tocar na linha
  display.print("SIG");

  display.setCursor(24, 55);
  display.print("1");

  display.setCursor(36, 55);
  display.print("3");

  display.setCursor(48, 55);
  display.print("5");

  display.setCursor(60, 55);
  display.print("7");

  display.setCursor(72, 55);
  display.print("9");

  display.setCursor(79, 55);
  display.print("...");

  display.setCursor(96, 55);
  display.print("+30");

  display.setCursor(115, 55);
  display.print("dB");         // Fim da escala dB sem tocar na linha
}