lunes, 30 de mayo de 2011

USB con microcontroladores AVR

Hoy en día cuando surge la necesidad de crear sistemas embebidos con microcontroladores, los cuales deben interactuar con computadores, se hace completamente necesaria la implementación de una interfaz a través del puerto USB. Anteriormente se hacía uso del puerto paralelo del computador, y posteriormente el puerto serial RS-232; sin embargo, estos puertos se están volviendo obsoletos y ya casi todos los computadores que salen al mercado no disponen de estos puertos.

Para tratar de solucionar este inconveniente, en el mercado se encuentra una popular interfaz que permite convertir desde RS-232 a USB. Sin embargo, implica un costo adicional y más espacio físico. A continuación se muestra una popular interfaz de RS-232 a USB:


De esta forma, es completamentamente recomendable incluir el protocolo USB directamente con el microcontrolador y así aprovechar las ventajas que trae consigo el uso de este tipo de puerto.

Los fabricantes de microcontroladores ya incluyen en sus chips el hardware necesario para hacer uso del puerto USB. Atmel incluye en algunos de sus microcontroladores de 8 bits el hardware necesario para la implementación de puerto USB.

Así, se desarrolló una librería completamente libre para trabajar con USB, tanto en modo HOST como en modo DEVICE. La librería se llama LUFA, y se puede encontrar una documentación muy completa en su página oficial.


Las clases que soporta esta librería son:
  • Audio: Device
  • CDC: Device, Host
  • HID: Device, Host
  • Midi: Device, Host
  • Almacenamiento masivo: Device, Host
  • Impresora: Host
  • RNDIS: Device, Host
  • Imagen fija: Host

La única limitante que tiene esta librería es que funciona únicamente con los microcontroladores USB de AVR. Para quienes no tienen a disposición un dispositivo microcontrolador que incluya en su hardware una interfaz USB, existe la librería V-USB, mediante la cual es posible implementar el protocolo USB con cualquier dispositivo AVR, sin necesidad que éste sea de tipo USB.



La librería V-USB funciona con cualquier microcontrolador AVR con al menos 2 kB de memoria Flash, 128 bytes de RAM y un reloj de al menos 12 MHz. La documentación de esta librería se encuentra en el sitio oficial.

Las dos opciones mencionadas anteriormente son bastante buenas e incluyen una gran cantidad de documentación y ejemplos. Con todas estas herramientas a disposición, hago la invitación a desarrollar proyectos con interfaz USB, y dejar atrás la vieja interfaz RS-232.

martes, 24 de mayo de 2011

Procesamiento de imágenes en Python

El procesamiento digital de imágenes es un tema muy extenso del cual existe una gran cantidad de libros y tratados que explican a profundidad todas las técnicas disponibles para extraer características o información útil a partir de una imagen. En esta entrada del Blog, enunciaré brevemente algunas herramientas que se pueden usar con Python para una aplicación sencilla, haciendo uso de una cámara web conectada al PC.

El procesamiento de imágenes hoy en día tiene un gran rango de aplicaciones, entre las cuales podemos encontrar:
  • Identificación de vehículos infractores
  • Reconocimiento de rostros para seguridad
  • Seguridad en viviendas y locales comerciales
  • Vigilancia de movimiento de vehículos
  • Aplicaciones de automatización industrial y verificación de calidad de productos
  • Robótica y sistemas de visión de robots y autómatas
  • Entre otras...



Adquisición

Si se cuenta con sistema operativo Linux, y una webcam, es bastante sencillo adquirir imágenes a partir de la misma usando un script en Python, únicamente se deben tener instaladas las librerías de opencv (Open Source Computer Vision), y comprobar que la cámara se encuentre listada en los drivers para linux UVC. A continuación se muestran las líneas de código necesarias para tomar una fotografía usando la webcam y convertirla al formato de imagen de Python:

import opencv.adaptors
from opencv import highgui 
import Image

camera= highgui.cvCreateCameraCapture(0)

im = highgui.cvQueryFrame(camera)
mat = opencv.cvGetMat(im)
im = opencv.adaptors.Ipl2PIL(mat) 

Preprocesamiento

Por su parte, la librería de imágenes de python (PIL) contiene una gran cantidad de herramientas que permiten procesar la imagen de forma adecuada para analizarla. Así, es posible realizar diferentes tipos de transformaciones como rotación, traslación, aumento, reducción, efecto de lentes, operaciones matemáticas, diferentes tipos de filtrado para realzar características específicas, umbralización, binarización, etc.

Para realizar todas las operaciones mencionadas anteriormente, se tienen a disposición los siguientes módulos:
  • Image: Permite abrir, guardar, convertir, evaluar funciones y obtener información de imágenes.
  • ImageDraw: Permite agregar formas geométricas y texto a imágenes.
  • ImageEnhance: Permite mejorar la calidad de las imágenes, ajustando parámetros como brillo, contraste y nitidez.
  • ImageFilter: Es un módulo que incluye varios filtros que pueden ser aplicados fácilmente a cualquier tipo de imágenes.
  • ImageMath: Permite realizar operaciones matemáticas con imágenes.
Para más información sobre estos u otros módulos, puede consultar la página de documentación oficial de la librería PIL.

Procesamiento y extracción de características

Los procedimientos a realizar en este paso del análisis de imágenes dependen mucho de la aplicación específica para la cual se esté desarrollando. Sin embargo, la mayoría de veces es necesario umbralizar la imagen para tener una matriz binaria y extraer la características necesarias para identificar patrones en la misma.

Cuando se trabaja con imágenes binarias, generalmente se hace necesario aplicar operaciones morfológicas, mediante las cuales es posible filtrar ruido, mejorar regiones de interés o identificar formas específicas. De esta forma, la librería pymorph implementa las funciones morfológicas más comunes para el procesamiento de imágenes. Se debe tener en cuenta que esta librería no opera con objetos de tipo imagen PIL, sino que es necesario realizar la conversión a matriz bidimensional de python.

Para una referencia más completa sobre la librería pymorph, consultar la documentación oficial AQUI.

miércoles, 18 de mayo de 2011

Python vs. Matlab

En el aporte del día de hoy daré mi punto de vista y comparación entre 2 herramientas de programación usadas ampliamente por desarrolladores e investigadores: Python y Matlab. Resaltaré los puntos fuertes y débiles de cada uno de estos lenguajes, y no diré cual es mejor, pues esa respuesta depende mucho del contexto de la aplicación; sin embargo complementaré la respuesta y diré cual es mejor para determinados propósitos, ya que ambas herramientas son excelentes, dependiendo del propósito para el cual se estén usando.


Matlab

Matlab es una herramienta muy potente, principalmente usada en el ámbito académico y de investigación por la rapidez con la cual se pueden desarrollar algoritmos. Está diseñado para probar metodologías, sin tener que preocuparse por los detalles de implementación. Lo anterior, lo hace ideal para pruebas preliminares y para validar determinados métodos de forma rápida y confiable. Los Toolboxes disponibles proveen muchas funciones y librerías que hacen muy fácil la implementación de algoritmos complejos para todo tipo de procesamiento. Adicionalmente, está disponible tanto para sistema operativo Windows, como para sistemas Linux.

La principal desventaja de esta herramienta es que no es un sistema gratis, y además es costoso, pues es necesario comprar cada Toolbox por aparte. Además, no es posible generar aplicaciones stand alone, sino que siempre es necesario instalar las librerías en el equipo en el cual se ejecutará la aplicación, con su correspondiente licenciamiento.

Python

Python es libre y de código abierto, viene preinstalado en muchas de las distribuciones actuales de Linux, y también puede ser instalado en Windows. Es un lenguaje orientado a objetos sencillo de usar cuya curva de aprendizaje es muy corta. No tiene tantas funcionalidades y herramientas como las que ofrece Matlab, pero aún así es muy sencillo de usar. Python es el punto intermedio entre C++ y Matlab.

En cuanto a librerías y herramientas, están a disposición una gran cantidad de módulos que se pueden descargar de forma gratuita. Por otra parte, Python permite generar ejecutables finales para aplicaciones stand alone, sin necesidad de instalar librerías adicionales en el equipo final.

En conclusión...

Matlab es una excelente herramienta para investigar y desarrollar (si se tienen los recursos necesarios para las licencias), pues permite ahorrar mucho tiempo en validación. Sin embargo, cuando se debe pasar a un entorno de producción y desarrollar aplicaciones para usuarios finales, recomiendo Python.

lunes, 9 de mayo de 2011

Servidor Web miniatura

Cuando escuchamos hablar de un Servidor Web nos imaginamos siempre un gran computador, con múltiples discos duros, una gran RAM, almacenado en un gabinete con sus correspondientes sistemas de conectividad, alimentación y refrigeración. Sin embargo, los avances tecnológicos de la actualidad han hecho posible implementar un servidor Web en una tarjeta de menos de una pulgada cuadrada.

A continuación se puede ver la imagen de un servidor de este tipo disponible en el mercado:
Un servidor Web es un sistema que permite resolver peticiones que se originan desde otros equipos hacia la IP que tiene asignada el servidor, a través de un puerto, el cual generalmente es el 80 para peticiones HTTP efectuadas desde un navegador.

El sistema anteriormente mencionado únicamente necesita un conector para Ethernet con los correspondientes filtros necesarios para la conexión con una red de área local. El dispositivo se puede conectar con un microcontrolador a través de una interfaz UART, y no necesita de hardware especializado adicional. Por otra parte, este servidor incluye un microcontrolador el cual se puede programar y no hace necesario el uso de un microcntrolador externo.

Las páginas que se servirán con este dispositivo se diseñan en HTML estándar, haciendo que el desarrollo de software no sea demasiado complejo. Además, es posible configurarlo para funcionar con dirección IP estática o dinámica, dependiendo de las necesidades de la aplicación.

En cuanto a costo, este dispositivo puede conseguirse desde 27 dólares, el cual es un muy buen precio, teniendo en cuenta todas las prestaciones que ofrece.

Este servidor puede tener muchas aplicaciones en el desarrollo de dispositivos electrónicos, especialmente para la implementación de interfaces de usuario gráficas y amigables, dejando atrás los pulsadores, potenciómetros, pantallas de cristal líquido monocromáticas, LEDs, etc, pues todos estos sistemas de interfaz de usuario pueden ser implementados a través de software en una página Web.

lunes, 2 de mayo de 2011

Uso de PWM en ATMEGA16

En la publicación del día de hoy mostraré un ejemplo práctico con código fuente incluido para el uso del módulo PWM del microcontrolador ATMEGA16. Este ejemplo se hace para este microcontrolador en específico, pero es posible aplicarlo a cualquier otro microcontrolador ATMEGA que tenga módulo PWM cambiando los correspondientes registros.

Se debe controlar un motor DC usando una señal PWM (generada con el Timer 0 en modo PWM con corrección de fase), la cual puede tener 8 niveles de ciclo de trabajo, desde 0% hasta 100%. Los niveles del PWM se deben modificar a través de dos interruptores pulsadores con los que se podrá incrementar o reducir un nivel de ciclo de trabajo por cada pulsación de éstos. Adicionalmente, el nivel actual del PWM se debe mostrar usando una barra de LEDs conectada al puerto C del microcontrolador.

El código fuente para solucionar el anterior ejemplo, se muestra a continuación:


//*****************************************************
// Programa para el control de velocidad de un motor DC
//
// Descripción: Mediante este programa se usa el módulo
// de PWM con corrección de fase del Timer 0 para el
// control de la velocidad de un motor DC a través de
// dos pulsadores, los cuales permiten aumentar o
// reducir la velocidad

//*****************************************************

// Dispositivo = ATMEGA16
// Fclk = 1.0MHz

#include<avr/io.h>


int main(void)
{

// Variable que guarda el nivel de velocidad
// del motor (0..8)
volatile char nivel=0;

// Configuración de dirección de puertos I/O
DDRA=0x00; // Puerto A como entrada
DDRC=0xFF; // Puerto C como salida
DDRB|=(1<<DDB3);// Pin 3 de puerto B como salida

PORTA=0xFF; // Habilitación de pull-ups del puerto A
PORTC=0x00; // Inicialización de salida del puerto C

// Configuración del Timer 0:
// * Modo PWM con corrección de fase
// * Modo no inversor
// * Fuente de reloj directa desde el oscilador del microcontrolador
TCCR0|=(1<<WGM00)|(1<<COM01)|(1<<CS00);

// Inicialización del PWM
OCR0=0x00;

// Ciclo de polling
while(1)
{
// Se evalúa si se ha presionado algún botón
if(PINA!=0xFF)
{
// Se evalúa cual botón se presionó
switch(PINA & 0x03){
case 1: if(nivel<8)
nivel++; // Incrementa velocidad
break;
case 2: if(nivel>0)
nivel--; // Decrementa velocidad
break;
};

PORTC=(1<<nivel)-1; // Visualización en barra de LEDS

OCR0=32*nivel-1*(nivel!=0); // Actualización de PWM

// Ciclo que pone el sistema en espera hasta que
// se libere el botón presionado
while(PINA!=0xFF)
{
asm("nop");
}
}
}

}

Para solucionar el anterior ejemplo, se observa que se inicializan los puertos asignando su correspondiente dirección, y posteriormente se inicia la unidad Timer0 en el modo PWM con corrección de fase. Luego, en el ciclo de polling se evalúa constantemente si se ha presionado alguno de los botones, y cuando esto es cierto, se procede a incrementar el nivel del PWM, se visualiza a través de la barra de LEDs y se actualiza el registro OCR0, con el cual se controla el ancho de pulso generado. Finalmente se introduce un ciclo de espera, en el cual se detiene el ciclo principal hasta que se suelte el botón que ha sido presionado. A continuación se muestra el diagrama esquemático para esta aplicación:


Link recomendado: http://www.administracionsatelital.com/

miércoles, 27 de abril de 2011

Desarrollo de aplicaciones con interfaz gráfica

Quienes desarrollan hardware en algún momento se han encontrado con la necesidad de implementar una aplicación para el computador, la cual muchas veces debe incluir una interfaz gráfica. Este tipo de aplicaciones a menudo requiere ingreso de datos por parte del usuario, visualización de reportes, e incluso manejo de bases de datos y conectividad a Internet. A parte de lo anterior, se hace necesaria la interacción con dispositivos externos y sistemas desarrollados con microcontroladores y software embebido. La interacción con estos dispositivos de hardware se realiza a través de puertos USB, RS-232, Ethernet, e incluso dispositivos inalámbricos como Bluetooth o WiFi.

El lenguaje de programación Python es un lenguaje muy sencillo y potente que permite la implementación de programas y sistemas complejos en poco tiempo de desarrollo, con lo cual se desarrollan productos complejos que puedan satisfacer las necesidades del cliente. La principal desventaja de Python es la dificultad para la creación de interfaces gráficas y desarrollo de aplicativos finales para el usuario.

El framework de desarrollo Web Django es una excelente herramienta que permite integrar programación en Python, manejo de puertos e interacción con hardware, uso de bases de datos, y desarrollo de una interfaz gráfica de usuario. Todo esto se implementa en un entorno Web, por lo cual el diseño gráfico de la interfaz es sencillo, y se reduce al diseño de plantillas HTML.


Una aplicación en Django tiene la forma de un sitio Web, con la ventaja que se puede manipular fácilmente el hardware del computador usando código Python. Mientras se encuentra en etapa de desarrollo, es posible usar un servidor incluido con el framework Django, sin embargo, en el momento de implementar la aplicación de producción, se recomienda el uso de un servidor Web robusto. Se pueden instalar módulos adicionales al servidor Apache para que tenga la capacidad de ejecutar aplicaciones desarrolladas en Django.

En cuanto a bases de datos, Django permite una fácil integración con sqlite, mysql y posgresql, y además incluye un sitio administrativo muy completo en donde es posible visualizar y editar registros de la base de datos.

El link del sitio es http://www.djangoproject.com/, y recomiendo hacer el tutorial básico de 4 pasos, en el cual se ilustran las principales características y funcionalidades de Django. La instalación en Linux es sencilla, y todos los paquetes adicionales necesarios se pueden bajar usando los repositorios y el gestor de paquetes.

martes, 9 de noviembre de 2010

Estructura general de un programa en C para sistemas embebidos

En un programa para computador común, éste puede iniciar, realizar su tarea en la función main() y cuando termina la tarea se sale de la función y retorna al sistema operativo. En los programas diseñados para microcontroladores generalmente no hay un sistema operativo al cual retornar cuando se ejecuta la función main(), y por tanto, el programa se debe diseñar para estar siempre dentro de esta función (exceptuando cuando se usa un sistema operativo en tiempo real, en donde cambia la filosofía de programación). Así, es posible el uso de ciclos que aseguren la ejecución continua del programa; interrupciones que manejen el flujo de acuerdo a la sincronización de timers o eventos externos; o sistemas más complejos que manejen sistemas operativos en tiempo real (RTOS).

Por otra parte, se debe tener en cuenta el tiempo de reacción del sistema, es decir, el tiempo que tarda en dar una salida correspondiente a una entrada determinada. Dependiendo de la aplicación, este tiempo puede ser crítico, sobre todo en sistemas que realizan varias tareas que tienen prioridades diferentes. De esta forma, de acuerdo a las necesidades de la aplicación, es posible implementar programas usando diferentes estructuras de ejecución.

Polling

Esta es la opción más simple, y se usa para implementar aplicaciones sencillas con recursos limitados de timers y puertos de interrupción. En esta aproximación, se implementa un ciclo en en cual se leen las entradas, se ejecutan los procesos correspondientes a las entradas, y finalmente se generan las salidas.

Programa en polling
La principal desventaja de esta estructura de ejecución radica en que no se tiene un control preciso de la sincronización de eventos, es decir, es difícil controlar el período en el cual se repite el ciclo principal. Para solucionar este problema, es posible insertar una instrucción de retraso que detiene la ejecución por un tiempo fijo, luego de este tiempo, procede a ejecutar el ciclo siguiente.

Otro inconveniente que se tiene al trabajar usando polling es que todos los procesos se ejecutan estrictamente de forma secuencial, y no es posible asignar prioridades. Esto es necesario si se tienen procesos que se deben ejecutar de forma urgente cada cierto tiempo o luego de una entrada determinada; y al mismo tiempo se tienen procesos que se ejecutan de una forma más lenta. Cuando se tiene una situación de este tipo en un programa estructurado para realizar polling, los procesos más lentos retrasarán la ejecución de los que se deben ejecutar de una forma más urgente, provocando un tiempo de reacción que puede ser inaceptable para la aplicación.

Interrupciones

Mediante el uso de interrupciones es posible asignar prioridades de ejecución a determinadas tareas, lo cual es una gran ventaja en el momento de implementar programas que tienen operaciones lentas y de baja prioridad y también operaciones que se deben ejecutar de forma prioritaria sobre las otras, independientemente si estas últimas ya terminaron o no.

Programa con estructura de interrupciones
Como se puede observar en la Figura anterior, se tiene un ciclo principal de fondo, el cual puede correr libremente sin realizar acciones, o puede realizar las acciones de baja prioridad en las que no se requiere un control estricto de ejecución. Las rutinas prioritarias, por su parte, se implementan en una o varias funciones de servicio de interrupción, que pueden ser llamadas por un evento externo, como el cambio de estado en un puerto; o por un evento interno, como el desbordamiento de un contador o timer.

El esquema basado en interrupciones es útil cuando se tienen sistemas de mediana complejidad. Es muy importante tener en cuenta que el intervalo en el cual se llaman las rutinas de interrupción debe ser mayor al tiempo que tardan en ejecutarse los procesos de dichas rutinas, para así asegurar que las funciones críticas se ejecuten correctamente a la frecuencia de deseada. De lo contrario, el sistema puede saltar de interrupción en interrupción evitando que se ejecuten las otras tareas.

RTOS - Real Time Operating System

En sistemas grandes y complejos en tiempo real, con muchas tareas que se deben ejecutar de forma concurrente, se hace necesario el uso de un sistema operativo en tiempo real (RTOS). Mediante el RTOS se implementa un planificador de tareas, basado en prioridad, para la ejecución de procesos múltiples.

El uso de RTOS hace que el diseño de software de microcontroladores para sistemas complejos sea una tarea mucho más sencilla. El modelo de RTOS se muestra en la Figura siguiente. Las conexiones entre las tareas representan señales de sincronización, intercambio de datos o notificaciones de agotamiento de tiempo de espera.

Programa con sistema operativo en tiempo real
Un RTOS es un programa de fondo que controla y organiza la ejecución y comunicación de tareas que se deben ejecutar de forma paralela, programa el uso compartido de recursos, y distribuye las prioridades de las tareas. Existe un gran numero de RTOS comerciales, y hoy en día su uso es extendido en aplicaciones embebidas de alta complejidad.