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/


lunes, 11 de marzo de 2013

Arduino-Reduciendo consumo-Parte 2

Página principal

Arduino
Reduciendo consumo
Atmega328 power low
Parte 2
Reloj - DS1302
xsetaseta@gmail.com

En esta segunda parte de como reducir el consumo de mi reloj arduds ,se utilizara la técnica de hacer dormir el ATMEGA328 cuando no se necesite.Este modo se llama SLEEP_MODE_PWR_DOWN, el oscilador externo se para.

SMCR – Sleep Mode Control Register

Existen varias maneras de despertar al ATMEGA328, y una de ellas es el
Watchdog(perro guardián),  es la forma que vamos a utilizar para que despierte el ATMEGA328. El Watchdog utiliza un oscilador  de 128 kHz, separado del reloj principal.
Mediante prescaler podemos hacer que se active en diferentes tiempos, para este caso utilizaré un prescaler a 0.5 Segundos.


Table 10-2. Watchdog Timer Prescale Select

El programa funciona de la siguiente forma:
1.- Se activa el
Watchdog en el setup a 0.5 S.
2.-Empieza el bucle del programa principal.
3.-Se pone el microprocesador a dormir en modo
SLEEP_MODE_PWR_DOWN.
4.-Si se rebasa el tiempo de 0.5 S., se activa el Watchdog y se produce una interrupción.
5.-Se ejecuta el programa de la interrupción.
6.-A la vuelta de la interrupción se sigue ejecutando el programa del bucle principal.
7.-Se vuelve al punto 2 .

Para conseguir aún más consumo he desactivado el conversor A/D de la siguiente forma:
ADCSRA = ADCSRA & B01111111;
ACSR = B10000000;


También existe la posibilidad de deshabilitar las líneas de entrada para ahorrar algo de corriente, pero en mi caso las necesito.
//DIDR0 = DIDR0 | B00111111;
He comentado esta parte para que no se realice.

Programa arduino


Montaje del circuito.

Para poder medir el consumo del circuito por partes y quitar el consumo de los componentes de la placa arduino, he sacado el Atmega en un modulo board. También he añadido un conversor USM->rs232 para poder programar el microcontrolador.


Tabla de consumos

Conversor A/D activado y frecuencia a 16Mhz.

5 V
4 V
4,5 V con diodo  quedando 3,88V
Batería 3,7 V
Atmega 328 + LCD
2,3 mA
1,43 mA
1,50mA (Picos 2,4 mA)
1,42mA(Picos 2,5 mA)
Atmega 328
0,44 mA(Picos 2,2 mA)
0,35 mA(Picos 1,36 mA)
1,36 mA(Picos 1,46 mA)
0,34mA(Picos 1,46 mA)

Conversor A/D desactivado.

5 V
4,5 V con diodo  quedando 3,88V
Batería 3,7 V
Atmega 328 + LCD (0,5-16Mhz)
2 mA(Picos 2,6 mA)

1,17 mA(Picos 1,24 mA)
Atmega (0,5-16Mhz) 0,123 mA

0,08 mA(Picos 1,50 mA)
Atmega 328 + LCD (16Mhz)
1,29 mA(Picos 2,30 mA)
1,20 mA(Picos 2,20 mA)
Atmega 328 (16Mhz)
0,08 mA(Picos 1,17 mA)
0,08 mA(Picos 1,50 mA)

Los picos de corriente corresponden a una mínima porción de tiempo, al despertar del micro cada segundo.

Conclusión:
El consumo del circuito (Atmega328+LCD) en el mejor de los casos es de 1,20 mA .Como podemos observar se encuentra muy penalizado por el LCD, que solo él consume 1,1 mA.
En una situación real donde el circuito se encuentra alimentado por 3 pilas alcalinas de 1,5V (2890mAh) , en total 4,5V, con un diodo en serie que nos quedaría 3,88V. Si consume 1,29mA el circuito, el tiempo máximo de autonomía sera 2240 Horas, 93 días.
Por otro lado si solo se utiliza el Atmega328 quitando el LCD,  la autonomia sería 36125 horas, 1505 días, 4 años.
Lo que verdaderamente aumentaría la autonomía, sería encontrar un LCD de bajo consumo.
Todo esto es bastante teórico, las baterías se autodescargan con el tiempo.
Los picos de corriente aunque sean cortos, disminuyen la autonomía. Existe la posibilidad de poner el Watchdog a un tiempo máximo de 8 segundos, con lo cual el microcontrolador estará dormido mucho más tiempo y aumenta la autonomía del circuito. No he querido tocar el programa principal, para poder ver los segundos, aunque disminuya algo la autonomía.

He de destacar que la diferencia de consumo entre variar la frecuencia y tenerla fija a 16Mhz es mínima. Tiene un motivo, si el micro va despacio, tardará más en ejecutar el programa, y por lo tanto consumirá más. A la inversa pasa lo mismo, es una cuestión de preferencia.

Espero que haya ayudado a aumentar la autonomía de vuestros circuitos.
Para la realización del programa he utilizado código de distinto sitios, modificando a mi gusto ciertas partes, no soy el autor de ciertas líneas del programa.

Saludos.
Juan Galaz


Bibliografía:
http://www.gammon.com.au/forum/?id=11497
http://www.surprisingedge.com/low-power-atmegatiny-with-watchdog-timer/
http://blog.dosbotones.com/2011/09/reducir-el-consumo-de-arduino.html
http://www.sparkfun.com/tutorials/309
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
http://www.engblaze.com/hush-little-microprocessor-avr-and-arduino-sleep-mode-basics/
http://www.fiz-ix.com/2012/11/low-power-arduino-using-the-watchdog-timer/
http://jeelabs.org/2009/05/16/power-consumption-more-savings/

viernes, 8 de marzo de 2013

Reduciendo consumo. Parte 1 Reloj - DS1302

Página principal

Arduino
Reduciendo consumo.
Parte 1
Reloj - DS1302
xsetaseta@gmail.com

En este montaje intentamos reducir el consumo de corriente de mi anterior montaje arduds.html.
El consumo de todo el circuito incluido placa de arduino y LCD es de 23,3 mA.
En esta primera parte he utilizado tres métodos para reducir el consumo.

Método 1.
El primero es variar dinámicamente mediante el programa la velocidad del reloj del ATMEGA328.
Esto se consigue modificando el registro CLKPR – Clock Prescale Register.


En la parte del programa que quiero que corra a 16MHZ pongo las ordenes:
            CLKPR = (1 << CLKPCE);
            CLKPR = 0; // Velocidad 16Mhz

En la parte del programa que quiero que corra a 500khz pongo las ordenes:
               CLKPR = (1 << CLKPCE);
             CLKPR = 5;  // Velocidad 500khz      

Método 2.
El segundo método para reducir el consumo es el de reducir el voltaje de alimentación del circuito.
El arduino utiliza 5V para la alimentación de todo el circuito. Si se disminuye el voltaje de 5V a 4V podemos obtener un significativo ahorro de consumo.
Podríamos disminuir el voltaje hasta 2,8 V, pero los LCD no trabajan por debajo de los 4V, con lo cual el microcontrolador funciona, pero en el LCD no se ve nada.
Tengo un LCD que en teoría funciona con 3,3V, pero en la práctica por debajo de 3,6V no se ven los caracteres.


Método 3.
El tercer método para reducir el consumo es montar solo el microcontrolador con los componentes mínimos para que funcione, cristal y dos condensadores. De esta forma eliminamos el consumo del conversor USB->RS232 y otros componentes que lleva la placa.
Si no se requiere mucha precisión de reloj, podríamos eliminar el crystal y los dos condensadores, utilizando el oscilador interno de  8 MHz. Estó requiere modificar el boot del arduino por lo que lo he descartado.

Montaje del micro con los dos condensadores y el cristal.

Programa arduino

Después de realizar todas la pruebas, estos son los resultados:

5V
4V
3,7V
16Mhz
23.3mA
14,5mA

2MHz
14,4mA
9mA

1MHz
13,4mA
8,6mA

500KHz
13,2mA
8,3mA

500KHz(Atmega328+LCD)
5,5mA
4,5mA
2,6mA

En el mejor de los casos, si alimentamos el circuito con 3 pilas alcalinas en serie (4,5V) de 2890mAH y colocamos un diodo en serie para bajar el voltaje a 3,8V la corriente medida es de 2,6mA.
Si dividimos 2890 entre 2.6 el resultado es de 1111 horas, 46 días. Siempre es algo menos debido a la autodescarga de la propia batería.
Si quitamos el LCD en consumo se reduce a 1mA, alimentando el Atmega a 3,7V.

En la segunda parte trataremos el poner el microcontrolador a dormir para disminuir el gasto de la batería.

Saludos
SETA43

Bibliografía:
http://www.gammon.com.au/forum/?id=11497
http://www.surprisingedge.com/low-power-atmegatiny-with-watchdog-timer/
http://blog.dosbotones.com/2011/09/reducir-el-consumo-de-arduino.html
http://www.sparkfun.com/tutorials/309
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/

martes, 5 de marzo de 2013

Arduino - Reloj mediante DS1302

Página principal

Arduino
Reloj mediante DS1302
xsetaseta@gmail.com

Este montaje es otro reloj realizado mediante el CI DS1302.
El DS1302 es un integrado que contiene un reloj-calendario.
A falta de alimentación sigue funcionando mediante una pequeña batería de 3V.

La comunicación con el microprocesador se realiza mediante 3 lineas, siendo el formato de comunicaciones propio y muy simple.
El reloj realizado tiene además de hora-minutos-segundos , día-mes-año, una alarma y un auto apagado.
El programa es una mezcla de el programa que viene como ejemplo en la página de arduino
http://playground.arduino.cc/Main/DS1302y mi montaje http://seta43.duckdns.org/ardura2.html.
Estuve probando la librería ds1302 para el arduino, pero me paso algo curioso, a pesar de tener dos DS1302 aparentemente iguales, el uno funcionaba y el otro no. Por lo cual decidí utilizar el programa que viene como ejemplo en la página de arduino, que funciona en los dos CI.

Para mantener la alarma cuando se va la alimentación, he utilizado los registros del propio DS1302.

El programa tiene el siguiente menú:
SLEEP
ALARM
TIME
   DATE   
60 Minutos, -10 min.
ON/OFF
HORAS
DIA

HORAS
MINUTOS
MES

MINUTOS

AÑO



Circuito montado


El DS1302 montado con la batería


Esquema del circuito.

Programa arduino


Saludos
SETA43

Bibliografía:
http://playground.arduino.cc/Main/DS1302
http://salvador.maciashernandez.com/Escolares/Microprocesadores/DS1302/DS1302_001.html
http://www.fettesps.com/time-keeping-with-the-arduino-and-ds1302/
http://henningkarlsen.com/electronics/library.php?id=5

sábado, 2 de marzo de 2013

Radio-Reloj-Despertador con TEA5767 y Arduino.

Página principal

Radio-Reloj-Despertador con TEA5767 y Arduino.


Este montaje es un radio-reloj-despertador realizado con TEA5767 y un arduino.
Para manejar todas la funciones se utiliza dos pulsadores para los menús.
Hubiese sido mucho mas fácil utilizar mas botones pero lo he hecho de esta forma para minimizar al máximo el interface.
Para cambiar la frecuencia en modo DIAL se utiliza un potenciómetro.
Como amplificador de audio he utilizado unos altavoces de PC auto-alimentados.
Dispone de 20 memorias, se almacenan en la EEPROM de microcontrolador, por lo cual no desaparecen cuando se desconecta la radio.
El reloj se basa en interrupciones internas de microprocesador, cuando se quita la corriente se va la hora.
En próximos montajes utilizare un DS1302 como reloj, es más preciso y no se va la hora.
Todo se ven en un LCD de 2x16 caracteres.

El TEA5767 es un integrado que tiene todo lo necesario para realizar una radio FM. Se necesitan unos pocos componentes añadidos para su funcionamiento, de tal forma que se pueden comprar todo el conjunto montado por 3,5€.
Toda la programación del TEA5767 se realiza mediante el I2C-bus.
Las características del TEA5767 son las siguientes:
* High sensitivity due to integrated low-noise RF input amplifier
* FM mixer for conversion to IF of the US/Europe (87.5 MHz to 108 MHz) and Japanese
  (76 MHz to 91 MHz) FM band
* Preset tuning to receive Japanese TV audio up to 108 MHz
* RF Automatic Gain Control (AGC) circuit
* LC tuner oscillator operating with low cost fixed chip inductors
* FM IF selectivity performed internally
* No external discriminator needed due to fully integrated FM demodulator
* Crystal reference frequency oscillator; the oscillator operates with a 32.768 kHz clock
  crystal or with a 13 MHz crystal and with an externally applied 6.5 MHz reference
  frequency
* Phase-locked loop (PLL) synthesizer tuning system
* I2C-bus and 3-wire bus, selectable via pin BUSMODE
* 7-bit IF counter output via the bus
* 4-bit level information output via the bus
* Soft mute
* Signal dependent mono to stereo blend [Stereo Noise Cancelling (SNC)]
* Signal dependent High Cut Control (HCC)
* Soft mute, SNC and HCC can be switched off via the bus
* Adjustment-free stereo decoder
* Autonomous search tuning function
* Standby mode
* Two software programmable ports
* Bus enable line to switch the bus input and output lines into 3-state mode
Recomiendo encarecidamente ver product data sheet el TEA5767 y APPLICATION NOTE, para ver todas sus características y modos de programación.

Esquema de TEA5767


TEA5767 con todos los componentes.


Descripción de la patillas.


TEA5767 montado sobre un circuito impreso.


Arduino controlando el TEA5767 mediante el bus I2C.

Esquema

Para encender la radio, pulsar Button1->Button2->Button1, y la radio estara encendida 60 minutos.
También se encenderá la radio al llegar a la hora de la alarma, siempre y cuando este activa la alarma, esta alarma es diaria.
Se sabe que la alarma está activa cuando aparece una "A" colocada a la izquierda de la hora.
Alternativamente se muestra el nivel de señal y si la señal es mono o stereo.


Imagen del LCD

Programa del arduino

MENÚS
(Cambiar con Button1 y seleccionar con Button2)

SLEEP Button2 decrementa desde 60 min. en 10 min. hasta llegar
a 10 minutos, despues decrementa en 1min. hasta llegar a 0.
Salir con  Button1.
MODE MEMO En el modo memo se cambian las emisoras memorizadas mediante Button2.
Cada pulsación aumenta el numero de memoria.
Cuando llega a 20 se vuelve a cero.
MODE SCAN Escanea emisoras desde la posición actual de frecuencia pulsando Button2.
Llegado a 108MHz vuelve a buscar desde 87.5MHz.
MODE DIAL Sintoniza la frecuencia mediante el potenciometro.
ALARM Se selecciona entre (ON/OFF-Horas-Minutos) con Button1.
Se cambia el valor con Button2.
MEMORY Se selecciona la memoria con Button2. Se memoriza con Button1.
LEVEL-SCAN Se cambia el valor (1-2-3) con Button2. Se selecciona con Button1.
TIME Se selecciona entre (Horas-Minutos) con Button1.
Se cambia el valor con Button2.

Debido a que la frecuencia intermedia es de 225KHz, puede ocurrir de ciertas ocasiones cuando la señal de dos emisoras sean muy fuerte y este muy cerca la una de la otra que se interfieran.
Para estos casos deberiamos utilizar el bit :
    4 HLSI HIGH/LOW Side Injection: if HLSI = 1 then HIGH side LO injection; if HLSI = 0 then   LOW side LO injection
Además deberiamos cambiar el modo de que se calcula la frecuencia, mirar APPLICATION NOTE.
En mi ciudad existen bastantes emisoras, pero no me a ocurrido el problema, por lo cual no he tenido en cuenta el problema.

Vídeo de la radio funcionando


Saludos.
JUAN GALAZ



Bibliografía:
http://www.doctormonk.com/2012/03/tea5767-fm-radio-breakout-board-for.html
http://www.electronicsblog.net/arduino-fm-receiver-with-tea5767/
http://kalum.posterous.com/arduino-with-tea5767-single-chip-radio-and-no