ARDUINO NANO + SI5351 QUADRATURE or 90 DEGREES PHASE SHIFT 2 (UPDATE JUN 2018)

ATENÇÃO : a variavel evendivisor não pode ser maior que 127 LINK :

http://qrp-labs.com/images/news/dayton2018/fdim2018.pdf

Modifiquei um VFO com SI5351 para operar com quadratura e fazer alguns testes.


Medindo a frequencia de saida

O esquema é o mesmo do VFO :


Os sinais em quadratura saem pelos CLK0 e CLK1 (VFO1 no sketch) e outra frequencia independente sai pelo CLK2 (VFO3 no sketch).




Montagem tipo sandwich com o display e o SI5351 soquetados

Este sketch gera sinais em quadratura entre 6MHz e 8,333MHz, para gerar outras frequencias é necessario alterar o valor da variavel evendivisor (veja tabelas abaixo), que deve SEMPRE inteira e PAR. Em proxima postagem faremos um VFO de ampla cobertura, onde a tabela da variavel evendivisor estará no sketch.

Sketch :


#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;
unsigned long  pll_freq;
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
int evendivisor = 100;
// 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)) {

        si5351.set_freq_manual(freqini * SI5351_FREQ_MULT, evendivisor * freqini * SI5351_FREQ_MULT, SI5351_CLK0);
        si5351.set_freq_manual(freqini * SI5351_FREQ_MULT, evendivisor * freqini * SI5351_FREQ_MULT, SI5351_CLK1);


        si5351.set_phase(SI5351_CLK0, 0);
        si5351.set_phase(SI5351_CLK1, evendivisor);
        si5351.pll_reset(SI5351_PLLA);
        si5351.update_status();

        TFTscreen.setTextSize(2);
        format(freqini , 41);
        freqvelha = freqini;
        incrvelho = 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 == 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 == 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);
}

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


Montagem retirando o display

Tabela para a variavel evendivisor :

evendivisor 600 900
4 150 225
6 100 150
8 75 112,5
10 60 90
14 42,857 64,286
20 30 45
30 20 30
50 12 18
75 8 12
112 5,357 8,036
Tabela PADRÃO (PLL de 600 a 900MHz) para a variavel evendivisor, para frequencias de 4,7MHz a 225MHz

EVENDIVISOR 600 750 880  limites de  frequencia
4 150 187,5 220 150 220
6 100 125 146,67 105 146,66
8 75 93,75 110 82 105
10 60 75 88 61 82
14 42,86 53,57 62,86 43 61
20 30 37,5 44 30,5 43
28 21,43 26,79 31,43 21,7 30,5
40 15 18,75 22 15,08 21,7
58 10,345 12,931 15,172 10,4 15,08
84 7,143 8,929 10,476 7,2 10,4
122 4,918 6,148 7,213 4,92 7,2
Tabela para o meu SI5351. No meu caso como o limite superior do PLL é de 880MHz e existirá um vazio entre 146,67 e 150MHz.
Esta tabela vai de 4,7MHz a 220MHz


Vista pela parte de traz ... o SI5351 vai monatdo em uma placa adaptadora, e um soquete normal de CI é fixado na parte posterior (centro a esquerda).

Em uso conjunto com um SDR os resultados foram ótimos. Vejam os videos :

https://www.youtube.com/watch?v=Y2_aO5EjRYU

https://www.youtube.com/watch?v=FOpfPFUSaB4

Um video em 40m o outro em 10m ... o munheca aqui diz em um video por duas vezes SI570 e não SI5351 ...é a idade que já chegou rerere...

O SI5351 opera na frequencia direta e não em 4x ...


73 de py2ohh miguel
may 2018
jun 2018 update