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