VFO COM SI5351 até 220MHz

VFO com tres frequencias independentes e simultâneas com o DDS SI5351, Arduino Nano e controle remoto (TV Sony).

Display do VFO mostrando as 3 frequencias independentes e simultâneas de saida.

O SI5351 chegou para ficar e esta mudando muito a forma de montagem, com seu tamanho diminuto, muito poderoso e com um preço acessível certamente vai substituir VFOs e osciladores a cristal de muitos radios.
Este VFO foi feito para testes e com o layout que fizemos o VFO, com pouco mais de 2 cm de espessura, passa a fazer parte do painel, ainda com o uso de um controle remoto (TV Sony) que requer o uso de apenas um pino do arduino e faz muitas funções e ainda deixa livre 6 I/O digitais e 6 I/O analógicas, que podem ser úteis em outros comandos.
Esquema :

O regulador de tensão não faz parte das fotos na montagem.

Montagem ;
Montamos em uma placa padrão de ilhas isoladas


O arduino Nano foi montado com os terminais na placa padrão e não foram soldados os pinos não utilisados. O Display vai conectado no soquete a esquerda, O SI5351 com seu soquete adaptador DIP, tem um soquete fixado/soldado no lado oposto e vai a direita no centro.


SI5351 com cristal HC49U de 27MHz colocado no soquete.


SI5351 com cristal ativo de 27MHz (SMD). As tres saidas a direita e acima são as saidas independentes e simultaneas do VFO.


Placa como display colocado.


Conjunto montado com pouco mais de 2cm de espessura.



Placa vista pelo lado de solda, note que os pinos do Arduino Nano não soldados admitem o uso de um conector femea e podem externamente controlar outras funções.


A esquerda em cima temos o conector do sensor do controle remoto (3 fios), as soldas abaixo são as saidas dos 3 VFOs.


O soquete de 14 pinos teve os 4 pinos das extremidades desmontados e duas aberturas usadas para fixar o soquete, que recebe o DIP do SI5351. Foi uma boa saida pois o SI5351 montado no DIP ficava muito alto.



Os botões numericos do controle remoto (TV Sony - antigas ou novas) acionam o display assim :

VOL+ habilita o VFO1 para alterações.
CH+   habilita o VFO2 para alterações
VOL-  habilita o VFO3 para alterações

tecla numerica 4 casa decimal é alterada para esquerda (em azul)
tecla numerica 6 casa decimal é alterada para direita (em azul)

tecla 2 casa decimal selecionada é alterada em um digito para cima (em azul)
tecla 8 casa decimal selecionada é alterada em um digito para baixo (em azul)

Para uso de outros controles remotos que possuam setas é possivel e facil, basta conhecer o codigo hexadecimal do teclado, se não souber como fazer me escreva.

Vídeo com o DDS em funcionamento

 O código para programação ou sketch, usa a excelente biblioteca do NT7S .
Foi previsto o uso de um cristal de 27MHz, que pode ser alterado no sketch, outra alteração possível via software e a potência de saída do SI5351 que aparece nestes comentarios
//si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_2MA); //you can set this to 2MA, 4MA, 6MA or 8MA
A dupla barra é comentário removendo ela fica ativa ... a potencia pode ser setada pela corrente de 2, 4, 6 ou 8mA.
O uso individual para montagens é aberto, mas o uso comercial deve ser visto junto ao colega NT7S que fornece a biblioteca.
Sketch

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


#include <IRremote.h>
#include <TFT.h>  // Arduino LCD library
#include <SPI.h>
#include <si5351.h>
#include <Wire.h>

#define cs   10
#define dc   8
#define rst  9
Si5351 si5351;
volatile uint32_t freqini =  700000000ULL / SI5351_FREQ_MULT;
volatile unsigned long freqini2 = 7100000;
volatile unsigned long freqini3 = 3000000;

float freqvelha = 0;
float freqvelha2 = 0;
float freqvelha3 = 0;
long passo = 1000;
char fnal [15];
float VFO = 1 ;

int RECV_PIN = 12;
IRrecv irrecv(RECV_PIN);
decode_results lido;
int gs = 0;
TFT TFTscreen = TFT(cs, dc, rst);
int incr = 1;
int incrvelho = 1;
int incrvelho2 = 1;
int incrvelho3 = 1;
int alt;  //altura do diplay automatica
int larg; // largura do display automatica

// teclas do controle remoto tv sony nova/antiga

float n2 = 0x810  ; //tecla 2 key => aumenta o valor da casa decimal selecionada

float n4 = 0xC10  ; //tecla 4  key => vai para casa decimal a esquerda

float n6 = 0xA10  ; //tecla 6 key => vai para casa decimal a direita

float n8 = 0xE10  ; //tecla 8 key => diminui o valor da casa decimal selecionada

float nf1 = 0x490 ; //tecla VOL +  Seleciona VFO1

float nf2 = 0x90 ; // tecla CH + Seleciona VFO2

float nf3 = 0xC90 ; // tecla VOL - Seleciona VFO3

void setup() {
  TFTscreen.begin();
  TFTscreen.background(0, 0, 0);
  alt = TFTscreen.height();
  larg = TFTscreen.width();
  si5351.set_correction(100);
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 27000000, 0); //If you're using a 27Mhz crystal, put in 27000000 instead of 0
  // 0 is the default crystal frequency of 25Mhz.
  si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
  //si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_2MA); //you can set this to 2MA, 4MA, 6MA or 8MA
  //be careful though - measure into 50ohms
  //si5351.drive_strength(SI5351_CLK1,SI5351_DRIVE_2MA); //you can set this to 2MA, 4MA, 6MA or 8MA
  //be careful though - measure into 50ohms
  //si5351.drive_strength(SI5351_CLK2,SI5351_DRIVE_2MA); //you can set this to 2MA, 4MA, 6MA or 8MA
  //be careful though - measure into 50ohms
  irrecv.enableIRIn(); // Inicializa o receptor IR

}

void loop() {
  si5351.set_freq((freqini * SI5351_FREQ_MULT), SI5351_CLK0);
  TFTscreen.background(0, 0, 0);
  TFTscreen.stroke(255, 255, 0);
  TFTscreen.setTextSize(2);
  TFTscreen.text(" SI5351 VFO" , 0 , 2);
  TFTscreen.stroke(0, 255, 255);
  TFTscreen.text("VFO1" , 40 , 22);
  TFTscreen.stroke(255, 255, 0);
  TFTscreen.setTextSize(1);
  TFTscreen.text("    MHz     kHz      Hz" , 0 , 63);
  while (gs == 0) {

    if (VFO == 1) {
      incrvelho2 = incrvelho2 + 1;
      if ((freqini != freqvelha) || (incr != incrvelho)) {
        if (freqini >= 10000000) {
          si5351.set_freq((freqini * SI5351_FREQ_MULT), SI5351_CLK0);
        }
        else {
          si5351.set_freq((freqini * SI5351_FREQ_MULT), SI5351_CLK0);
        }
        TFTscreen.setTextSize(2);
        format(freqini , 41);
        freqvelha = freqini;
        incrvelho = incr;
        delay(50);
      }
    }
    if (VFO == 2) {
      incrvelho = incrvelho + 1;
      if ((freqini2 != freqvelha2) || (incr != incrvelho2)) {
        if (freqini2 >= 10000000) {
          si5351.set_freq((freqini2 * SI5351_FREQ_MULT), SI5351_CLK1);

        }
        else {
          si5351.set_freq((freqini2 * SI5351_FREQ_MULT), SI5351_CLK1);

        }

        TFTscreen.setTextSize(2);
        format(freqini2 , 78);

        freqvelha2 = freqini2;

        incrvelho2 = incr;
        delay(50);
      }
    }
    if (VFO == 3) {
      incrvelho = incrvelho + 1;
      if ((freqini3 != freqvelha3) || (incr != incrvelho3)) {
        if (freqini3 >= 10000000) {
          si5351.set_freq((freqini3 * SI5351_FREQ_MULT), SI5351_CLK2);

        }
        else {
          si5351.set_freq((freqini3 * SI5351_FREQ_MULT), SI5351_CLK2);

        }

        TFTscreen.setTextSize(2);
        format(freqini3 , 110);

        freqvelha3 = freqini3;

        incrvelho3 = incr;
        delay(50);
      }
    }
    if (irrecv.decode(&lido)) {
      float result = (lido.value);

      if (result) {
        delay(100);

        if (result == nf1)  {
          VFO = 1 ;
          TFTscreen.setTextSize(2);
          TFTscreen.stroke(0, 0, 0);
          TFTscreen.text("VFO2" , 40 , 22);
          TFTscreen.text("VFO3" , 40 , 22);
          TFTscreen.stroke(0, 255, 255);
          TFTscreen.text("VFO1" , 40 , 22);
          TFTscreen.setTextSize(2);
        }
        if (result == nf2)  {
          VFO = 2 ;
          TFTscreen.setTextSize(2);
          TFTscreen.stroke(0, 0, 0);
          TFTscreen.text("VFO3" , 40 , 22);
          TFTscreen.text("VFO1" , 40 , 22);
          TFTscreen.stroke(0, 255, 0);
          TFTscreen.text("VFO2" , 40 , 22);
          TFTscreen.setTextSize(2);
        }
        if (result == nf3)  {
          VFO = 3 ;
          TFTscreen.setTextSize(2);
          TFTscreen.stroke(0, 0, 0);
          TFTscreen.text("VFO2" , 40 , 22);
          TFTscreen.text("VFO1" , 40 , 22);
          TFTscreen.stroke(255, 255, 255);
          TFTscreen.text("VFO3" , 40 , 22);
          TFTscreen.setTextSize(2);
        }
        if (result == n4)  {
          if (incr <= 7) incr ++ ;
        }
        if (result == n6) {
          if (incr >= 1) (incr -- );
        }
        double valor = 0;
        switch (incr) {
          case 0:
            valor = 1;
            break;
          case 1:
            valor = 10;
            break;
          case 2:
            valor = 100;
            break;
          case 3:
            valor = 1000;
            break;
          case 4:
            valor = 10000;
            break;
          case 5:
            valor = 100000;
            break;
          case 6:
            valor = 1000000;
            break;
          case 7:
            valor = 10000000;
            break;
          case 8:
            valor = 100000000;
            break;
        }
        if (VFO == 1) {
          if (result == n2) {
            if (freqini <= 225000000) {
              freqini = (freqini + valor);
            }
            if (freqini > 225000000) {
              (freqini = 225000000);
            }
          }
          if (result == n8) {
            if (freqini > valor) {
              freqini = (freqini - valor);
            }
            else {
              freqini = 0;
            }
          }
          if ((freqini != freqvelha) || (incr != incrvelho)) {
            TFTscreen.fill(0, 0, 0);
            TFTscreen.stroke(0, 0, 0);
            TFTscreen.rect(0, 40, 160, 20);
          }
        }
        if (VFO == 2) {
          if (result == n2) {
            if (freqini2 <= 225000000) {
              freqini2 = (freqini2 + valor);
            }
            if (freqini2 > 225000000) {
              (freqini2 = 225000000);
            }
          }
          if (result == n8) {
            if (freqini2 > valor) {
              freqini2 = (freqini2 - valor);
            }
            else {
              freqini2 = 0;
            }
          }
          if ((freqini2 != freqvelha2) || (incr != incrvelho2)) {
            TFTscreen.fill(0, 0, 0);
            TFTscreen.stroke(0, 0, 0);
            TFTscreen.rect(0, 75, 160, 20);
          }
        }

        if (VFO == 3) {
          if (result == n2) {
            if (freqini3 <= 225000000) {
              freqini3 = (freqini3 + valor);
            }
            if (freqini3 > 225000000) {
              (freqini3 = 225000000);
            }
          }
          if (result == n8) {
            if (freqini3 > valor) {
              freqini3 = (freqini3 - valor);
            }
            else {
              freqini3 = 0;
            }
          }
          if ((freqini3 != freqvelha3) || (incr != incrvelho3)) {
            TFTscreen.fill(0, 0, 0);
            TFTscreen.stroke(0, 0, 0);
            TFTscreen.rect(0, 105, 160, 20);
          }
        }

      }

      delay(50);
      irrecv.resume();
    }

  }
}


void format(unsigned long value , int linha) {
  unsigned long j = 100000000;
  for (int i = 0; i <= 8; i++) {
    int digit = (value / j) % 10;
    incr == (8 - i) ? TFTscreen.stroke(0, 255, 255) : TFTscreen.stroke(255, 255, 0);
    String sfreqini = String(digit);
    sfreqini.toCharArray(fnal, 15);
    TFTscreen.text(fnal , 17 * i + 10, linha);
    if ( (i == 5) || (i == 2)) {
      TFTscreen.stroke(255, 255, 0);
      TFTscreen.text("." , (17 * i + 17), linha);
    }
    j /= 10;
  }

  delay(30);
}



XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

73 de py2ohh miguel jun /2017



Este artigo