terça-feira, 30 de junho de 2026

10kHz 225MHz Júlio Cesar AM, LSB, USB Cobra 148 GTL.

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á pessoal, Continuando o prometido no vídeo mês passado. Publico aqui e no vídeo YouTube mais algumas implementações, no mesmo sketch do Sr. Júlio Cesar, meus agradecimentos pelo código livre que foi publicado em sua página 10 kHz a 225 MHz versão 2 e diversas páginas sendo o projeto de DDS VFO gerador RF mais copiado e modificado desde 2021. Ás modificações que implementei são para nós PX, Radioamadores montadores de transceptores, técnicos em modificações de equipamentos com PLL ou VFO analógico. O que conseguir: 1- Modo AM, LSB, USB com FI 7.800 kHz Cobra 148 GTL. Adicionei memória total frequência por banda. Ou seja última frequência selecionada em cada banda serão memorizadas mesmo ao mudar de banda ou desligar o rádio, tipo transceptores comerciais. Clarificador Tune Fine VFO 8 kHz direita e 8 kHz esquerda ajustável no sketch. Bem como já estava com mão na massa continuei a fazer modificações para implementar MENU e funções como: Scanner. Ajuste de VFO com STEP. Ajuste de BFO FI CLK1, entre outras atualizações que fiz em todo estes 2 meses. Mas não estou satisfeito com ás novas atualizações do clarificador e MENU. Faltam alguns ajustes. Não é fácil acertar no que não se ver, fiz este mês 30 ou mais gravações no meu Arduino ATmega 328P que ainda está aguentando firme todo este ano de gravações entre erros e acertos. Pessoal vocês que tem interesse em aprender a modificar qualquer projeto, seja um simples receptor, transmissor, transverter, Sketch de DDS VFO, ou seja, quais quer projetos que você pensar em fazer uma modificação para melhorar, você tem que ter na sua mente que vai conseguir fazer, nunca deixe o pensamento negativo tomar conta do seu interesse que está pensando em modificar para melhor. Não sou nenhum cérebro inteligente nem tenho QI superior a ninguém, pelo contrário eu até meus 12 anos de idade pensava que era um menos inteligente "Burro", achava que meu irmão era o inteligente, e tudo que eu queria saber perguntava a ele. Isso porque ele é mais velho que eu um ano. Depois comecei a ver a realidade da vida e do cérebro humano, ai fui me aprimorando no que eu tinha vontade de fazer e modificar. Quando tinha dinheiro comprava uma revista de eletrônica em esquema de amplificador de áudio e adicionava um pré amplificador de outra revista, isso eu desenhava o esquema em um caderno simples de páginas de linhas. Sempre estava desenhando esquemas. A pessoal, queria poder contar o muito que já fiz e o quanto já sofri para ser o que sou, eu fui como um monte de barro que é amassado para depois virar um belo vazo que vai decorar uma linda sala. Mas hoje vocês tem a internet WEB, revistas de graça, pessoas que fazem e dá dicas em blogs, vídeos verdadeiros no YouTube. Na minha época não tinha nada disso, por isso aproveitem o máximo possível pois um dia poderá ser tarde. Bem voltando a atualidade do nosso sketch, eu vou postar o sketch prometido no vídeo com os modos AM, LSB, USB já pronto para ser colocado no Cobra 148 GTL, espero que se algum técnico quiser e tiver interesse em colocar este projeto do Sr. Júlio Cesar e modificado por mim em transceptores Cobra 148 GTL ou outros equipamentos por favor façam um vídeo ou mande um comentário aqui ou no meu canal do YouTube para ver como ficou na prática o DDS VFO atuando no transceptor. Ficarei grato se também dissesse o criador do DDS VFO em funcionamento. Vejam muitas fotos e outras que no começo do mês não tirei, como é fazer: Ajustar ás posições dos caracteres, desenvolver, desenhar o esquema e muito mais. 
Vejam que faltam o 0 zero dos 100Hz, eu já tinha depois de muitos erros e gravações os modos: AM, LSB, USB.
Vejam a frequência de CLK1.
Vejam que mesmo em LSB não tem o 500Hz.
 
Olhem no frequencimetro frequência de CLK1 em LSB.
Mesma coisa faltam os Hz. e frequência de CLK1.
Frequência do modo USB.
Abaixo observem a data na foto, coloquei o clarificador e os Hz de CLK1.
O número 14 de CL tinha que tá na frequência do VFO.
Vejam que na foto abaixo está acontecendo a mesma coisa em CL.
Tela inicial agora com clarificador em RX e TX no VFO.
Conseguir colocar os Hz na tela do display só com um dígito Centézimo.
Agora parece que está ajustado. Vejam em CL: 23 é o mesmo que o Hz da frequência do VFO.
Vejam que aparece IF os Hz 500 de CLK1 LSB.
Vejam a frequência saída de CLK0 com FI do Cobra 148 GTL canal 1 26.965.00MHz LSB.
Também com os 500 Hz de FI CLK1, só com a centena 5.
Vejam a frequência saída de CLK0 com FI do Cobra 148 GTL canal 1 26.965.00MHz USB.
Vejam que CL está bem próximo a IF.
Vejam que agora com sinal de - para quando o clarificador for para sentido negativo esquerdo.
O z está sobrepondo o I, não pode ser assim.
Acho que assim ficou melhor.
Agora com -8kHz Acho que está bom.
 
Vejam a data da foto. Estou tentando adicionar um MENU.
Tentando adicionar um Scanner para correr ás frequências.

Ainda falta muitas funções.
Ficou bom assim mas faltam ajuste e mais tempo.
Vou tentar colocar os Hz tal como no display em CLK1.
Ainda ter erros e muitos.
Vamos adicionar mais alguns recursos no Scanner.
Agora com indicador contador de 4 dígitos, banda, sinal.

Vou tentar colocar um limite para o Scanner parar pelo S/Meter. 
Esquema elétrico DDS VFO AM, LSB, USB Cobra 148 GTL.
Abaixo sketch DDS VFO AM, LSB, USB, memória total ao desligar, botão de bandas + e - ou sobe e desce. O sketch está com todas explicações comentadas em português. Sucesso na montagem. 
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, observe a porta USB entre outras preferencias poderá provocar erros na compilação. 
 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.
***********************************************************************************************************/
// ============================================================================
// TRANSCEPTOR COBRA 148 GTL - CONTROLE DIGITAL COM Si5351
// ============================================================================
// Sketch original: 10kHz a 225MHz
// Autor original: Júlio Cesar  Fevereiro 2021
// Modificado por: Waldir Cardoso   Junho 2026
// Blog: https://projetosetransceptores.blogspot.com/
// ============================================================================
// FUNCIONALIDADES PRINCIPAIS:
// ============================================================================
// - Frequência: 10 kHz até 225 MHz (cobertura HF/VHF/UHF completa)
// - CLK0 (VFO): Oscilador local para recepção
//   Exemplo: CLK0 Canal 1 PX (CB) AM = 34.765 MHz (26.965 + 7.800 MHz)
// - CLK1 (BFO): Oscilador de frequência intermediária (FI)
//   FI padrão: AM (7.8000 Hz) LSB (7.7985 MHz) USB (7.8015 MHz) (ajustável no sketch)
// - Modos de operação: AM, LSB, USB (teclas físicas separadas)
// - Encoder STEP ajustável: 1Hz, 10Hz, 1kHz, 10kHz, 100kHz, 1MHz, 1.5MHz, 2MHz
// - Bandas: 21 bandas pré-programadas (GEN, MW, 160m a 1m)
// - Botões: BAND+ (D10) sobe banda, BAND- (A1) desce banda
// - S-Meter: Escala estilo Cobra 148 GTL (SIG 1-9 +30 dB)
//   Com suavização e peak hold para melhor visualização
// - EEPROM: Memória total - salva frequência, banda, step e BFO ao desligar
//   Ao ligar, retorna exatamente na última configuração usada
// ============================================================================
// PINOS UTILIZADOS:
// ============================================================================
// D2, D3: Encoder rotativo (controle de frequência)
// A0: Botão do encoder (STEP)
// A1: Botão BAND- (desce banda)
// D10: Botão BAND+ (sobe banda)
// A2: Chave RX/TX
// D6, D7, D8: Teclas de seleção de modo (USB, LSB, AM)
// A3: Entrada do S-Meter (sensor de sinal)
// ============================================================================
// BIBLIOTECAS NECESSÁRIAS
// ============================================================================
#include <EEPROM.h>           // Memória EEPROM para salvar configurações
#include <Wire.h>             // Comunicação I2C (display e Si5351)
#include <Rotary.h>           // Controle do encoder rotativo
#include <SPI.h>              // Comunicação SPI
#include "PU2REO_Si5351Lite.h" // Gerador de frequência Si5351
#include <Adafruit_GFX.h>     // Biblioteca gráfica para display
#include <Adafruit_SSD1306.h> // Driver para display OLED SSD1306

// ============================================================================
// ENDEREÇOS DA MEMÓRIA EEPROM (onde os dados são salvos permanentemente)
// ============================================================================
#define EEPROM_FREQ        0    // Endereço 0: Frequência atual
#define EEPROM_BAND        10   // Endereço 10: Banda atual
#define EEPROM_STEP        20   // Endereço 20: Step (passo) atual
#define EEPROM_BAND_FREQ   100  // Endereço 100: Frequências das bandas

// ============================================================================
// FREQUÊNCIAS DO BFO (Beat Frequency Oscillator) para cada modo
// ============================================================================
#define BFO_AM    7800000UL     // BFO para modo AM  (7.800 MHz)
#define BFO_LSB   7798500UL     // BFO para modo LSB (7.7985 MHz)
#define BFO_USB   7801500UL     // BFO para modo USB (7.8015 MHz)

// ============================================================================
// PINOS DE SELEÇÃO DE MODO (AM, LSB, USB)
// ============================================================================
#define USB_PIN   6             // Pino para selecionar modo USB
#define LSB_PIN   7             // Pino para selecionar modo LSB
#define AM_PIN    8             // Pino para selecionar modo AM

// ============================================================================
// CONFIGURAÇÕES GERAIS DO RÁDIO
// ============================================================================
#define BAND_INIT 15            // Banda inicial ao ligar (15 = 11m CB 27MHz)
#define XT_CAL_F  18000         // Fator de calibração do cristal Si5351
#define S_GAIN    303           // Sensibilidade do S-Meter (1.5V máximo)

// ============================================================================
// PINOS DE ENTRADA (BOTÕES E CHAVES)
// ============================================================================
#define tunestep  A0            // Botão do encoder (muda step)
#define band      A1            // Botão BAND+ (sobe banda)
#define rx_tx     A2            // Chave RX/TX (LOW = TX)
#define band_dn   10            // Botão BAND- (desce banda)

// ============================================================================
// CONFIGURAÇÕES DO DISPLAY OLED
// ============================================================================
#define SCREEN_WIDTH 128        // Largura do display em pixels
#define SCREEN_HEIGHT 64        // Altura do display em pixels
#define OLED_RESET     -1       // Pino de reset (não usado)

// ============================================================================
// OBJETOS DAS BIBLIOTECAS
// ============================================================================
Rotary r = Rotary(2, 3);        // Encoder nos pinos 2 e 3
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Display OLED
Si5351 si5351(0x60);            // Si5351 no endereço I2C 0x60

// ============================================================================
// VARIÁVEIS DO S-METER (Medidor de Sinal)
// ============================================================================
const int sMeterPin = A3;       // Pino de entrada do S-Meter
int smoothedSMeter = 0;         // Valor suavizado do S-Meter
int peakHold = 0;               // Valor de pico mantido
unsigned long peakTimer = 0;    // Temporizador do pico

// ============================================================================
// VARIÁVEIS GLOBAIS PRINCIPAIS
// ============================================================================
unsigned long lastSave = 0;     // Último salvamento na EEPROM
unsigned long freq, freqold, fstep; // Frequência atual, anterior e passo
long cal = XT_CAL_F;            // Calibração do Si5351
byte stp, n = 1;                // Step atual e contador do gráfico
byte count;                     // Banda atual (1-21)
bool sts = 0;                   // Status RX/TX (0=RX, 1=TX)
unsigned long bfo = BFO_AM;     // Frequência do BFO atual
byte mode = 0;                  // Modo atual (0=AM, 1=LSB, 2=USB)

// ============================================================================
// INTERRUPÇÃO DO ENCODER (executada quando gira o encoder)
// ============================================================================
ISR(PCINT2_vect) {
  char result = r.process();    // Lê a direção do encoder
  if (result == DIR_CW) set_frequency(1);   // Sentido horário: sobe frequência
  else if (result == DIR_CCW) set_frequency(-1); // Anti-horário: desce
}

// ============================================================================
// FUNÇÃO: Ajusta a frequência conforme direção do encoder
// ============================================================================
void set_frequency(short dir) {
  if (dir == 1) {               // Se girou para cima
    freq = freq + fstep;        // Soma o step à frequência
    if (freq >= 225000000) freq = 225000000; // Limite máximo: 225 MHz
  }
  if (dir == -1) {              // Se girou para baixo
    freq = freq - fstep;        // Subtrai o step da frequência
    if (fstep == 1000000 && freq <= 1000000) freq = 1000000; // Mínimo com step 1MHz
    else if (freq < 10000) freq = 10000; // Limite mínimo: 10 kHz
  }
}

// ============================================================================
// FUNÇÃO: Salva configurações na memória EEPROM
// ============================================================================
void saveMemory() {
  EEPROM.put(EEPROM_FREQ, freq);   // Salva frequência atual
  EEPROM.put(EEPROM_BAND, count);  // Salva banda atual
  EEPROM.put(EEPROM_STEP, stp);    // Salva step atual
}

// ============================================================================
// FUNÇÃO: Carrega configurações da memória EEPROM
// ============================================================================
void loadMemory() {
  EEPROM.get(EEPROM_FREQ, freq);   // Carrega frequência
  EEPROM.get(EEPROM_BAND, count);  // Carrega banda
  EEPROM.get(EEPROM_STEP, stp);    // Carrega step

  // Se frequência inválida, usa banda inicial
  if (freq < 10000 || freq > 225000000) {
    count = BAND_INIT;
    bandpresets();
  }

  // Converte código do step para valor em Hz
  switch (stp) {
    case 1: fstep = 2000000; break;  // 2 MHz
    case 2: fstep = 1; break;        // 1 Hz
    case 3: fstep = 10; break;       // 10 Hz
    case 4: fstep = 1000; break;     // 1 kHz
    case 5: fstep = 10000; break;    // 10 kHz
    case 6: fstep = 100000; break;   // 100 kHz
    case 7: fstep = 1000000; break;  // 1 MHz
    case 8: fstep = 1500000; break;  // 1.5 MHz
    default:
      stp = 5;                       // Padrão: 10 kHz
      fstep = 10000;
      break;
  }
}

// ============================================================================
// FUNÇÃO: Salva frequência da banda atual na EEPROM
// ============================================================================
void saveBandFrequency() {
  int addr = EEPROM_BAND_FREQ + ((count - 1) * sizeof(unsigned long));
  EEPROM.put(addr, freq);
}

// ============================================================================
// FUNÇÃO: Carrega frequência da banda atual da EEPROM
// ============================================================================
bool loadBandFrequency() {
  int addr = EEPROM_BAND_FREQ + ((count - 1) * sizeof(unsigned long));
  unsigned long tempFreq;
  EEPROM.get(addr, tempFreq);
  if (tempFreq >= 10000UL && tempFreq <= 225000000UL) {
    freq = tempFreq;
    return true;
  }
  return false;
}

// ============================================================================
// FUNÇÃO: Lê o modo de operação (AM/LSB/USB) pelos pinos
// ============================================================================
void readMode() {
  if (digitalRead(USB_PIN) == LOW) {
    mode = 2;
    bfo = BFO_USB;
  }
  if (digitalRead(LSB_PIN) == LOW) {
    mode = 1;
    bfo = BFO_LSB;
  }
  if (digitalRead(AM_PIN) == LOW) {
    mode = 0;
    bfo = BFO_AM;
  }
}

// ============================================================================
// FUNÇÃO DE CONFIGURAÇÃO INICIAL (executada uma vez ao ligar)
// ============================================================================
void setup() {
  Wire.begin();                 // Inicia comunicação I2C
  
  // Inicializa display OLED
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.display();

  // Tela inicial de boas-vindas
  display.setTextSize(2); 
  display.setCursor(9, 10);
  display.print(F("Cobra 148"));
  display.setCursor(45, 40);
  display.print(F("GTL"));
  display.display(); 
  delay(2000);

  // Configura pinos dos botões como entrada com pull-up
  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);
  pinMode(AM_PIN, INPUT_PULLUP);
  pinMode(LSB_PIN, INPUT_PULLUP);
  pinMode(USB_PIN, INPUT_PULLUP);
  
  // Inicializa gerador de frequência Si5351
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
  si5351.set_correction(cal, SI5351_PLL_INPUT_XO);
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);  // CLK0: 8mA (VFO)
  si5351.drive_strength(SI5351_CLK1, SI5351_DRIVE_6MA);  // CLK1: 6mA (BFO)
  si5351.output_enable(SI5351_CLK0, 1);  // Habilita CLK0
  si5351.output_enable(SI5351_CLK1, 1);  // Habilita CLK1
 
  // Configura interrupção do encoder
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();                      // Habilita interrupções globais
  
  loadMemory();               // Carrega configurações da EEPROM
  
  // Se frequência inválida, usa valores padrão
  if (freq == 0) {
    count = BAND_INIT;
    bandpresets();
    stp = 5;
    setstep();
  }  

// ============================================================================
// FUNÇÃO PRINCIPAL (executada em loop infinito)
// ============================================================================
void loop() {
  readMode();                 // Lê modo de operação (AM/LSB/USB)
  tunegen();                  // Gera frequências no Si5351
   
  // Se frequência mudou, atualiza Si5351
  if (freqold != freq) {
    tunegen();
    freqold = freq;
  }
  
  // Botão STEP do encoder (muda passo de ajuste)
  if (digitalRead(tunestep) == LOW) {
    setstep();
    delay(300);
  }
  
  // Botão BAND+ (sobe banda)
  if (digitalRead(band) == LOW) {
    inc_preset();
    delay(300);
  }
  
  // Botão BAND- (desce banda)
  if (digitalRead(band_dn) == LOW) {
    dec_preset();
    delay(300);
  }
  
  // Lê status RX/TX
  sts = (digitalRead(rx_tx) == LOW) ? 1 : 0;
  
  // Lê valor do S-Meter
  int sMeterVal = analogRead(sMeterPin);

  // Atualiza display completo
  display.clearDisplay();
  displayfreq();              // Mostra frequência
  layout();                   // Mostra layout (STEP, modo, etc)
  updateDisplay(sMeterVal);   // Mostra S-Meter
  display.display();

  // Salva na EEPROM após 5 segundos sem mexer
  if (millis() - lastSave > 5000) {
    saveMemory();
    lastSave = millis();
  }
  delay(50);                  // Delay para estabilidade
}

// ============================================================================
// FUNÇÃO: Gera as frequências no Si5351 (CLK0 = VFO, CLK1 = BFO)
// ============================================================================
void tunegen() {
  long vfoFreq = (long)(freq + bfo);  // VFO = frequência + BFO
  
  si5351.set_freq((uint64_t)vfoFreq * 100ULL, SI5351_CLK0);  // CLK0: VFO
  si5351.set_freq(bfo * 100ULL, SI5351_CLK1);                // CLK1: BFO

  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);
}

// ============================================================================
// FUNÇÃO: Exibe a frequência no display
// ============================================================================
void displayfreq() {
  unsigned int m = freq / 1000000;           // MHz
  unsigned int k = (freq % 1000000) / 1000;  // kHz
  unsigned int h = (freq % 1000);            // Hz
  
  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);
}

// ============================================================================
// FUNÇÃO: Muda o step (passo) de ajuste da frequência
// ============================================================================
void setstep() {
  switch (stp) {
    case 1: stp = 2; fstep = 1; break;        // 2MHz → 1Hz
    case 2: stp = 3; fstep = 10; break;       // 1Hz → 10Hz
    case 3: stp = 4; fstep = 1000; break;     // 10Hz → 1kHz
    case 4: stp = 5; fstep = 10000; break;    // 1kHz → 10kHz
    case 5: stp = 6; fstep = 100000; break;   // 10kHz → 100kHz
    case 6: stp = 7; fstep = 1000000; break;  // 100kHz → 1MHz
    case 7: stp = 8; fstep = 1500000; break;  // 1MHz → 1.5MHz
    case 8: stp = 1; fstep = 2000000; break;  // 1.5MHz → 2MHz
  }
}

// ============================================================================
// FUNÇÃO: Sobe para a próxima banda
// ============================================================================
void inc_preset() {
  saveBandFrequency();        // Salva frequência atual da banda
  count++;
  if (count > 21) count = 1;  // Volta para banda 1 se passou da 21
  if (!loadBandFrequency()) bandpresets();  // Carrega frequência da banda
  saveMemory();
  delay(50);
}

// ============================================================================
// FUNÇÃO: Desce para a banda anterior
// ============================================================================
void dec_preset() {
  saveBandFrequency();        // Salva frequência atual da banda
  if (count <= 1) count = 21; // Volta para banda 21 se estava na 1
  else count--;
  if (!loadBandFrequency()) bandpresets();  // Carrega frequência da banda
  saveMemory();
  delay(50);
}

// ============================================================================
// FUNÇÃO: Define frequências padrão para cada banda
// ============================================================================
void bandpresets() {
  switch (count) {
    case 1: freq = 100000; tunegen(); break;      // 100 kHz (GEN)
    case 2: freq = 800000; break;                 // 800 kHz (MW)
    case 3: freq = 1800000; break;                // 1.800 MHz (160m)
    case 4: freq = 3650000; break;                // 3.650 MHz (80m)
    case 5: freq = 4985000; break;                // 4.985 MHz (60m)
    case 6: freq = 6180000; break;                // 6.180 MHz (49m)
    case 7: freq = 7200000; break;                // 7.200 MHz (40m)
    case 8: freq = 10000000; break;               // 10.000 MHz (31m)
    case 9: freq = 11780000; break;               // 11.780 MHz (25m)
    case 10: freq = 13630000; break;              // 13.630 MHz (22m)
    case 11: freq = 14100000; break;              // 14.100 MHz (20m)
    case 12: freq = 15000000; break;              // 15.000 MHz (19m)
    case 13: freq = 17655000; break;              // 17.655 MHz (16m)
    case 14: freq = 21525000; break;              // 21.525 MHz (13m)
    case 15: freq = 26965000; break;              // 26.965 MHz (11m CB)
    case 16: freq = 28400000; break;              // 28.400 MHz (10m)
    case 17: freq = 50000000; break;              // 50.000 MHz (6m)
    case 18: freq = 100000000; break;             // 100.000 MHz (WFM)
    case 19: freq = 130000000; break;             // 130.000 MHz (AIR)
    case 20: freq = 144000000; break;             // 144.000 MHz (2m)
    case 21: freq = 220000000; break;             // 220.000 MHz (1m)
  }
  si5351.pll_reset(SI5351_PLLA);  // Reset do PLL para estabilidade
  saveMemory();
}

// ============================================================================
// FUNÇÃO: Desenha o layout completo do display (linhas, textos, etc)
// ============================================================================
void layout() {     
  display.setTextColor(WHITE);
  
  // Linhas horizontais e verticais do layout
  display.drawLine(0, 18, 127, 18, WHITE);   // Linha abaixo da frequência
  display.drawLine(0, 42, 127, 42, WHITE);   // Linha abaixo do STEP
  display.drawLine(105, 19, 105, 41, WHITE); // Linha vertical (RX/MHz)
  display.drawLine(87, 19, 87, 41, WHITE);   // Linha vertical (STEP/RX)
  
  display.setTextSize(1);
  
  // STEP
  display.setCursor(57, 22);
  display.print(F("STEP"));
  display.setCursor(48, 32);
  if (stp == 2) display.print(F("   1Hz"));
  if (stp == 3) display.print(F("  10Hz"));
  if (stp == 4) display.print(F("  1kHz"));
  if (stp == 5) display.print(F(" 10kHz"));
  if (stp == 6) display.print(F("100kHz"));
  if (stp == 7) display.print(F("  1MHz"));
  if (stp == 8) display.print(F("1.5MHz"));
  if (stp == 1) display.print(F("  2MHz"));

  // Indicação do BFO/FI (CLK1)
  display.setCursor(0, 45);    // Posição dos nome caracteres IF CLK1
  display.print(F("IF CLK1:"));
  
  // BFO (Frequência Intermediária)
  display.setCursor(55, 45);   // Posição da frequencia IF CLK1
  display.print(bfo / 1000);
  display.print(F("."));
  display.print((bfo % 1000) / 100);
  display.print(F(" kHz"));
  
  // Unidade da frequência (kHz ou MHz)
  display.setTextSize(1);  
  display.setCursor(110, 21);
  if (freq < 1000000) display.print(F("kHz"));
  if (freq >= 1000000) display.print(F("MHz"));
  
  // Modo de operação (AM/LSB/USB)
  display.setCursor(110, 32);
  if (mode == 0) display.print(F("AM"));
  if (mode == 1) display.print(F("LSB"));
  if (mode == 2) display.print(F("USB"));
  
  // Status RX/TX
  display.setCursor(91, 27);
  if (!sts) display.print(F("RX"));
  if (sts) display.print(F("TX"));
  
  bandlist();  // Mostra nome da banda
}

// ============================================================================
// FUNÇÃO: Mostra o nome da banda atual no display
// ============================================================================
void bandlist() { 
  display.setTextSize(2);
  display.setCursor(0, 23);
  if (count == 1) display.print(F("GEN"));
  if (count == 2) display.print(F("MW"));
  if (count == 3) display.print(F("160m"));
  if (count == 4) display.print(F("80m"));
  if (count == 5) display.print(F("60m"));
  if (count == 6) display.print(F("49m"));
  if (count == 7) display.print(F("40m"));
  if (count == 8) display.print(F("31m"));
  if (count == 9) display.print(F("25m"));
  if (count == 10) display.print(F("22m"));
  if (count == 11) display.print(F("20m"));
  if (count == 12) display.print(F("19m"));
  if (count == 13) display.print(F("16m"));
  if (count == 14) display.print(F("13m"));
  if (count == 15) display.print(F("11m"));
  if (count == 16) display.print(F("10m"));
  if (count == 17) display.print(F("6m"));
  if (count == 18) display.print(F("WFM"));
  if (count == 19) display.print(F("AIR"));
  if (count == 20) display.print(F("2m"));
  if (count == 21) display.print(F("1m"));
}

// ============================================================================
// FUNÇÃO: Desenha o S-Meter (medidor de sinal) no rodapé
// ============================================================================
void updateDisplay(int sMeterVal) {
  // Moldura do S-Meter
  display.drawRect(0, 53, 128, 11, WHITE);
  display.fillRect(1, 54, 126, 8, BLACK);

  // Reduz sensibilidade em 50%
  sMeterVal = (sMeterVal * 50) / 100;
  sMeterVal = constrain(sMeterVal, 0, S_GAIN);
  
  // Converte valor para largura da barra
  int barWidth = map(sMeterVal, 0, S_GAIN, 0, 106);
  
  // Suavização do valor (média móvel)
  smoothedSMeter = ((smoothedSMeter * 2) + barWidth) / 3;

  // Peak Hold (mantém valor de pico)
  if (smoothedSMeter > peakHold) {
    peakHold = smoothedSMeter;
    peakTimer = millis();
  }
  
  // Decay do pico (diminui gradualmente)
  if (millis() - peakTimer > 15) {
    if (peakHold > 0) peakHold -= 2;
  }
  peakHold = constrain(peakHold, 0, 125);

  // Desenha barra do S-Meter
  if (smoothedSMeter > 0) {
    display.fillRect(20, 54, smoothedSMeter, 9, WHITE);
  }

  // Desenha linha de pico
  display.drawLine(peakHold + 20, 53, peakHold + 20, 62, WHITE);
  
  // Desenha escala vertical
  for (int i = 0; i < 126; i++) {
    if (i < smoothedSMeter) {
      display.drawFastVLine(i + 20, 54, 9, WHITE);
    }
  }
  
  // Escala numérica do S-Meter
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(2, 55);
  display.print(F("SIG"));
  display.setCursor(24, 55);
  display.print(F("1"));
  display.setCursor(36, 55);
  display.print(F("3"));
  display.setCursor(48, 55);
  display.print(F("5"));
  display.setCursor(60, 55);
  display.print(F("7"));
  display.setCursor(72, 55);
  display.print(F("9"));
  display.setCursor(79, 55);
  display.print(F("..."));
  display.setCursor(96, 55);
  display.print(F("+30"));
  display.setCursor(115, 55);
  display.print(F("dB"));
}

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 desenvolvido 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 desenvolvido por Waldir Cardoso.

Implementação da EEPROM: Para memorizar última visualização e apresentação total em todo display. Pesquisada outros esboços e desenvolvido 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. 
Assistam ao vídeo deste fabuloso DDS VFO atualizado parcialmente.
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
}