GERADOR DE QUADRATURA COM 2 X AD9850


Foto : geradores DDS setados em 10MHz

Este artigo foi feito somente como referencia para quem se aventurar a montar, fizemos testes e funcionou até 10MHz, segundo o autor a montagem dele foi testada até 20MHz.
O proposito é gerar duas ondas defasadas em 90 graus para uso em equipamentos SDR.
Como a montagem foi muito improvisada, com uma montagem dedicada com circuitos impressos especiais é possivel atingir frequencias mais altas.
O projeto foi baseado no artigo do John G8GKU (gostaria de deixar meus agradecimentos ao John G8GKU  pela ajuda prestada) que pode ser visto aqui
Antes eu havia testado muitos projetos encontrados na web mas nenhum funcionou ou se funcionava não era possivel repetir sem alterar manualment o setup.
Um programa interessante que trabalha com fase, no AD9850, é do colega Martin Oldfield que fez um programa para gerar figuras lissajous é um trabalho interessante para aulas de fisica. link para o site
(eu tambem fiz alterações nos programas do sr. Martin Oldfield quem quizer os sketchs é só escrever).
Para informação aos colegas que quiserem se aventurar sobre fase no AD9850, ele  pode ser setado de steps de 11,5 graus ... em binario
teremos
00000 = 0 graus (0X00 hexa)
00001 = 11,5 graus ( 0X01 hexa)
00010 =  22,5 graus (0X02 hexa)
00011 =  33,75 graus (0X03 hexa)
00100 =  45 graus (0x04)
e assim por diante até
11111 = 348,5 graus (0X1F)

Esquema




Foto as placas do arduino foram interconectadas e presas com parafusos, retirei o oscilador de um dos modulos e refiz a ligação com os lides mais proximos possivel das conexões.


Foto detalhes das placas interligadas


Foto mais detalhes das placas


Montagem com o arduino


Foto usamos as entradas dos eixos X e Y com os dois sinais defasados em 90 graus.

Arquivos para o arduino incluindo as bibliotecas  (estes arquivos deverão ser copiados para a pasta criada pela IDE do arduino).
O programa que fiz foi uma alteração no original , colocando um  controle remoto vendido pelo Ebay (usado em IR do arduino e nos dongles RTL283) Eu tambem usei um arduino nano e um modulo AD9850 diferente do utilizado pelo autor. O programa original gera frequencias fixas setadas pela porta serial do PC / teclado.

Controle remoto usado (outro controle remoto pode ser configurado qualquer duvida me escreva)

O unico cuidado é com as ligações dos terminais FQ das placas que apesar de terem as ligações em comum devem ter um caminho identico entre o arduino (D6) e cada placa. ESTA CONEXÃO É BASTANTE CRITICA !

Sketch principal do arduino (esta incluso no arquivo RAR acima).

#include "DDSDualModule.h"


// Globals for the command interpreter.
String g_command      = "";
const String MHZ      = "mhz";
const String KHZ      = "khz";
const String HZ       = "hz";

//xxxxxxxxxxxxxxxxxxxxx

#include <Wire.h> // biblioteca comunicação
#include <LiquidCrystal_I2C.h> // biblioteca LCD
#include <IRremote.h> // biblioteca controle remoto

#define FREQCORR 0 // correção de frequencia por software

volatile unsigned long frequencia = 1000000;    // Starts at 10mhz
String letra; // uma letra ou numero considerado como letra
String palavra = ""; //uma palavra ou sequencia de letras
long numero = 0; // um numero a palavra transformada em numero
volatile unsigned long frequ; // valor da frequencia
int IRRX_pino = 11; // define o pino de recepção do IR como D11
IRrecv irrecv(IRRX_pino);
decode_results resultado; // apresenta o valor lido no IR em resultado
float armazenavalor; // aramzena o valor lido do IR
int num = 0; // num é um flag ou bandeira se altera a bandeira ocorre algo
int digi = 5; // posição do cursor da frequencia começa no meio 5
double degrau = 0.1; // é o valor em que o cursor da frequencia esta
int i = 1; //
long frmax = 45000000;
long frmin = 10;
int espa = 1;
String branco = " ";
// Inicializa o display, geralmente. no endereco 0x27
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// teclas do controle remoto 
float n0 = 0xFF6897  ; //tecla 0
float n1 = 0xFF30CF  ; // tecla 1
float n2 = 0xFF18E7  ; //tecla 2
float n3 = 0xFF7A85  ; //tecla 3
float n4 = 0xFF10EF  ; //tecla 4
float n5 = 0xFF38C7  ; //tecla 5
float n6 = 0xFF5AA5  ; //tecla 6
float n7 = 0xFF42BD  ; //tecla 7
float n8 = 0xFF4AB5  ; //tecla 8
float n9 = 0xFF52AD  ; //tecla9
float nn = 0xFF629D  ; //tecla CH entrar valor numerico da freq. em kHz
float nncfm = 0xFF906F  ; //tecla EQ confirma valor numerico da frequencia
float nce = 0xFF22DD  ; //tecla <<= seta cursor a esquerda
float ncd = 0xFF02FD  ; //tecla =>> seta cursor a direita
float nsobe = 0xFFA857  ; //tecla + sobe um valor na posição do cursor
float ndesce = 0xFFE01F  ; //tecla - abaixa um valor na posição do cursor


DDSDualModule * g_dualDDS;
void setup() {
 
    // Pins for the DDS modules.
    const int DDS_ResetPin = 4;
    const int DDS_DataPin = 5;
    const int DDS_FreqUpdatePin = 6;
    const int DDSA_DataClockPin = 7;
    const int DDSB_DataClockPin = 8;

    // Initialise the serial port.
    Serial.begin(9600);
    delay(500);
    lcd.begin (16, 2);
    irrecv.enableIRIn(); // Inicializa o receptor IR
   

    // Instantiate a DDSDualModule with the correct pins.
    g_dualDDS = new DDSDualModule(DDS_ResetPin, DDS_FreqUpdatePin, DDS_DataPin, DDSA_DataClockPin, DDSB_DataClockPin); 
}
void loop () {
  if (frequencia > frmax) {
    (frequencia = frmax) ;
  }
  if (frequencia < frmin) {
    (frequencia = frmin);
  }
  if (frequencia >= 10000000)
  {
    espa = 1;
    branco = " ";
  }
  if ((frequencia < 10000000) && (frequencia > 999999))
  {
    (espa = 2);
    branco = " 0";
  }
  if ((frequencia < 1000000) && (frequencia > 99999))
  {
    (espa = 3);
    branco = " 00";
  }
  if ((frequencia < 100000) && (frequencia > 9999))
  {
    (espa = 4);
    branco = " 000";
  }
  if ((frequencia < 10000) && (frequencia > 999))
  {
    (espa = 5);
    branco = " 0000";
  }
  if ((frequencia < 1000) && (frequencia > 99))
  {
    (espa = 6);
    branco = " 00000";
  }
  if ((frequencia < 100) && (frequencia > 9))
  {
    (espa = 7);
    branco = " 00000";
  }
  lcd.setCursor(2, 0);
  lcd.print("Frequencia");
  lcd.setCursor(0, 1);
  lcd.print(branco);
  lcd.setCursor(espa, 1);
  //sendFrequency(frequencia);
 if (frequencia!=frequ){
 unsigned long freq = frequencia;
  g_dualDDS->SetFreq(freq);
 }
  frequ=frequencia;
  lcd.print(frequencia);
  lcd.print(" Hz");
  if (irrecv.decode(&resultado))
  {
    armazenavalor = (resultado.value);
    if (armazenavalor == nn)
    {
      lcd.clear();
      lcd.setCursor(10, 0);
      lcd.print("in kHz");
      delay (1000);
      numerico();
      lcd.clear();
    }
    if (armazenavalor == ncd)
    {
      digi = (digi + 1);
      if (digi > 8 )
      {
        digi = 1 ;
      }
      lcd.setCursor(digi, 1);
      lcd.cursor();
      delay(1000);
    }
    if (armazenavalor == nce)
    {
      digi = (digi - 1);
      if (digi < 1 )
      {
        digi = 8 ;
      }
      lcd.setCursor(digi, 1);
      lcd.cursor();
      delay(1000);
    }
    if (armazenavalor == nsobe) //soma
    {
      do
      {
        degrau = degrau * 10;
        i = i + 1;
      } while (i < (10 - digi));
      frequencia = frequencia + degrau;
      delay(500);
      i = 1;
      degrau = 0.1;
    }
    if (armazenavalor == ndesce) //abaixa
    {
      do
      {
        degrau = degrau * 10;
        i = i + 1;
      } while (i < (10 - digi));
      frequencia = frequencia - degrau;
      delay(500);
      i = 1;
      degrau = 0.1;
    }
    lcd.noCursor();
    irrecv.resume();
  }
  num = 0;
}



void numerico() {
  
  while (num == 0) {
    if (irrecv.decode(&resultado))
    {
      armazenavalor = (resultado.value);
      if (armazenavalor == n1)
      {
        letra = "1";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n2)
      {
        letra = "2";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n3)
      {
        letra = "3";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n4)
      {
        letra = "4";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n5)
      {
        letra = "5";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n6)
      {
        letra = "6";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n7)
      {
        letra = "7";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n8)
      {
        letra = "8";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n9)
      {
        letra = "9";
        palavra = palavra + letra;
        delay (500);
      }
      if (armazenavalor == n0)
      {
        letra = "0";
        palavra = palavra + letra;
        delay (500);
      }
      // xero = xero + ero;
      //lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(palavra);
      lcd.print("kHz");
      // delay(2000);
      if (armazenavalor == nncfm)
      {
        palavra = (palavra + "000");
        numero = palavra.toInt();
        lcd.setCursor(0, 1);
        if (numero > 45000000) {
          (numero = 45000000);
        }
        if (numero < 1000) {
          (numero = 1000);
        }
        frequencia = numero;
        lcd.print(numero);
        //frequ = numero;
        palavra = "";
        letra = "";
        numero = 0;
        num = 1;
        delay(1000);
      }
      irrecv.resume();
    }
  }
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


73 de py2ohh miguel