domingo, 17 de marzo de 2013

Arduino AD9850 DDS(Direct Digital Synthesizer) Generador señal desde 1Hz a 40MHz

Arduino
AD9850
DDS(Direct Digital Synthesizer)
Generador señal desde 1Hz a 40MHz
xsetaseta@gmail.com

Versión 2.  23/09/2014
Después de 1 año del montaje me mandaron algunos correos de que no les funcionaba el circuito.
Les pregunte que placa de arduino utilizaban, y me dijeron que era la placa leonardo, algunos me mandaron imagenes de sus montajes.
Después de que comprara la placa y montara el circuito, efectivamente no funcionaba.
Buscando el motivo por el cual funcionaba perfectamente en Arduino_Diecimila y no funcionaba en Arduino_Leonardo encontré el motivo.
Para utilizar los pin A0 y A1 como entradas digitales se hacía referencia a los pin 14 y 15, pero ahora con las nuevas versiones del compilador se deben utilizar A0 y A1.
Por lo que he cambiado lo siguiente:

//Arduino_Diecimila
//#define e1Pin 14
//#define e2Pin 15

por

//Arduino_Leonardo
#define e1Pin A0
#define e2Pin A1

 y ya funciona perfectamente.

Programa Arduino modificado.


Navegando por la red encontré un generador de señal senoidal de entre 1Hz y 40MHz.
Estaba realizado en torno al circuito integrado DDS (Direct Digital Synthesizer) AD9850, y su costo rondaba los 5€.
La tentación de poder tener un generador de señal por ese precio era simplemente irresistible.
Para controlar el AD9850 he utilizado un arduino, representando la frecuencia de señal en un LCD.
He utilizado dos pulsadores y un potenciómetro para poder modificar la frecuencia generada.
La señal de salida es de 1V pico a pico, reduciendo su amplitud a frecuencias altas.

Módulo DDS con el AD9850

El programa de arduino dispone de una serie de menús para cambiar la frecuencia.
En el primer menú, que es por defecto, se puede cambiar todos los dígitos de la frecuencia, desde 1Hz a 40MHz. Pulsando el botón1 se recorren todas las cifras, desde millones a unidades, y con el boton2 se cambia el valor de la cifra en cuestión.
A continuación existen varios menús, +500, +5K, +50K, +500K, que desplazan la frecuencia prefijada mediante un  potenciómetro.


Esquema del circuito.



Circuito generando una frecuencia de 1000Hz



Lectura de la frecuencia en mi frecuencímetro



Onda mostrada en el osciloscopio

Para manejar el AD9850 desde arduino, existen dos posibilidades, utilizar una librería que existe específicamente para ello, o utilizar varias funciones que se pueden insertar en tu propio código. Me he decidido por insertar las funciones en mi propio código debido a que son bastante simple y no aumentan mucho el tamaño del código fuente.
Las funciones las he sacado de:
 http://webshed.org/wiki/AD9850_Arduino#Wiring_up_.26_example_code_download
son funciones muy sencillas, como se pueden ver en el siguiente código:

//AD9850 DDS test

#define DDS_CLOCK 125000000

#define  CLOCK  8  //pin connections for DDS
#define  LOAD 9
#define  DATA  10
#define  RESET 11

void setup()
{
  pinMode (DATA,  OUTPUT);
  pinMode (CLOCK, OUTPUT);
  pinMode (LOAD,  OUTPUT);
  pinMode (RESET, OUTPUT);
  AD9850_init();
  AD9850_reset();

  SetFrequency(10000000);

}

void loop()
{

}

void SetFrequency(unsigned long frequency)
{
  unsigned long tuning_word = (frequency * pow(2, 32)) / DDS_CLOCK;
  digitalWrite (LOAD, LOW);

  shiftOut(DATA, CLOCK, LSBFIRST, tuning_word);
  shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 8);
  shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 16);
  shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 24);
  shiftOut(DATA, CLOCK, LSBFIRST, 0x0);
  digitalWrite (LOAD, HIGH);
}

void AD9850_init()
{

  digitalWrite(RESET, LOW);
  digitalWrite(CLOCK, LOW);
  digitalWrite(LOAD, LOW);
  digitalWrite(DATA, LOW);
}

void AD9850_reset()
{
  //reset sequence is:
  // CLOCK & LOAD = LOW
  //  Pulse RESET high for a few uS (use 5 uS here)
  //  Pulse CLOCK high for a few uS (use 5 uS here)
  //  Set DATA to ZERO and pulse LOAD for a few uS (use 5 uS here)

  // data sheet diagrams show only RESET and CLOCK being used to reset the device, but I see no output unless I also
  // toggle the LOAD line here.

  digitalWrite(CLOCK, LOW);
  digitalWrite(LOAD, LOW);

  digitalWrite(RESET, LOW);
  delay(5);
  digitalWrite(RESET, HIGH);  //pulse RESET
  delay(5);
  digitalWrite(RESET, LOW);
  delay(5);

  digitalWrite(CLOCK, LOW);
  delay(5);
  digitalWrite(CLOCK, HIGH);  //pulse CLOCK
  delay(5);
  digitalWrite(CLOCK, LOW);
  delay(5);
  digitalWrite(DATA, LOW);    //make sure DATA pin is LOW

    digitalWrite(LOAD, LOW);
  delay(5);
  digitalWrite(LOAD, HIGH);  //pulse LOAD
  delay(5);
  digitalWrite(LOAD, LOW);
  // Chip is RESET now
}

A este código he añadido los menús, y el controlador de LCD.
Programa arduino.

Saludos.
JUAN GALAZ

Bibliografía:
http://danirebollo.blogspot.com.es/2012/06/ad9850-cmos-125-mhz-complete-dds.html
http://webshed.org/wiki/AD9850_Arduino
http://alhin.de/arduino/index.php?n=70
http://www.elecfreaks.com/2110.html
http://www.analog.com/en/rfif-components/direct-digital-synthesis-dds/ad9850/products/product.html
http://www.scienceprog.com/


5 comentarios:

  1. saludos. donde encuentro losmenus y el controlador de LCD?

    ResponderEliminar
  2. Hola

    El código fuente del arduino se encuentra en el enlace Programa arduino, hay se encuentra la parte del código de los menus y LCD.
    El código que muestro es solo una parte del código para entender como se gobierna el chip.

    Saludos

    ResponderEliminar
  3. amigo os 4 ponto de saída do Arduino que indica reset,data,fq_ud-load,clk vai para o modo AD9850?

    ResponderEliminar
  4. o esquema a cima amigo é completo com Arduino mais o modo ad9850.

    ResponderEliminar
    Respuestas
    1. Hola

      No te comprendo bien lo que quieres decir.
      El el montaje funciona bien tal como está, y dependiendo el modelo de arduino que utilices debes cambiar dos líneas de código.
      También hice otro montaje con el AD9850 para generar frecuencia para los 40m de radio.
      http://seta43.blogspot.com.es/2014/12/arduino-ad9850-ddsdirect-digital.html
      Igual te sirve mejor este montaje.

      Juan Galaz

      Eliminar