Panama Hitek Logo
Panama Hitek Logo

DTMF, Control a distancia con teléfono celular

DTMF es la sigla que identifica a Dual-Tone-Multi-Frecuency. En esta oportunidad vamos a realizar un proyecto de control a distancia utilizando el teléfono Celular. Para tal objetivo, nos basaremos en un control por tonos duales, o DTMF.

El tema de decodificación DTMF, es  conocido, lo que resulta interesante es la manera de agregar ciertas características profesionales como contraseña de entrada y claves para activar y desactivar, así también como un dispositivo  audible desde el mismo celular con que se opera, para la confirmación de las acciones realizadas. La idea también es aprovechar para aprender algo sobre la implementación con Microcontroladores PIC.

El sistema conceptual puede dividirse en 3 módulos como se ve en la figura

Bloques control DTMF
Bloques control DTMF

 

 

 

 

Describiremos en profundidad cada bloque con el Hardware y el Software asociado.

DETECTOR DTMF

Los tonos de audio que se generan en un teclado convencional de telefonía están normalizados. En realidad no es un tono simple sino una combinación de tonos formado por dos grupos de tonos, el grupo bajo y el grupo bajo. Cada dígito o carácter del teclado posee una combinación de grupos única e irrepetible que permite determinar el dígito que ha sido pulsado. En este módulo utilizaremos el popular HT9170 que es relativamente simple de utilizar. Este chip puede configurarse de 2 maneras diferentes, en modo diferencial y en modo común. Se utilizó el modo común.

La función de este chip es detectar los grupos validos de un digito y ofrecer un código binario a la salida para que se pueda leer desde un Controlador, o algún otro circuito decodificador.

Les presento el diagrama en bloques:

Chip DTMF
Chip DTMF

 

 

 

 

 

 

 

 

Si bien el Datasheet está disponible en internet y lo pueden bajar, voy a considerar alguna cuestiones de diseño:

Como se observa, a la entrada se encuentra un amplificador operacional para ajuste de ganancia y filtrado. Para operación en modo común el esquema es el siguiente:

Operacional de entrada DTMF
Operacional de entrada DTMF

 

 

 

 

 

 

En esta configuración, se ingresa por la pata negativa del operacional y se observan las ecuaciones de ganancia, impedancia y frecuencia de corte, S=JW y es el operador Laplaciano que se usa para modelar las respuestas de frecuencia y trazar diagramas de Bode. Sin entrar en demasiados detalles, se aprecia que la ganancia posee una raíz en el origen S y un polo (lugar donde la función se hace infinita) en S=1/RC. Para analizar esto matemáticamente es necesario trabajar con el módulo por un lado y con la fase por el otro. Para evitar esto se puede trazar el diagrama de Bode que opera en escalas logarítmicas. Las frecuencias se expresan en dedadas y las amplitudes en decibeles. Así por ejemplo vemos que 1 Hz la amplitud es de -100DB, es decir casi cero. El cero no lo representamos porque el Log base 10 de 0 no existe, en el límite de frecuencia tendiente a cero, la ganancia es prácticamente cero, es lógico dado el capacitor C que filtra la continua. Los ceros en Bode se representan con una pendiente de +20Db/década y los polos a -20 Dpb por década. Cuando se llega a la frecuencia del Polo S=1/RC los +20, se cancelan con -20 y queda una constante que es nuestra ganancia Rf/R. La otra frecuencia de corte queda determinada por el operacional.

Diagrama de BODE respuesta entrada DTMF
Diagrama de BODE respuesta entrada DTMF

 

 

 

 

 

Como se ve queda una banda de paso. Dentro de esta banda deben ingresar todos los tonos a ser detectados, cuya tabla es la siguiente:

Tabla e todos y decodificación binaria DTMF
Tabla e todos y decodificación binaria DTMF

El grupo de frecuencia más pequeño corresponde a 697 Hz, por lo tanto S=1/RC < 697 Hz. Bode también permite saber que justo en la frecuencia de corte la caída o perdida de ganancia es de -3db, es decir 0.707 por la ganancia que tenía hasta ese momento, es decir Rf/R. Todo esto es verificable matemáticamente. El manual recomienda lo siguiente:

HT9170-DTMF
HT9170-DTMF

 

 

 

 

 

 

 

 

 

Como vemos RF=R es decir la ganancia en la banda de paso es 1, la frecuencia del polo es W=1/RC, sabiendo que W = 2*PI*f, se tiene que fc= 16 Hz, es decir que va a atenuar los tonos por debajo de los 16 Hz y entre 16 y el corte del operacional va a amplificar en 1 los tonos que vengan. Por mi parte lo que hice fue darle una ganancia ajustable que no modifica la respuesta pero si la impedancia de entrada, es una relación de compromiso. RF la formé con una resistencia de 12 K en serie con un Preset Multivueltas de 50 K y R=12 K. Luego la ganancia máxima será de 12+50/12 = 6 veces y el corte me quedó en fc=1/12K*0.1Uf = 132 Hz lo cual limita más la banda de paso y lo hace más inmune al ruido. Todo esto a expensas de bajar la impedancia de entrada lo cual por un lado favorece cuestiones de ruido, pero por el otro carga a la salida de audio del celular y va a bajar un poco el nivel, pero funciona muy bien. Ustedes pueden experimentar con sus propios valores.

Ganancia ajustable DTMF
Ganancia ajustable DTMF

 

 

 

 

El resto, se configura similar al Datasheet, con cristal 3.58Mhz, es importante elegir un cristal adecuado, de bajo corrimiento. Yo use uno de 3.575611 MHz y capacitores de 18pf.

En cuanto al resto que se observa RG/CT y EST configuran las constantes internas de detección de un tono válido y se pueden estudiar en el Datasheet y su diagrama de tiempos, pero respetando estos valores funciona correctamente.

Lo importante es la señal DV que emitirá un pulso de 5v indicando que se ha Latcheado o memorizado en el registro de salida D3 a D0 el código binario de un tono dual válido, ver la tabla de tonos anterior de códigos binarios de decodificación.

El resto de los pines del HT9170

OE= 5V fijos

INH y PWDN = 0v

En la tabla de tonos, se ve que del 1 al 9 sigue la conversión convencional de decimal a binario, el 0 sería el 10 en decimal, el “ * “el 11 y el “ # “ el 12. Las letras no las usamos.

MICROCONTROLADOR

Este bloque tiene el objetivo de procesar las funciones del equipo, Las señales D0 a D3 del DTMF van a conectarse a un Puerto del microcontrolador, La señal DV a otro pin del mismo con ciertas características. El puerto de salida del microcontrolador actuará sobre el Driver del sistema de actuación.

Se utilizó un PIC 16F873 con el entorno de programación MPLABX de microchip y compilador XC8. El micro operará a 4 MHz de frecuencia.
Les dejo los siguientes enlaces:

Esta es la parte más compleja, en el sentido que involucra no solo conocimiento de Hard del micro sino también como herramientas de programación, es decir Soft, y conocimiento del lenguaje C como base que usan los compiladores. A diferencia de ARDUINO, los sketches son más simples, es decir, los sketches ya son un C precompilado lo cual lo hace más simple. La idea es tratar de explicarles lo más simple posible este proyecto DTMF ya que hay lectores que no tienen experiencia y por otro lado los que ya conocen del tema puedan usarlo como referencia. La idea no es un Post sobre PIC’s , sino una implementación usando PIC’s, por lo tanto puede haber lectores que no comprendan algunas cuestiones si no han trabajado antes con ellos.

Este POST, como dije, no trata las características de un PIC sino la implementación del proyecto DTMF, no obstante se tratará de ser lo más didáctico posible.

En principio, vemos que cada pin tiene varias identificaciones esto es debido a que los PIC multiplexan

PIC usado en el DTMF
PIC usado en el DTMF

diferentes funciones en cada pin, como Digitales, Analógicas, de eventos externos, fuentes de reloj diversas, protocolos asincrónicos como USART , y sincrónicos como I2C , MSSI para comunicarse con sensores, memorias, etc.

Para que el micro tenga determinada funcionalidad hay que configurar los Registros internos de acuerdo a lo deseado. Esta es una gran diferencia con ARDUINO, que no es necesario conocer el Hard interno.

El esquema de conexiones para el Microcontrolador  como parte del DTMF será el presentado a continuación. He utilizado el Eagle 6.1.0,  para realizar el esquemático y el diseño final de la placa .

Esquema Conexiones Microcontrolador DTMF
Esquema Conexiones Microcontrolador DTMF

 

 

 

 

 

 

 

 

Concentrándonos en este bloque del Micro, observamos lo necesario:

  • Un pulsador de reset general, que es útil para las pruebas.
  • El oscilador externo de 4mhz con los capacitores de 18 pf
  • RA0 a RA3 serán entradas digitales conectadas a D3-D0 del decodificador DTMF, es decir RA0-D3, RA1-D2, RA2-D1 y RA3-D0.
  • El pulso DV de salida de tono válido del DTMF HT9170 se conecta a RB0/INT.
  • Las RB7 a RB4 serán salidas digitales que activarán el driver, módulo que sigue. Cada una maneja la activación / desactivación de una carga de 220 VCA, es decir, este equipo tiene la capacidad de manejar 4 cargas.
  • RB1 será la salida de activación de un Buzer sonoro para dialogar vía celular.
  • RB0/INT será entrada digital del pulso DV del DTMF.

RB0/INT indica que además de ser un pin de entrada/salida digital, puede ser fuente de Interrupciones de eventos externos (INT). De hecho se utilizará de esa manera, es decir cuando se genere un tono válido el pulso de DV disparará una interrupción de software interna en el PIC e irá a atender un bloque de programa especial que atiende dicha interrupción, más adelante se explicará cómo se implementa esto.

Características de funcionamiento

El equipo de control DTMF, funcionará de la siguiente manera:

  • Contraseña de 3 dígitos , por ejemplo “7#*” o la que se prefiera
  • Clave de activación / desactivación de salidas, ejemplo 11* activa salida 1 y 10* la desactiva. Lo mismo para la 2, 3 y 4. <Salida><1-on, 0-off><*>.
  • El sistema opera en 2 estados, estado 0 y estado 1. El estado 0 es cuando se ha conectado y se espera validar la contraseña, sin ella no se podrán operar las salidas. El estado 1 cuando se ha validado la contraseña.
  • En estado 0, el equipo valida 5 segundos de espera entre digito y digito, si expira este tiempo habrá que comenzar de nuevo.
  • En el estado 1, las salidas se pueden operar y permite un timeOut de 5 minutos desde el último pulsado. Aun cuando se corte la comunicación, se podrá llamar nuevamente y operar las salidas sin necesidad de la clave. Pasado ese tiempo volverá al estado 0.
  • Un buzzer sonoro indicará determinadas acciones. Contraseña invalida o clave mal ingresada, serán 10 beeps seguidos. Contraseña válida, un beep largo. Activación / desactivación válida 3 beeps. Estos beeps serán escuchados desde el celular de origen de llamada.

Necesidades de configuración

Pin RBO/INT como entrada y fuente de interrupciones

Timer que cuente 5 segundos y 5 minutos

Funciones de Beep sonoros

Cambios de estado 0 y 1

Contraseñas y claves

Software

Vamos a ir explicando las secciones de código y explicando lo que hacen y su interacción con el Hardware del micro. Para esto es necesario utilizar el MPLABX que es el entorno de desarrollo donde programamos, compilamos, simulamos y guardamos el ejecutable en el propio PIC. Nuevamente, no voy a detenerme en el MPLABX ya que no es el interés de este post. El MPLABX tiene la plataforma del NetBeans de Java.

El proyecto en el MPLABX se verá de esta manera:

Proyecto DTMF
Proyecto DTMF

 

 

 

 

 

 

 

 

Librerías: Se deben incluir en el proyecto y vienen con el compilador XC8

Preprocesadores: todo micro posee registros especiales que preconfiguran globalmente al PIC por ejemplo le decimos que usamos un cristal tipo XT, el WatchDog timer en Off, El Power On Reset que indica que el micro arranca cuando la fuente de alimentación es estable, Programación de bajo voltaje Off, etc. Para más detalle hay que consultar el DataSheet.

Declaraciones: Crear nombres de referencia para mapear bits

Vemos que por ejemplo el pin RB7 del PortB lo llamamos SAL_1. Es decir creamos nuestras propias definiciones de nombres más manejables en el programa. Se ve que el programa posee hasta 6 salidas pero yo solo he implementado 4 por tema de espacio en la plaqueta y dimensiones del gabinete final.

Observamos también que la definición FlagPulsoDTMF que se mapeará con el registro INTCON, bit INTF. Para saber que es esto vamos al datasheet:

PIC 16F873 DTMF
PIC 16F873 DTMF

Este registro controla muchas cosas, lo que nos interesa es que el bit1, INTF es un bit o flag que se enciende cuando ha ocurrido una solicitud de interrupción RB0/INT, para nuestro caso el pulso del DTMF, DV.

Variables

Aquí hay varias cosas, el arreglo Digito[14], es un vector timo string o cadena que relaciona el índice con el carácter, de manera que Digito[código D3-D0] =Carácter buscado, es decir es como un puntero. Por ejemplo si mi código D3-D0 que es un nible de 4 bits es el 00001010 (solo válido lo últimos 4 bits), entonces Digito [10] = ‘0’ carácter 0. Las variables tipo Unsigned Char, son de 8 bits, es decir representan el código Ascii entre 0 y 255 del carácter guardado.

La variable Char código [4] también es un arreglo de caracteres. El Ansi C, al crear una variable cadena o arreglo siempre hay que finalizarla con el carácter NULL de fin de cadena o ‘’. En esta variable vamos a ir concatenando los dígitos de entrada, la cadena se arma cada 3 dígitos más el NULL, por eso su dimensión es 4.

La variable Const Char Contraseña[], similar, aquí definimos la cadena de contraseña.

Unsigned Char estado =0; es el estado del equipo , 0 o 1, ya explicado.

unsigned int contador, lleva la cuenta de los dígitos o caracteres ingresados en la cadena código[].

unsigned int ciclosT1=0, es una variable entera entre 0 y 65535. Para explicar esto debemos saber como es la temporización en los micros.

El cristal es de 4 MHz, es decir que cada pulso de reloj es de 1/4Mhz= 0.25 us. El TCY o ciclo de instrucción es el tiempo que tarda en ejecutarse una instrucción dentro del micro y es una cantidad conocida. La ejecución se lleva a cabo en 4 etapas dentro de la PIPELINE que posee las etapas de Fetch (búsqueda de instrucción) – Decoding (decodifica la instrucción)- OP (operandos) – Ex (ejecución y almacenamiento), es decir que cada TCY = 4 pulsos de reloj. Hay instrucciones que como las de salto que consumen más de 4 ciclos de reloj. Entonces 1TCY= 4×0.25us = 1us. Los TCY son las fuentes de conteo de los timers internos del PIC, como TMR0 ( timer 0), TMR1 ( timer 1), etc.

El Timer 1 es de 16 bits es decir que puede contar entre 0 y 65535 y luego pasa a cero nuevamente, es decir que cada vuelco del Timer1 o ciclo completo puede generar 65536*1us= 65.536 ms. Es 65536 ya que se considera un pulso más desde 65535 a cero cuando desborda y vuelca, lo cual es indicado por el bit flag TMR1IF. Al Timer 1 se le puede asignar un Prescaller, esto es que el pulso que cuente sea el TCY pero dividido previamente:

16F873 DTMF
16F873 DTMF

Los bits del registro T1CON permiten asignar el prescaller al Timer1. Entonces si lo afectamos por un prescaller de 1:8:

ciclosT1= 10 SERAN 5 SEG, 10 desbordes de T1 a 65536 * 0.1us * 8

Prototipo de Funciones

Se definen funciones o métodos para estructurar mucho más todo el software, es decir dividir el problema en sus problemas.

Configuración I/0

Los ADCON1 y 0 regulan la operación analógica digital. Cuando arranca el micro siempre están activados impidiendo el uso de pines I/O digital. Por eso se desactivan. El ADCON1 escribirndo un 0x06 en hexadecimal. Fila 7 de la tabla.

16F873 DTMF
16F873 DTMF

Los TRISA, B, C son los registros de dirección del PUERTO A, B, C, etc. El “1” significa entrada y el “0” salida, inversamente a ARDUINO. Son registros de 8 bits, TRISB0 = definirá RBO, TRISB1, RBI y así siguiendo.

Cuando hacemos uso de PORTB, A, C, etc. estamos leyendo el puerto o escribiendo.

PORTB=0, escribirá 0x00 (00000000) todos 0 a la salida de cada RB7 al RB0. RBO es una entrada por lo cual no tendrá efecto la escritura de RB0.

Configuración Interrupción

 

16F873 DTMF
16F873 DTMF

Si volvemos a la tabla del INTCON veremos los significados de los diferentes bits. El bit INTEDG del registro OPTION_REG define el flanco de disparo de la interrupción IRQ.

Normalmente las interrupciones se habilitan con permisos de periféricos , con bits especiales y el permiso global de interrupciones bit GIE. Cada periférico sea un conversor AD, PWM, TIMERS, ETC poseen Flags de disparo de eventos, al igual que como hemos explicado el RB0/INT. Veamos el siguiente esquema lógico de permisos:

16F873 INTERRUPCIONES DTMF
167873 INTERRUPCIONES DTMF

Los bits IE son los permisos y los IF los flags de eventos. Vemos que GIE=1, habilita globalmente ( compuerta lógica AND). El INTE es el bit que habilita el permiso de Interrupción de RB0/INT via su flag RBIF que ya lo hemos visto. El bit PEIE=0, no permite otra fuente de interrupción de otros periféricos, es un 0 en una AND.

Indicación Sonora

Esta función se encarga de generar una onda cuadrada , el tiempo en ON, y en OFF asi también como la cantidad de ciclos a generar. La función Delay10Ktcy(A), genera 10*1000*1TCY*A demora de tiempo. Esta función debe ser incluida como archivos fuente y está dentro del compilador XC8.

10KTCY = 10*1K*1TCY. El argumento cant, pasado determina la cantidad de ciclos de beep.

Lectura del Puerto del DTMF

Esta función es compleja debido a que en la construcción , para que el HT9170 se conecte al PIC línea a línea y sin cruces de pistas, el PORTA leído y llevado a una variable puerto de 8 bits queda de la siguiente manera:

Variable puerto:

            x      x      x      x D0 D1 D2 D3

Como vemos está invertido en los pesos binarios , y hay que llevarlo a que quede de esta manera:

            0        0      0        0 D3 D2 D1 D0

Esto va a permitir leer la variable puerto directamente el valor decimal del código.

Esto se logra leyendo de a cada bit individual e ir desplazándolo en la variable final juntamente con operaciones OR. Lo dejo para ustedes para analizar.

Ahora el byte retornado será usado de índice para el arreglo Digito[].

Limpiar Todo

Esta función, básicamente vuelve al estado del micro a estado=0, reinicia las variables como si arrancara nuevamente.

El Timer 1

Básicamente se le asigna la fuente de conteo al Timer1, que sea el reloj o Xtal= 4mhz, la fuente de reloj secundaria y externa apagada, el prescaller en 8, su cuenta en cero, y se lo deja apagado. Todo esto se logra con T1CON=0x30;

Encender Timer1

Enciende el Timer, ver tabla del registro T1CON, el bit TMRION

Chequear Tiempo

Si el estado=0, no valido contraseña, el Timer1 se cuentan 10 desbordes del Timer , 5 seg. Si el estado es 1, se cuentan 600 desbordes del Timer. Cada desborde lo acusa el flag TMR1IF , el cual es borrado manualmente ya que no se borra solo después de seteado.

Chequear el estado del Timer1

Simplemente chequea si el Timer esta encendido o apagado..

Apaga el Timer1

Limpiar el Timer1

Lo pone a cero, su cuenta interna actual, pone a cero la bandera de desborde y el contador de ciclos de espera en 0. Este proceso se realiza al validar un digito presionado.

Control de Salidas

Esta función compara el código cadena de 3 digitos con las respectivas claves. Se Observa que dentro de esta función se encuentran strcmp() para comparar cadenas , perteneciente a la librería String.h.

Limpiar código

Esta función lo que hace es resetear la variable cadena código[], con caracteres NULL.

ARMANDO EL PROYECTO DE SOFTWARE COMPLETO

Vamos a comenzar ahora a unir los métodos aislados en una función o método principal que es el main(). Antes de esto vamos a analizar la rutina de Interrupción que es llamada con cada pulso DV del DTMF:

Notar que en todo el código , todo lo colocado entre /*…….. */ son comentarios no tenidos en cuenta por el compilador.

Lo primero que se hace es limpiar el Flag de interrupción ya definido, esto evita que al salir de esta rutina se vuelva a ingresar creando un Loop inestable. Luego limpiamos el Timer1 que es el que cuneta entre digito y digito, seteamos el flagEntrada en ON o 1, que va a indicar al programa principal que se recibió un dígito. Se crea una variable local char carácter[2] que almacena temporalmente el carácter recibido. Luego se crea un índice que va a traer el valor en decimal del código binario leído en el puerto. Después con ese índice entramos como puntero al vector Digito[] y se lo asignamos a carácter[]. Armamos la cadena concatenando con dicho carácter , función strcat(). Si el contador de caracteres es 3, se resetea a cero y se verifica el estado del equipo. Si el estado es cero, verificamos contraseña con strcmp(). Si el código = contraseña, la función devuelve 0 y se pasa a estado =1 y se avisa con el dispositivo de audio, caso contrario, si no es la contraseña, se limpia todo. Si el estado es 1, se va a verificar las claves de control de salidas.

Programa principal

Al arrancar el PIC ejecuta el main() , lo que hace es llama a los métodos de configuración ya vistos y luego entra en un loop continuo del que nunca sale, salvo cuando se dispara una interrupción.

Si el flagEntrada está activo es que se produzco una interrupción y si el Timer1 no está activado, lo activa, luego chequea los tiempos y se queda haciendo esto esperando a que se cumpla en tiempo entre digito y digito o los 5 minutos después de pasar al estado 1.

PROYECTO COMPLETO

MÓDULO DRIVER RELÉ

Para manejar los Reles, en lugar de usar los clásicos transistores en emisor común, se utilizó el ULN2803 que es un driver colector abierto para manejar, en general, cargas inductivas como en este caso relés de 12 V o motores PAP.

ULN2803 DTMF
ULN2803 DTMF

Los diodos son de protección del clásico efecto de sobrepico Lenz al desactival la carga inductiva o bobina de rele. Se produce un sobrepico de tensión que es recortado por los diodos. Para esto se debe colocar el COM a 12 V que es la tensión de manejo de los reles.

El esquema de Drivers es el siguiente:

ULN2803 DRIVER DTMF
ULN2803 DRIVER DTMF

 

 

 

 

 

 

 

 

 

El puerto PORTB del micro se conecta a las entradas del Driver, y sus salidas de esta manera:

Reles DTMF
Reles DTMF

 

 

Juntamente con los relés, se colocan leds indicadores del estado de cada salida. Cuando la salida de driver va a 0 Volt, se activa el rele asociado y su led.

 

 

 

 

 

El esquema completo no se va a visualizar muy bien, pero pueden enviarme un mail y se los paso.

Esquema completo DTMF
Esquema completo DTMF

 

 

 

 

Les dejo un video de muestra del equipo funcionando. Es necesario configurar el celular remoto para respuesta automática de llamada en modo auriculares y con volumen de medio a alto. Espero les haya gustado

FIN

 

 

Gustavo Circelli
Gustavo Circelli
Ingeniero Electrónico egresado de la U.N.Mar del Plata, Analista Programador (ISSD Córdoba) , Profesor PDI (UTN). Especialista en Comunicaciones y sistemas automatizados.

Posts relacionados

Post relacionados