Cualquier estudiante de ingeniería se ha visto en la necesidad de implementar un ADC, y la verdad es que en casi todos los microcontroladores implementarlo es bastante sencillo. No obstante, en ocasiones no nos preocupamos por optimizar la manera en la que usamos el ADC, puede ser por que los requerimientos de nuestros proyectos no son tan exigentes, o en ocasiones por desconocimiento de las opciones que el microcontrolador nos brinda, pero que no lo hagamos no significa que no sea necesario, y quizá en algún momento cuando se necesite desarrollar un proyecto mas demandante donde la velocidad y la memoria son aspectos a cuidar, este tema podra ser de ayuda. De manera general este tema presenta algunas sugerencias en cuanto el uso del ADC,y la mejor forma de emplearlos y consumir la menor cantidad de recursos del sistema, cabe recalcar que en teoría en muchos microcontroladores es posible aplicar los consejos descritos a continuación, pero la dificultad para hacerlo es variable.
¿Debo usar un ADC por cada señal?
Por lo general tendemos a usar un ADC por cada señal de interés, esto si bien es funcional, consume muchos recursos y memoria, y en situaciones mas estrictas, o bien para algún proyecto con fines de lucro, la memoria es un aspecto critico que se debe intentar optimizar al máximo. Cuando la velocidad de muestreo no es un aspecto muy critico, una opción es usar ADC duales o de doble canal, para alternar entre la lectura de 2 señales, y aunque el muestreo se ve reducido a la mitad, los requerimientos de memoria igual. Por otro lado, algunos microcontroladores mas poderosos como los de la familia 3 y 5 de Cypres por poner un ejemplo, permiten configura ADC para un muestreo múltiple, esto se logra mutiplexando la señales de entrada al ADC de una manera controlada ya sea por por software o por hardware. En internet se pueden encontrar algunos ejemplos de esto, que incluso procesan 16 señales diferentes con un mismo ADC.
¿Polling o interrupciones?
El polling es una practica muy común cuando se intenta implementar de manera rápida algún proyecto de programacion, la finalidad del polling es crear una actividad sincrónica, es decir sincronizar algún tipo de proceso en base a la lectura de algun detonante. No obstante el polling podría ser visto con una pobre implementación en la búsqueda de sincronismo ya que constantemente se hacen consultas esperando hasta el momento en que consulta sea afirmativa, dichas consultas constantes degradan el rendimiento del equipo y el tiempo de ejecución de un programa se ve muy afectado. Si no a quedado muy claro que es el polling el siguiente pseudo código debe aclararlo.
ciclo infinito{
si (Conversion_ADC_Lista==Verdad)
{
//codigo aqui
}
}
Si bien el polling es la mejor opción para la lecturas y sincronización de ciertos procesos como pueden ser la lectura de un acelerómetro. La mayoría de los procesos pueden ser sincronizados mas eficientemente de otros modos, como por ejemplo, pidiéndole al sistema operativo que informe cuando se desencadenado un evento que haga referencia al proceso, en java se les llama oyentes, en C# se les llama eventos, cuando trabajamos con microcontroladores son llamados interrupciones.
El uso de interrupciones aparte de permitir llevar un control mas claro sobre donde y cuando se ejecutan cierto tipo de acciones relacionados con algún proceso, mejora dramáticamente el rendimiento del sistema ya que este no se preocupa por estar a la espera leyendo constantemente el estado de los procesos, si no que el controlador de interrupciones le avisa cuando un proceso debe ser ejecutado, el sistema deja lo que esta haciendo, hace caso a la petición, y posteriormente regresa al punto donde se había quedado y continua.
¿Entonces las interrupciones son la ultima maravilla o hay algo mas?
Trabajar con interrupciones tiene sus limitantes, en primer lugar se tienen que ajustar prioridades en dado caso que varias interrupciones realicen una petición al mismo tiempo lo que puede ser algo problemático. En segundo lugar, el numero de interrupciones permitidas son limitadas, si bien en cada microcontrolador es diferente, es común que incluso en los mas poderosos, el numero de interrupciones permitidas no excedan las 32. Por ultimo y el aspecto mas critico de trabajar con interrupciones es saturar al sistema con ellas, imaginen que se habilitan todas las interrupciones de un microcontrolador y que varios de estos procesos son repetitivos o continuos, como el caso de un ADC, o la interrupción de fin de periodo de una señal PWM, etc. el sistema se vera saturado con dichas peticiones y esto perjudicara el rendimiento, ya que el código de programa principal no puede ser ejecutado a un ritmo constante. Para dicho problema existe algo llamado DMA(Direct Memory Acces) o Acceso directo a memoria.
El DMA permite a cierto tipo de componentes de un computador acceder a la memoria del sistema para leer o escribir independientemente de la unidad central de procesamiento, esto permite a procesos de diferentes velocidades comunicarse sin someter a la unidad central a una carga masiva de interrupciones.
El concepto es algo complicado, pero bastante útil y practico, la transferencia DMA consiste principalmente en copiar un bloque de memoria de un lado a otro. En lugar de que la unidad central inicie la transferencia, la transferencia se lleva a cabo por el controlador DMA.
En el caso que nos ocupa ahora, y por poner un ejemplo, se crea un controlador DMA para hacerse cargo de mover los valores obtenidos de la conversión de un ADC directamente a la RAM del microcontrolador, esto se hace sin interrumpir a la unidad central por lo que esta sigue ejecutando su código principal, en cualquier momento que se requiera la información, esta puede ser tomada de la RAM y así se han reducido dramáticamente los recursos requeridos y se aumenta la velocidad del sistema, de igual manera permite la agilización de operaciones, por ejemplo, se desea calcular un promedio de los últimos 10 valore obtenidos de un ADC, si se usaran interrupciones los datos tendrían que ser almacenados en variables y una vez que se tengan 10, calcular el promedio, si se define en la RAM un bloque de diez espacios en memoria para la transferencia del controlador DMA, solo basta con tomar los 10 valores de la RAM, y en ese mismo momento promediarse ahorrando valioso tiempo de ejecución.
Estos son solo algunos consejos útiles para la optimización del uso de los ADC y de varios procesos en general, si conocen alguno no mencionado, son bienvenidos a comentarlo, si tienen algún comentario o critica igual es bien recibida.