GTZ – Curso de Electrónica – 4 Tomos Completos

agosto 14, 2009 en 11:30 pm | Publicado en Electrónica | 1 comentario
.fullpost{display:inline;}

Bueno, No tengo palabras para describir ese fabuloso libro, 4000 paginas, 4 tomos, cada tomo dividido en Teoria, Ejercicios y Hojas de trabajo.
Para Asignaturas: Digitales I, Digitales II, Taller de Electrónica Basica, Taller de Electrónica Intermedia, Ingenieria Basica y Otros más.


Link: MediaFire 96 Megas

Este Libro es completo solo me queda decirles que lo descarguen, es una biblio de la Electrónica, al termino de este curso Tecnico Electronico estaras en la capacidad de interpretar manuales de Reparacion, Diseño Intermedio.

ESPAÑOL(CISCO)CCNA-1-2-3-4 Semestres 3.1 CD

mayo 27, 2009 en 1:43 am | Publicado en Electrónica, Programación, Redes | Deja un comentario
Formato: Html/swf | 4 Semestres | RAR Compresion

Curso de redes por excelencia, elaborado por cisco, al finalizar el curso el alumno será capaz de supervisar la administración y las políticas de seguridad de los sistemas y redes, mediante la implantación y gestión de medidas de seguridad ante posibles ataques o usos inapropiados de los usuarios, evaluando riesgos y garantizando la confidencialidad y la integridad de las transacciones electrónicas.

Seminario 1:
MU

Seminario 2:
MU

Seminario 3:
MU

Seminario 4:
MU

Librería para Display de Nokia 3310 con C30 y dsPIC

mayo 21, 2009 en 11:23 pm | Publicado en Electrónica, Microcontroladores | Deja un comentario

Los displays gráficos de los teléfonos Nokia 3310 se caracterizan por tener una magnífica relación calidad / precio, ya que por un módico precio puedes disfrutar de una resolución de 84 x 48 pixels, con controlador integrado, y con un contraste y velocidad de respuesta bastante aceptables. Además, para usarlos sólo son necesarios 5 pines del microcontrolador, incluso menos que los LCD tradicionales de modo texto.

En vista de todas estas virtudes, y utilizando como base la librería escrita por mi amigo Cucaracha para manejar un display de Nokia 3310 con PIC, me dispuse a escribir una librería para dsPIC en C30. Y una vez puestos, he implementado diversas funciones que la completan y facilitan bastante la realización de todo tipo de gráficos.

Nokia Intro

CONEXIONES

Recomiendo visitar la web de Cucaracha ( http://webs.ono.com/usr008/cucaracha/ ) y descargar el zócalo que él diseñó para conectar el display cómodamente, sin necesidad de soldar sobre sus pequeñas pistas.

En cualquier caso, las patillas de conexión del display con el micro son:

  • sclk
  • sda
  • dc
  • cs
  • res

Las otras tres son de alimentación:

  • Vdd a 5V
  • Vss a GND
  • Vo con un condensador de 10uF a GND

FUNCIONES

Función de inicialización

void lcd_init(void)

Esta función debe ser llamada en el main() de tu programa, en la fase de arranque, para que configure los parámetros básicos del Display.

Funciones internas

int write(int handle, void *buffer, unsigned int len)
void nokia_envia_bits(char byte_dato)
void nokia_envia_dato(char byte_dato)
void nokia_envia_comando(char byte_comando)
float arcocoseno (perimetro,radio)

Estas cinco funciones son necesarias para el funcionamiento interno de la librería y no son útiles para el usuario.

Funciones de escritura directa en Pantalla<

void nokia_imprime_caracter(int *caracter)
void nokia_gotoxy(char xnokia, char ynokia)
void nokia_borra_pantalla(void)

Este grupo de funciones permite escribir directamente sobre la pantalla, sin usar ningún buffer intermedio. Para ello, pondremos el cursor en la posición donde queremos escribir (nokia_gotoxy) y luego enviamos la cadena de caracteres (nokia_imprime_caracter). También podemos borrar la pantalla (nokia_borra_pantalla).

Funciones de escritura a través de memoria de video

void nokia_borra_memoria(void)
void nokia_imprime_memoria(void)
void nokia_punto (char x, char y, char color)
void nokia_linea (char x1, char y1, char x2, char y2, char color)
void nokia_rectangulo (char x1, char y1, char x2, char y2, char estilo, char color)
void nokia_circulo (char x, char y, char radio, char estilo, char color)
void nokia_bitmap (char x, char y, const char *bitmap, char ancho, char alto)
void nokia_texto(char x, char y, char fuente, char *caracter)

Este grupo de funciones permite realizar distintas actividades gráficas sobre una memoria de video, que posteriormente puede ser volcada al display de una tacada.

Para la gestión de dicha memoria de vídeo se utilizan las funciones nokia_borra_memoria() y nokia_imprime_memoria(). Cabe destacar que la segunda no vacía la memoria, por lo que si seguimos dibujando, en la siguiente impresión que se haga seguirá estando lo que había; es como si se dibuja encima.

El resto de funciones no tiene mucha historia:

  • nokia_punto: dibuja un punto en las coordenadas x,y de color NEGRO o BLANCO. Nokia puntos

  • nokia_linea: dibuja una línea desde x1,y1 hasta x2,y2 de color NEGRO o BLANCO. Nokia líneas

  • nokia_rectangulo: dibuja un rectángulo desde el vértice x1,y1 hasta el vértice x2,y2 de color NEGRO o BLANCO. Si el estilo es TRANSPARENTE sólo se dibujará el perímetro; si es OPACO se dibujará completamente.
    Nokia cuadros

  • nokia_circulo: dibuja un círculo con centro en x,y con un radio determinado, de color BLANCO o NEGRO, y con estilo TRANSPARENTE u OPACO.
    Nokia círculos

  • nokia_bitmap: dibuja el bitmap que se envíe en un string en las coordenadas x e y. Hay que indicar el ancho y el alto. Los bytes que formen el bitmap tienen que estár orientados en vertical y barriendo de izquierda a derecha.
    Nokia bitmaps

  • nokia_texto: escribe la frase que se envíe en las coordenadas x,y usando la fuente NORMAL , NEGRITA o COMPRIMIDA.
    Nokia fuentes

Os dejo aquí un video del resultado, y en el área de Descargas encontraréis la librería junto con un programa de pruebas:

<!– var jsval = '’; writethis(jsval);//–>

AMPLIACIÓN: controlando LCD NOKIA 1100 con PIC 16F

LCD Nokia 1100

El amigo Alberto Casatti me ha pasado su librería para controlar un display de Nokia 1100 con un PIC 16F en MikroC.

Tanto la librería como el esquema están disponibles en el área de Descargas, aquí: Librería para Display Nokia 1100 con MikroC para 16F

Doy las gracias a Alberto y espero que la disfrutéis.

Curso de soldadura electrónica

mayo 16, 2009 en 11:48 pm | Publicado en Electrónica, Tec.Electronica PCB | Deja un comentario

Soldadura con estaño es la base de todas las aplicaiones electrónicas porque permite la realización de conexiones entre conductores y entre éstos y los diversos componentes, obteniendo rápidamente la máxima seguridad de contacto. Consiste en unir las partes a soldar de manera que se toquen y cubrirlas con una gota de estaño fundido que, una vez enfriada, constituirá una verdadera unión, sobre todo desde el punto de vista electrónico. Ésta es una tarea manual delicada que sólo se consigue dominar con la práctica. Recuerda que tu habilidad para soldar con efectividad determinará directamente el buen funcionamiento del montaje a lo largo del tiempo. Una soldadura mal hecha puede causar que el producto falle en algún momento. Esto es como aprender a andar en bicicleta, una vez que se domina ya nuca se olvida.

DOWNLOADCurso de soldadura electrónica

Microcontralodores PIC

mayo 16, 2009 en 11:14 pm | Publicado en Electrónica, Microcontroladores | Deja un comentario

Los microcontroladores estan conquistando el mundo. Están presentes en nuestro trabajo, en nuestra casa y en nuestra vida, en general. Se pueden encontrar controlando el funcionamiento de los ratones y teclados de los computadores, en los teléfonos y en los hornos microondas y los televisores de nuestro hogar. El objetivo primordial que nos ha motivado al escribir este libro es facilitar el camino al lector para que se entusiasme y utilice los microcontroladores. Desde el primer tema le proponemos programas para confeccionar y simularm, y desde el segundo, proeyectos con perifericos.
Características de la descarga:

Tipo: E-BookS
Formato: Pdf
Compresión: Winrar
Hospeda: RapidShare
Peso: 92.35 Mb
Idioma: Español

Descarga:Libro de Microcontralodores PIC

Robot que dibuja retratos

mayo 15, 2009 en 9:12 pm | Publicado en Electrónica | Deja un comentario

Básicamente, lo que hace el robot creado por Sylvain es registrar la imagen del rostro de la persona que tiene enfrente y separarla del fondo. Esto implica el uso de algoritmos de reconocimiento de patrones y ajustes para compensar las diferencias de iluminación o en la posición del modelo. Luego, el software del robot transforma la fotografía en una imagen vectorial. Este paso no es demasiado novedoso, y prácticamente cualquier software de ilustración dispone de opciones similares.Una vez que el robot tiene lista la imagen del modelo, procede a dibujarla. En lugar de utilizar una impresora para esta etapa del proceso, Sylvain ha dotado a su robot de una mano con la que, gracias a sus cuatro grados de libertad, puede coger una pluma y dibujar directamente la imagen sobre un papel, tal como lo haría un plotter.El siguiente video muestra al robot en acción.

checkFull(“post-” + “4181663777740066522”);

Cómo hacer un mini-robot con un cepillo de dientes

mayo 15, 2009 en 9:11 pm | Publicado en Electrónica | Deja un comentario

#fullpost{display:none;} Este video-tutorial (en ingles) muestra como hacer un mini-robot con un cepillo de dientes:

– con la cabeza de un cepillo de dientes
– cinta adhesiva
– un pequeño motor que vibra
– y una pila pequeña de reloj.

¿Cómo funciona? Un pequeño robot muy inquieto e imparable (mientras dure la pila), con movimiento aleatorio y además te limpia cualquier superficie plana

Wireless Watch 2.0.1.0

mayo 15, 2009 en 9:06 pm | Publicado en Electrónica, Redes | Deja un comentario
#fullpost{display:none;}

Ahora puedes descubrir quien esta dentro de tu red Wi-Fi. Con Wireless Watch podras descubrir quien te “roba” conexion a Internet. Wireless Watch hara constantes barridos de frecuencia wireless y te dara la voz de alarma cuando detecte intrusos. ¿Tienes Wi-Fi…? Si es asi­, conecta tu alarma¡¡.

DESCARGAR AHORA

Witricity, electricidad sin cables

mayo 15, 2009 en 9:03 pm | Publicado en Electrónica, Redes | Deja un comentario
#fullpost{display:none;}

Un equipo de investigación del MIT (Instituto de Tecnología de Massachusetts) ha conseguido encender una bombilla de 60W sin utilizar ningún cable para llevar la electricidad a esta, lo han llamado Witricity.
La idea surgió hace tiempo, como suele ocurrir en estas cosas, de una manera bastante corriente, un miembro del equipo del MIT estaba harto de que su móvil le avisará cada vez que tenía la batería baja, a todos se nos olvida cargar el móvil, de esa manera surgió la idea, se pusieron a pensar en como podían hacer que la electricidad viajara sin necesidad de cables y lo han conseguido, aunque no son los primeros.
Para conseguir que la electricidad viaje sin cables utilizan dos resonadores, que usan la misma frecuencia de resonancia. Uno de ellos es el emisor, que está conectado a la electricidad, enviando mediante ondas magnéticas la energía hacia el receptor. Las radiaciones magnéticas no son nocivas, por lo que es una manera segura de hacerlo. El receptor convierte esas ondas en electricidad y la envía a lo que tenga conectado. Es mucho más complejo que esto, pero no soy físico, si alguien lo puede explicar mejor que no dude en dejar un comentario.
En el CES 2007 ya se presentó algo similar, el eCoupled, los dos son bastante similares en cuanto a pérdidas de energía, así que lo interesante es ver quien lo comercializa primero y cuanto nos va a costar a nosotros.
El cuando es una de las dudas, pero ¿Quién será el emisor de energía sin cables? Podemos tener centrales eléctricas con grandes emisores y un receptor en cada casa, ¿sería esto viable? Podemos comprobar en casa que el envío de señales sin cables puede verse afectado por la climatología, un ejemplo es el TDT, a veces, cuando hay mal tiempo la señal es débil, al menos en las zonas alejadas de las grandes ciudades.

Monodevelop 2.0

mayo 15, 2009 en 8:50 pm | Publicado en Clases 2009-I, Electrónica, Programación | Deja un comentario
#fullpost{display:none;}

Monodevelop es un entorno de desarrollo principalmente diseñado para desarrollar aplicaciones con C# y algunos lenguajes como Visual Basic .NET, C/C++, Java, Vala y Boo. También permite desarrollar rápidamente aplicaciones ASP.NET sobre Linux , de esta manera es sencillo portar aplicaciones .NET creadas con Visual Studio a Linux y mantener el mismo código base entra ambas plataformas.

Características en esta nueva versión 2.0

  • Edición de texto avanzado. soporta autocompletado de sintaxis para C# 3 , plantillas de código..etc.
  • Entorno configurable. puedes cambiar a tu gusto: posicionamiento de ventanas, mapeo de teclas definidas por usuario, herramientas externas.
  • Soporte de Múltiples Lenguajes. C#, Visual Basic.NET, C/C++, Vala..etc
  • Depurador Integrado. para depurar aplicaciones .NET y aplicaciones nativas.
  • Diseñador Visual para GTK# ( algo parecido a los formularios Windows Forms)
  • ASP.NET. Puedes crear proyectos web y probarlos con XSP, el web server de Mono.
  • Más Herramientas. control de código fuente, integración de Makefiles, pruebas unitarias, deployment y empaquetado de aplicaciones.

Puedes leer todas las nuevas funciones que Monodevelop 2.0 tiene para que desarrolles aplicaciones en .NET desde Linux. haz clic en la siguiente liga: http://monodevelop.com/Download/MonoDevelop_2.0_Released.

Descarga de Monodevelop visita la siguiente pagina: http://monodevelop.com/Download

Existen paquetes para OpenSuse, Ubuntu, Debian y Mac OS X 10.4, de igual manera puedes entrar al svn del proyecto y descargar el código fuente de la versión al día de hoy , para Windows aún no hay versión disponible por el momento.

mayo 15, 2009 en 8:42 pm | Publicado en Desarrollo, Electrónica, Mision Sucre | Deja un comentario

AUTOMATION STUDIO 3.05


DESCARGAR AHORA

Internet y Redes Inalambricas

mayo 15, 2009 en 8:15 pm | Publicado en Electrónica, Redes | Deja un comentario


Un libro muy didactico que te enseña pasa a paso todo lo que debes saber sobre redes inalambricas, en este libro podras aprender de forma fácil que es un AP, tarjetas wifi, router asi como su configuración y los diferentes tipos de antenas para poder recepcionar internet inalambrico en tu PC, hacer radio enlaces, conexiones punto a punto, AP cliente, repetidor y ademas del empleo de diferentes programas como el Radiomobile para ayudarnos en nuestros enlaces de wifi y mas.

Tamaño: 26Mb Aprox
Tipo: PDF
180 Paginas

Link:Descargar

Emulador de un Casio F91W basado en FreeRTOS (2 de 2)

mayo 15, 2009 en 3:46 pm | Publicado en ATMega y AVR, Electrónica, Microcontroladores | Deja un comentario

Aunque el gadget pretende ser un emulador fiel al reloj Casio, este se encuentra en modo “desarrollo” y se ha añadido una pequeña funcionalidad de ayuda a la depuración.
Como el Casio original, este gadget tiene 6 teclas distintas A,B,C cortos y A,B,C largos. Si estando en un menú, introducimos una tecla que no hace nada, se muestra una pantalla de información con todas las funciones asociadas a cada una de las teclas.

Las funciones de hora, alarma y cronómetro basan su precisión en el periférico Real Time Clock Calendar (RTCC) que incorpora el microcontrolador. El cronómetro tiene opciones de Start, Stop y Split, pero estas solo tienen precisión de 1 segundo(el Casio tiene una precisión de 0.01 segundos).

Los métodos mostrados a continuación permiten al usuario realizar las operaciones de cronómetro definidas en documento USER’S GUIDE 2428 de Casio:


void Inicio( Watch *this );
void Parada( Watch *this );
void Fraccion( Watch *this );
void Libera( Watch *this );
void Borrado( Watch *this );
void ClearSplit( Watch *this );
void StartStop( Watch *this );
/* 
Función Medición de tiempo transcurrido.
Tecla C C C C A
Acción Inicio Parada Reinicio Parada Borrado
Función  Medición de tiempo fraccionado.
Tecla C A A C A
Acción Inicio Fracción Libera Parada Borrado
Función Tiempos fraccionados y/o tiempos del primero y del segundo en llegar.
Tecla C A C A A
Acción Inicio Fracción Parada Libera Borrado
*/

La tarea TaskGetLeds.

Responsabilidades:
Debe informar al sistema cunado el usuario pulse una tecla, indicando la tecla pulsada.
Estructura de la tarea:
Está dividida en dos funciones, vStartTaskGetLeds y vTaskLeds. La primera crea los recursos usados. La segunda comprueba continuamente las teclas e informa y envía un mensaje.
Funcionamiento:
Lo primero que hace esta tarea es intentar obtener un mutex. Esta tarea comparte los 24 LEDs con TaskPutLeds y por eso ambas deben estar sincronizadas. Cuando obtiene el mutex llama a la función get_leds y ésta devuelve un valor con el siguiente significado:
-1: No hay ninguna tecla pulsada.
0: La tecla A está pulsada.
1: La tecla B está pulsada.
2: La tecla C está pulsada.
Si no hay ninguna tecla pulsada se libera el mutex y vuelve al principio.
Si hay una tecla pulsada se espera hasta que se suelte y se envía en un mensaje uno de estos códigos:
0: La tecla A esta pulsada menos de 1.5 segundos.
1: La tecla B esta pulsada menos de 1.5 segundos.
2: La tecla C esta pulsada menos de 1.5 segundos.
3: La tecla A esta pulsada más de 1.5 segundos.
4: La tecla B esta pulsada más de 1.5 segundos.
5: La tecla C esta pulsada más de 1.5 segundos.

La librería LEDs.c
Incorpora funciones para el control de los LEDs. Permite controlar individualmente el estado de cada LED y su polaridad.

unsigned long long order_LEDS( unsigned long value );
void put_ordered_LEDS( unsigned long long out );
void put_LEDS( unsigned long value );
void set_COLS_DIR( unsigned char COLS );
void set_LEDS_DIR( unsigned long value );
unsigned long get_LEDS( void );

La función get_LEDS necesita que los LEDS puedan ser polarizados en inversa, para esto el PCB incorpora dos mosfet que pueden dar una salida de GND o VCC.
Los LEDS están divididos en 2 grupos, pares e impares. Mientras unos se polarizan como receptores los otros pueden estar como emisores y medir asi la luz reflejada.

PIN SWAP para un ruteado más sencillo en Altium Designer.
Esta es una de las opciones que me han permitido reducir notablemente el tiempo de ruteado y el número de vias de la placa. Se trata de indicar al programa que pines tienen funciones intercambiables y él mismo los intercambia para que el número de cruces sea mínimo.

Aquí se puede ver el antes y el después:

Reordenar antes de mostrar.
Puesto que no hay ningún orden entre los LEDs y los pins que ocupan, es necesario reordenar todos los datos que quieran ser mostrados. La función ordenar debe ser optima ya que es llamada muchas veces durante el funcionamiento del programa. Una primera implementación en C es suficientemente rápida y portable, pero decidí implementar una segunda versión en ensamblador para mejorar la eficiencia.

Solución en C


La tarea TaskGraphics


Generar el tono

Responsabilidades:
Debe dibujar en un buffer todas las primitivas. Cuando recibe el mensaje Qglcd_update envía el buffer a la tarea TaskPulLeds.
Recursos:
Dispone de un queue de entrada llamado xQueuePrimitive para recibir las primitivas que debe dibujar y otro queue llamado xQueueDisp para enviar el buffer con toda la imagen.
Estructura de la tarea:
Está dividida en dos funciones, vStartTaskGraphics y vTaskGraphics. La primera crea los recursos y la segunda dibuja y envía el buffer.
Funcionamiento:
No tiene ningún misterio, cada vez que recibe un mensaje con una primitiva llama a la función correspondiente de la librería Graphics.c

code

La librería Graphics.c
Es la librería que proporciona el compilador CCS para dibujar primitivas 2D básicas como líneas, píxeles, círculos…
Tiene algunas modificaciones:
La función glcd_init acepta un puntero a un array tipo unsigned long, todas las primitivas serán dibujadas en este array.
La función glcd_pixel utiliza una tabla (rotate table) para pintar los píxeles en el buffer.
La función glcd_textArial pinta texto en formato Arial. Las fuentes de este texto han sido generadas con el programa BitFontCreator Pro.

Doble buffer compartido con la tarea TaskPutLeds
La tarea TaskGraphics declara dos buffers del mismo tamaño que la pantalla, para poder representar la información antigua mientras se genera la nueva.
Cuando se recibe el mensaje Qglcd_update, se envía a la tarea TaskPutLeds el buffer pintado y se empieza a dibujar sobre el otro buffer.
Puesto que los buffers son grandes, no se hace copia en el mensaje, solo se envía un puntero. Esto es algo con lo que hay que tener cuidado, y en este caso el tamaño del queue (solo admite 1 mensaje) impide que se produzcan errores.

Paso de punteros en los mensajes
Cuando se pasa un puntero en un mensaje se debe estar seguro que el dato al que apunta “exista” cuando el mensaje es recibido.
En la tarea TaskWatch las funciones Qglcd_text5x7 y Qglcd_Arial pasaban un puntero a la cadena que debía ser dibujada y de vez en cuando se dibujaban caracteres sin sentido… Cuando se trabaja con concurrencia hay que tener en cuenta que todas las tareas se ejecutan en “paralelo” y que mientras una esta leyendo un dato la otra lo puede borrar. Esto se solucionó copiando toda la cadena (hasta 5 caracteres mas el carácter nulo) en el mensaje enviado.

La tarea TaskSpeaker

Responsabilidades:
Debe generar un sonido utilizando el piezo-altavoz cada vez que reciba un mensaje.
Tipo:
Tarea consumidora.
Estructura de la tarea:
Está dividida en dos funciones, vStartTaskSpeaker y vTaskSpeaker. La primera crea los recursos y la segunda recibe el mensaje y generará el sonido.
Funcionamiento:
Esta tarea esta inactiva mientras no se reciba ningún mensaje. Una vez recibido un mensaje lo primero que hace esta tarea es intentar obtener un mutex. Esta tarea comparte un pinIO con la tarea TaskButton y ambas deben estar sincronizadas.
Cuando se obtiene el mutex se configura el pinIO como salida y se genera el sonido indicado en el mensaje.

TASKSPEAKER_C

El mensaje recibido posee 3 datos:
Aunque la función que se muestra arriba funciona, aún esta en desarrollo. Aquí voy a describir su funcionamiento final:
long pattern: Es la secuencia de sonidos que se va a generar.
Por ejemplo SOS podría ser algo como 0b00000010101001110111011100101010.
int pitch: Es el tiempo que dura cada “bit” de la secuencia.
int reps: Es el número de veces que se repite la secuencia.

Tomar el control del sistema
Como el piezo-altavoz fue un periférico añadido al sistema mucho tiempo después del diseño del PCB, este no cuenta con el pin mas adecuado para generar audio ( como PWM). El tono es generado con muchas instrucciones PORTAbits.x = ! PORTAbits.x y eso requiere que el procesador este en la tarea TaskSpeaker durante un tiempo relativamente largo sin poder atender otras tareas.
Como el RTOS esta configurado en modo preemtitive se deben evitar los cambios de contexto al menos durante un “bit” de la secuencia. Esto se consigue dando a la tarea TaskSpeaker la prioridad más alta.
Una opción anterior fue utilizar las funciones taskENTER_CRITICAL y taskEXIT_CRITICAL pero no resultaron muy adecuadas puesto que modificaban indirectamente el comportamiento de la función vTaskDelayUntil.

La tarea TaskPutLeds

Responsabilidades:
Debe imprimir una imagen de 128×24 sincronizada con el movimiento de la mano.
Tipo:
Es una tarea consumidora.
Estructura de la tarea:
Está dividida en dos funciones, vStartTaskSpeaker y vTaskSpeaker. La primera crea los recursos y la segunda recibe la imagen en un mensaje y la imprime cuando se lo indica la tarea TaskAcce.

Funcionamiento:
Puesto que los LEDs son un recurso compartido controlado por mutex, lo primero que hace antes de mostrar nada es intentar obtener el mutex.
Una vez tiene el mutex configura los LEDs y espera, durante 256 ticks, un mensaje de la tarea TaskAcce para mostrar la imagen. Después de mostrar la imagen volverá a esperar el mensaje de la tarea TaskAcc. Cuando pasen mas de 256 ticks y no se reciba un mensaje liberara el mutex.

TASKPUTLEDS_C

Sincronización con el movimiento de la mano
La tarea TaskPutLeds recibe mensajes de la tarea TaskAcce indicando que la mano de el usuario esta a la izquierda o a la derecha del todo, pero esto no es suficiente para mantener estable la imagen en el aire.
Se calcula el instante en que se debe mostrar la imagen ( O[n] ) en base a los dos últimos instantes en que la mano se encontraba a la izq./drcha. del todo (I[n] e I[n-1] ). Conociendo estos dos datos y el “tamaño” de la imagen 128 se puede calcular O[n] de la siguiente manera:
O[n] = I[n] + ( I[n] – I[n-1] )/2 -128/2.
Donde I[n] – I[n-1] puede ser sido sustituido por DIFF(I[n])
Si por alguna razón el instante O[n] pertenece al pasado o a un futuro lejano se asigna un nuevo instante O[n] aproximado.

En esta imagen se muestra el movimiento y la imagen mostrada.

Uso de la CPU
Puesto que esta tarea es larga, y además tiene una prioridad alta, se ha diseñado para liberar a la CPU el máximo tiempo posible, permitiendo así a otras tareas tomar la CPU para realizar sus trabajos. El tiempo de CPU consumido por esta tarea es inferior al 5%.

En esta imagen se muestran los estados de la tarea TaskPutLeds

Impedir que el sistema se bloquee debido a queues llenos.
Un criterio de diseño escogido para la mayoría de las tareas productoras/procesadoras ha sido que si el queue de salida de la tarea esta lleno esta se bloquee.
Si la tarea PutLeds no consume mensajes durante mucho tiempo bloqueara indirectamente a la tarea anterior, y esta a la anterior… Para evitar esto periódicamente consume mensajes aunque no se utilicen.

La tarea WakeUp

Responsabilidades:
Debe despertar a todas las tareas cuando el usuario pulse el botón y volverlas a dormir si en 20 Segundos no se pulsa nada.
Tipo:
Es una tarea de control.
Estructura de la tarea:
Esta dividida en dos funciones, vStartTaskWakeUp y vTaskWakeUp. La primera crea los recursos y la segunda despierta o duerme al resto de tareas.
Funcionamiento:
Esta tarea espera continuamente un mensaje de la tarea TaskButton. Cuando lo recibe despierta a todas las tareas del sistema. Ahora comprueba la tarea TaskGetLeds para resetear un contador y la tarea TaskButton para borrarlo (lo pone a su valor máximo). Cuando el contador llega a su valor máximo suspende todas las tareas del sistema, excepto la tarea TaskButton.
Además, aunque en principio no es necesario, la tarea TaskWakeUp también apaga los LEDs, el mosfet y el acelerómetro.

Codigo de la tarea:

TASKWAKEUP_C

El orden para suspender y resumir tareas
Si se suspende una tarea consumidora antes que una productora se llenaran los queues de mensajes. Estos mensajes serán leídos cuando se vuelva a resumir la tarea consumidora y probablemente ya no tengan utilidad.
El orden que se ha escogido para resumir tareas es:
Consumidoras.
Procesadoras.
Productoras.
El orden para suspenderlas es el contrario. Esto evita que se llenen los queues mientras el sistema entero se suspende.
La tarea TaskWakeUp posee la prioridad más alta del sistema, y eso le permite tomar la CPU siempre que la necesite. Por este motivo todas las tareas serán resumidas al mismo tiempo, pero este orden puede ser útil a la hora de suspenderlas.

Suspender una tarea que posee un mutex
Si suspendemos una tarea que tiene un mutex, nunca lo liberará, y estaremos bloqueando indirectamente a otra tarea que se encuentre esperando ese mutex.
También es importante asegurar que un periférico no esta en uso cuando se bloquea a la tarea que lo controla.
Para evitar todo esto la tarea TaskWakeUp “conoce” los mutex que puede poseer cada tarea. Si una tarea posee un mutex, se espera a que lo suelte antes de suspenderla.

Modo bajo consumo
Cuando todas las tareas están suspendidas la tarea TaskWakeUp cambia el reloj del sistema a 32kHz, esto permite seguir funcionando al RTOS y a la tarea TaskButton pero con un consumo aproximado de 0.1 mA y da un tiempo de funcionamiento teórico de 1 año.
Cuando el usuario pulsa el botón, la tarea TaskWakeUp vuelve a cambiar el reloj del sistema a 8MIPs y resume todas las tareas.

“Interrupción” por RTCC
La tarea TaskWakeUp comprueba (pooling) continuamente el flag de interrupción por RTCC. Cuando la alarma esta activada es capaz de despertar al sistema y generar el sonido de alarma. Esta opción no esta terminada ya que aun no he podido programar la alarma del RTCC, pero de momento no tiene importancia.

La función Main

Responsabilidades:
Debe inicializar todos los periféricos de la CPU, configurar la aplicación y arrancar el RTOS
Variables
xTaskAcceResources xTaskAcce1;
xTaskPutLedsResources xTaskPutLeds1;
xTaskGetLedsResources xTaskGetLeds1;
xTaskButtonResources xTaskButton1;
xTaskSpeakerResources xTaskSpeaker1;
xTaskWakeUpResources xTaskWakeUp1;
xTaskGraphicsResources xTaskGraphics1;
xTaskWatchResources xTaskWatch1;

Funcionamiento:
Primero llama a la función VisualInitialization(). Esta función ha sigo generada totalmente con la herramienta VisualDeviceInitializar que incorpora el MPLAB.
Después llama a todas las funciones del tipo vStartTaskX y va copiando los recursos de unas

tareas a otras.
Finalmente arranca el RTOS llamando a la función vTaskStartScheduler.

Aplicación creada por la tarea main:

/* Standard includes. */
#include
#include
#include
#include
#include
/* Device description includes */
#include "P24FJ64GA004.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Application includes*/
#include ".\utils\Hardware.h"
#include ".\utils\LEDs.h"
#include ".\utils\GLCD.h"
//#include "Filters.h"
//#include "CORDIC.h"
#include ".\Tasks\TaskAcce.h"
#include ".\Tasks\TaskPutLeds.h"
#include ".\Tasks\TaskGetLeds.h"
#include ".\Tasks\TaskButton.h"
#include ".\Tasks\TaskSpeaker.h"
#include ".\Tasks\TaskWakeUp.h"
#include ".\Tasks\TaskWatch.h"
#include ".\Tasks\TaskGraphics.h"
#include ".\Generated Files\VDIInit\init_PIC24FJ64GA004.sinit_vi.h" 

/*-----------------------------------------------------------*/
// Create Tasks handlers, these must be placed as a GLOBAL varibles.
xTaskAcceResources xTaskAcce1;
xTaskPutLedsResources xTaskPutLeds1;
xTaskGetLedsResources xTaskGetLeds1;
xTaskButtonResources xTaskButton1;
xTaskSpeakerResources xTaskSpeaker1;
xTaskWakeUpResources xTaskWakeUp1;
xTaskGraphicsResources xTaskGraphics1;
xTaskWatchResources xTaskWatch1;
/* Create the demo tasks then start the scheduler.  */
int main( void ){

/* Configure any hardware required for this demo. */
VisualInitialization();
 /* Create the test tasks defined within this file. */

// Productor role tasks
xTaskAcce1.uxPriority = 5;
if( startAcceTask(&xTaskAcce1) ) return -1;
 xTaskGetLeds1.uxPriority = 1;
if( startGetLedsTask(&xTaskGetLeds1) ) return -1;
 xTaskButton1.uxPriority = 1;
if( startTaskButton( &xTaskButton1 ) ) return -1;

// Processor role tasks
xTaskWatch1.xQueueSound = xTaskGetLeds1.xQueueSound;
xTaskWatch1.xQueueKey = xTaskGetLeds1.xQueueKey;
xTaskWatch1.uxPriority = 2;
if( startTaskWatch( &xTaskWatch1 ) ) return -1;
 xTaskGraphics1.xQueuePrimitive = xTaskWatch1.xQueuePrimitive;
xTaskGraphics1.uxPriority = 3;
if( startTaskGraphics( &xTaskGraphics1 ) ) return -1;

// Consumer role tasks
xTaskSpeaker1.xMutexIO = xTaskButton1.xMutexIO;
xTaskSpeaker1.xQueueSound = xTaskWatch1.xQueueSound;
xTaskSpeaker1.uxPriority = 4;
xTaskSpeaker1.uxPriorityHigh = 7;
if( startTaskSpeaker( &xTaskSpeaker1 ) ) return -1;

xTaskPutLeds1.xMutexLeds = xTaskGetLeds1.xMutexLeds;
xTaskPutLeds1.xQueueMove = xTaskAcce1.xQueue;
xTaskPutLeds1.xQueueDisp = xTaskGraphics1.xQueueDisp;
xTaskPutLeds1.uxPriority = 6;
if( startPutLedsTask(&xTaskPutLeds1) ) return -1;

// Control tasks
xTaskWakeUp1.xHandleTasks[7] = xTaskGetLeds1.xHandle;
xTaskWakeUp1.xMutexes[7] = xTaskPutLeds1.xMutexLeds; // Productor Task
// Productor Task
xTaskWakeUp1.xHandleTasks[6] = xTaskAcce1.xHandle;
xTaskWakeUp1.xMutexes[6] = NULL;
xTaskWakeUp1.xHandleTasks[5] = NULL;
xTaskWakeUp1.xMutexes[5] = NULL;
// Processor Task
xTaskWakeUp1.xHandleTasks[4] = xTaskWatch1.xHandle;
xTaskWakeUp1.xMutexes[4] = NULL;
xTaskWakeUp1.xHandleTasks[3] = xTaskGraphics1.xHandle;
xTaskWakeUp1.xMutexes[3] = NULL;
xTaskWakeUp1.xHandleTasks[2] = NULL;
xTaskWakeUp1.xMutexes[2] = NULL;
xTaskWakeUp1.xHandleTasks[1] = xTaskSpeaker1.xHandle;
// Consumer Task
xTaskWakeUp1.xMutexes[1] = xTaskSpeaker1.xMutexIO;
xTaskWakeUp1.xHandleTasks[0] = xTaskPutLeds1.xHandle;
xTaskWakeUp1.xMutexes[0] = xTaskPutLeds1.xMutexLeds;

xTaskWakeUp1.xQueueButtonKey = xTaskButton1.xQueueKey;
xTaskWakeUp1.xQueueGetLedsKey = xTaskGetLeds1.xQueueKey;
xTaskWakeUp1.uxPriority = 8;
if( startTaskWakeUp( &xTaskWakeUp1 ) ) return -1;


/* Finally start the scheduler. */
vTaskStartScheduler();
 return 0;
}
/*
void _ISRauto _RTCCInterrupt(void)
{}
if( pdTRUE == xTaskResumeFromISR( xTaskWakeUp1.xHandle ) )
{
// We should switch context so the ISR returns to a different task.
// NOTE: How this is done depends on the port you are using. Check
// the documentation and examples for your port.
portYIELD_FROM_ISR();
}
}
*/

Crear, configurar e interconectar tareas
La estructura xTaskXXResources engloba los manejadores (punteros) de los recursos utilizados por la tarea TaskXX. Es inicializada al llamar a la función vStartTaskXX( & xTaskXXn ). Esta devuelve un 0 todo ha ido bien y un -1 si ha habido algún error.
Se puede observar como coincide el diagrama de la aplicación con las asignaciones que se van haciendo entre la inicialización de cada tarea.

La estructura xTaskXXResources esta definida en el archivo TaskXX.h de la siguiente manera:

typedef struct xTaskXXResources{
xTaskHandle xHandle; // Task handler.
unsigned portBASE_TYPE uxPriority; // Task priority.
xSemaphoreHandle xMutexXX; // Mutex handler.
xQueueHandle xQueueXX; // Queue handler.
}xTaskXXResources;

La tarea vStartTaskXX tiene la siguiente forma básica, definida en el archivo TaskXX.c:

int vStartTaskXX( xTaskXXResources *pxResources ){
if( pxResources->xMutexXX == NULL ){
if( NULL == ( pxResources->xMutexXX = xSemaphoreCreateMutex() ) )
return -1;
vQueueAddToRegistry( pxResources->xMutexXX, ( signed portCHAR * )"xMutexXXName" );
}

if( pxResources->xQueueXX == NULL ){
if( NULL == ( pxResources->xQueueXX = xQueueCreate( 5, sizeof( xMessageXX ) ) ) )
return -1;
vQueueAddToRegistry( pxResources->xQueueXX, ( signed portCHAR * )"xQueueXXName" );
}

if( pdPASS != xTaskCreate(vTaskXX,(signed portCHAR *)"TaskName",
configMINIMAL_STACK_SIZE,
pxResources, pxResources->uxPriority, &pxResources->xHandle ) )
return -1;

return 0;
}

Conclusiones
Este gadGet ha sido construido con herramientas caseras. El acabado final no es como el de un producto comercial, pero creo que el diseño, tanto software como hardware, si lo son.

El objetivo de este proyecto ha sido iniciarse en los RTOS y lo ha cumplido a la perfección. También se ha desarrollado una técnica de programación orientada a objetos útil para todos los que programamos en C y he improvisado un método práctico para la divulgación y especificación del funcionamiento global y detallado del sistema.

Según lo que he visto, un RTOS no proporciona una ventaja tan grande como lo es el paso de ASM a C, pero creo que se vuelve imprescindible a la hora de crear sistemas ROBUSTOS con más de 2500 líneas de código.
Para este proyecto se han escrito casi 50 archivos, y creo que no hay ninguno con más de 500 líneas. Esto refleja un buen enfoque en la división de los algoritmos según el principio “divide y vencerás”.También se ha seguido otro principio que ha permitido, de manera invisible, una mayor “módularidad” del código. Este ha sido el principio de “la regularidad favorece la simplicidad”.

La herramienta RTOSViewer del MPLAB ha sido de gran ayuda en la depuración del sistema. Ha permitido conocer en cada momento el estado del RTOS y sus recursos. Es casi imprescindible, sobre cuando uno esta empezando con los RTOS…

Una de las ideas que más me han gustado ha sido la de utilizar un conector ICSP compatible con el conector macho del tipo miniUSB.
Este conector es sencillo, muy asequible, ocupa poco espacio en placa (6mm x 6mm) y es atractivo para el usuario final.

Mejoras
Algoritmo de detección y sincronización: Aunque el algoritmo actual es sencillo y funciona bastante bien, es la mejora más útil que se le puede hacer a este proyecto. Creo que también podría añadirse algún tipo de corrección sobre el desplazamiento vertical.
RTOS: La aplicación ha sido implementada con recursos del FreeRTOS. Quizás se pueda simplificar o añadir nuevas funcionalidades con un RTOS mas completo.
DEPURACION DEL RTOS: El RTOS posee una serie de utilidades para seguir desde el exterior su funcionamiento. En proyectos posteriores intentaré sacarles partido.
LEDs: Por supuesto cuantos mas leds, mejor resolución vertical.
LEDs RGB: Seria una opción interesante añadir mas colores a la aplicación. La harían mucho más vistosa, aunque el PIC24 no tiene más pines para controlarlos.
PCB: El PCB esta en general bien, aunque, junto con las pilas es algo grande para utilizarlo de llavero.
PESO: La verdad, mover rápido dos pilas AAA durante un rato se hace incomodo. Todo el peso que se pueda eliminar al gadjet se ganara en comodidad de uso. Creo que se podría utilizar una sola pila y un elevador de voltaje.

Bugs
SCH y PCB
Los componentes MOSFET y ACELEROMETRO no tienen correctamente asignados los pines en el encapsulado. Esto se ha solucionado mediante apaños en la placa ya soldada.
SOFTWARE:
Si que existirán, pero aun no he encontrado ninguno que se merezca aparecer aquí.

Agradecimientos
Agradezco a toda la comunidad de todopic, y especialmente a Nocturno, septiembre_negro, aitopes, MLO__, vtasco, J1M, todopic, barral, RICHI777 y SavageChicken los buenos comentarios sobre el proyecto que sin duda me han motivado mucho para seguir creando gadgets en el futuro.

DESCARGA
Proyecto: ManualLedScanner, versión 2.45. José Antonio García Peiró. 2009.

Descarga del proyecto completo

Algunos documentos de consulta
Sistemas embebidos
Libro: Embedded Systems Firmware
RTOS
Libro: Real Time Concepts for Embedded Systems
Programación orientada a objetos en ANSI C
PDF: Implementing object-oriented designs in ANSI-standard C
PDF: Object-oriented programming with ANSI C

Links interesantes

Enlace a la guía de usuario del reloj de Casio. Aunque no es el F91W, es el modelo mas parecido del que conseguí la guía ya que no en contre justo la del F91W.
http://ftp.casio.co.jp/pub/world_manual/wat/en/qw2428.pdf
Enlace a una pagina que explica como usar un LED como sensor de Luz.
http://en.wikipedia.org/wiki/LED_as_light_sensor
Enlace a la página del RTOS utilizado
http://www.freertos.org/
Maquina de estados finitos:
http://en.wikipedia.org/wiki/Finite_state_machine#Software_applications
Led como sensor:
http://en.wikipedia.org/wiki/LEDs_as_Photodiode_Light_Sensors
BitFontCreator Pro:
http://www.iseasoft.com/bfc.htm
Librerías graficas, incluidas en el compilador CCS:
http://www.ccsinfo.com/
Computación concurrente:
http://es.wikipedia.org/wiki/Concurrente
Preemption:
http://en.wikipedia.org/wiki/Preemptive_multitasking

Software utilizado
MPLAB 8.30
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469∂=SW007002
MPLAB PIC24 Compiler 3.12
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en535364
Altium Winter 09
http://www.altium.com/products/altium-designer/en/altium-designer_home.cfm
Proteus 7
http://www.labcenter.co.uk/index.cfm

Emulador de un Casio F91W basado en FreeRTOS (1 de 2)

mayo 15, 2009 en 3:27 pm | Publicado en ATMega y AVR, Electrónica, Microcontroladores | Deja un comentario

Emulador de un reloj Casio F91W basado en un PIC24 de Microchip, por <!– var prefix = 'ma' + 'il' + 'to'; var path = 'hr' + 'ef' + '='; var addy10475 = 'jgpeiro' + '@'; addy10475 = addy10475 + 'gmail' + '.' + 'com'; var addy_text10475 = 'José Antonio García Peiró'; document.write( '‘ ); document.write( addy_text10475 ); document.write( ” ); //–>\n José Antonio García Casio F91WPeiró <!– document.write( '‘ ); //–> Esta dirección de correo electrónico está protegida contra los robots de spam, necesita tener Javascript activado para poder verla <!– document.write( '’ ); //–> .
El sistema pretende emular al modelo F91W, imitando las especificaciones y el funcionamiento del reloj de Casio.
El emulador dispone de 3 botones, un display y un altavoz que permiten al usuario interactuar de la misma manera que con el F91W, aunque con una interfaz totalmente distinta.Este gadget no tiene ni pantalla ni botones, para visualizar la hora se utiliza un mecanismo similar al de los relojes “propeller clock” o “giroplay” y para detectar las teclas pulsadas se utilizan LEDs como sensores.

El altavoz es piezo-eléctrico, igual que en el Casio.

El proyecto tiene unos 5 meses y la mayor parte del tiempo la he dedicado a escribir el software, con el objetivo de iniciarme con los RTOS. En proyectos anteriores me encontré con la dificultad de mantener y ampliar el código cuando el proyecto iba creciendo. Por ejemplo: Si queremos añadir una nueva funcionalidad al sistema será fácil si nuestro sistema aun es pequeño, pero será cada vez mas y mas difícil a medida que el sistema vaya creciendo. Esto no ocurre si diseñamos el sistema basado en un RTOS. En este caso, el sistema se divide en subsistemas y al RTOS se le indican las interconexiones entre ellos. Si queremos añadir una nueva funcionalidad será tan fácil como escribirla e indicar al RTOS su relación con las demás.

Algunas fotos

Circuito

Este es el aspecto del circuito montado. En la parte inferior se acopla un portapilas con dos pilas tipo AAA. Tambien se puede ver como el conector ICSP tiene un formato miniUSB.

Pulsando teclas

Esta imagen muestra como se usan los LEDs cuando se detecta una pulsación.

Funcionamiento

El sistema esta dividido en 8 tareas concurrentes comunicadas entre sí con colas “queues”. Cada tarea incluye objetos y librerías para efectuar su función. Las tareas que acceden a un mismo recurso poseen mecanismos de sincronización como mutex. Las tareas se pueden agrupar en cuatro grupos diferentes según su rol en el sistema: productoras, procesadoras, consumidoras y control. Cada grupo de taras posee prioridades distintas, teniendo la menor las productoras … y la mayor la de control.

Para utilizar el gadget el usuario debe agitar continuamente la mano para leer la información. El aparato tiene una columna de 24 LEDs y genera en el aire una imagen estable de 128*24 pixels. Incorpora un acelerómetro para sincronizar el movimiento de la mano con el barrido de la imagen y así mantenerla lo más estable posible en el aire.
Los mismos 24 LEDs se pueden poner en modo inverso y así ser usados como sensores. De este modo se emulan los 3 botones (A B y C) del Casio.

El sistema también posee un botón, un botón físico real, que no existe en el reloj Casio. Este botón permite “despertar” al reloj durante un tiempo para que el usuario interactúe con él. Además el botón comparte pin IO con el altavoz y, aunque sus funciones son totalmente incompatibles, el sistema sincroniza perfectamente el pin IO de tal manera que las dos funciones se ejecuten en “paralelo” y NUNCA se interfieran entre sí.

Después de un reset, la función main configura todas las 8 tareas y arranca el RTOS. En este punto solo hay dos tareas en funcionamiento: TaskButton y TaskWakeUp.
Cuando el usuario pulsa el botón, la tarea TaskButton envía un mensaje a la tarea TaskWakeUp y esta ultima despierta todas las demás tareas. Pasados 20 segundos, las vuelve a suspender.

Mientras todas las tareas están despiertas, el usuario puede interactuar con el reloj visualizando en pantalla la misma información que en el reloj original y navegando por los mismos menús.
Cuando pulsa una tecla la tarea GetLeds envía un mensaje a la tarea TaskWatch con la tecla pulsada.


La tarea TaskWatch le pasará a la función WatchProcces la tecla pulsada para actualizar el estado del reloj y después enviará a la tarea TaskGraphics todas las primitivas que componen la pantalla del reloj en el modo actual ( texto, líneas, símbolos…).

La tarea TaskGraphics pintará todas las primitivas en una matriz de 128*24 y cuando termine le pasará esta matriz a la tarea TaskPutLeds.

La tarea TaskPutLeds recibirá el mensaje y esperará a que la tarea TaskAcce le indique el momento exacto para mostrar el mensaje en el aire.

La tarea TaskAcce mide constantemente la aceleración y envía un mensaje a la tarea TaskPutLeds cuando la aceleración alcanza un máximo o un mínimo.

Las tareas TasButton y TaskSpeaker comparten un recurso (un pin IO del PIC), y para evitar que ambas accedan al recurso al mismo tiempo están sincronizadas mediante un mutex. Las tareas GetLeds y PutLeds también comparten recursos (los 24 LEDs y el Mosfet) y también están sincronizadas con un mutex.

Diagrama de la aplicación

Diagrama

Este grafico muestra un diagrama de bloques de la tarea TaskAcce y su equivalente en C. Los bloques Avg, Diff y AND, RSFF están modelados como objetos.

TaskAcce

El código

El código esta dividido en 3 partes principales:
El main. Este se encarga de definir la aplicación en si (tareas y su interconexión) y de arrancar el RTOS llamando a la función vTaskStartScheduler.
Las tareas. Hay 4 tipos de tareas según su rol:
-Productoras: Cogen datos del exterior del sistema como un pinIO o el ADC y envían un mensaje con el dato leído.
-Procesadoras: Reciben un mensaje, procesan la información y reenvían los resultados en otro mensaje.
-Consumidoras: Reciben un mensaje y lo mandan al exterior del sistema como a un LED o a algún periférico externo.
-Control: Supervisan el funcionamiento del sistema “escuchando” la información que se pasan las tareas.
Las utilidades. Aquí se agrupan todas las funciones de utilidad general necesarias para las tareas, como por ejemplo la clase Watch.c o las funciones graficas GLCD.c.

Voy a empezar describiendo la tarea TaskButton. Es una tarea de tipo productor, y realiza una función muy sencilla en el sistema: informar a quien lo necesite de que el usuario ha pulsado el botón.

Tiene 2 funciones vStartTaskButton() y vTaskButton(). La primera es llamada por el main y se encarga de indicar al RTOS los recursos que tiene esta tarea (un mutex llamado xMutexIO y un queue llamado xQueueKey). La segunda función es la que ejecutara el RTOS cuando este arranque.

TaskButton http://www.megaupload.com/?d=2LGV3LWR

Una vez arrancado el RTOS el PC empezara a correr por la función vTaskButton y esta realiza lo siguiente en el bucle infinito while(1):
Primero comprueba si el recurso compartido esta disponible para su uso, de lo contrario esperará un tiempo y vuelve a comprobar. Hay que recordar que el botón y el altavoz están conectados al mismo pin y que hay que asegurar que NUNCA se lea del botón mientras se escribe en el altavoz. Para esto las dos tareas implicadas, vTaskButton y vTaskSpeaker comparten un mutex y se mantienen sincronizadas.
Cuando la tarea vTaskButton “se adueña” del mutex sabe que la tarea vTaskSpeaker no podrá tocar el pin IO hasta que vuelva a “liberar” el mutex.
Ahora, en posesión del mutex, sí podemos configurar el pin como entrada, leer su valor desconfigurarlo y liberar el mutex para que otra tarea pueda usarlo.
Si el valor leído es de “botón pulsado” se comunica a otras tareas enviando un mensaje.

¿Sencillo?, yo creo que si. ¿Eficiente?, no mucho…¿Robusto? 100%.
Las funciones xSemaphoreTake, vTaskDelay, xSemaphoreGive… son las herramientas que proporciona el RTOS y se encuentran perfectamente documentadas en su página web (ver links recomendados al final del artículo).

Tarea TaskAcce.

Esta tarea tiene como objetivo sincronizar el mensaje de la tarea TaskPutLeds con el movimiento de la mano y ofrecer así una imagen lo mas estable posible.
Debe leer continuamente el acelerómetro (a través del ADC) e indicar al sistema dos eventos clave del movimiento de la mano: cuando la mano esta a la izq. del todo y cuando esta a la drcha. del todo.
Con esta información se puede calcular el momento en el que se debe refrescar la imagen para que se superponga con la anterior.

Lo primero de todo es definir la relación que existe entre el movimiento en zig-zag de la mano y la aceleración medida.

Movimiento zig-zag

En esta figura se muestran los eventos que queremos detectar. En t = 1.54 la mano está a la izquierda del todo, su velocidad es 0 y su aceleración es mínima. En t = 4.68 la mano está a la derecha del todo, su velocidad es 0 y su aceleración es máxima.


Puesto que solo se puede leer la aceleración, se debe calcular cuando está en su punto máximo o mínimo, y esto se cumple cuando su derivada (la velocidad) es 0.

Diagrama de bloques del algoritmo.

Diagrama de bloques del algoritmo

En el diagrama de bloques esto esta implementado con el Diff y el Avg, aunque este último hace un promedio con un buffer de 8 muestras.

A partir de aquí los bloques son similares tanto para detectar el máximo como para el mínimo, así que solo describiré el máximo.

Lo primero que hay que hacer es definir un margen ( TRIGER_LEVEL ) por debajo del cual consideraremos que la señal es 0, y otro margen (ARM_LEVEL) que nos dirá si la aceleración es máxima o mínima.
También hay que evitar que se envie más de un mensaje por evento, y para eso se ha introducido un biestable RS. Cuando se envía un mensaje (simbolizado con una banderita levantada) se resetea el biestable, y este no vuelve a ponerse a uno hasta que la velocidad es inferior a -ARM_LEVEL.

En esta imagen se muestra el uso de los márgenes y el biestable en la detección.
Margenes y biestable

Aquí se muestra el código de la aplicación. Tiene, como la tarea anterior, 2 funciones vStartTaskAcce y vTaskAcce.
La primera función es llamada por el main durante la configuración de aplicación (antes de arrancar el RTOS). Recibe como parámetro una estructura que contiene manejadores (handler) de todos los recursos de la tarea, devuelve un -1 si ha habido error al inicializar crear algún recurso o 0 si todo ha sido correcto. Es responsabilidad del main leer el valor devuelto y actuar en consecuencia (en este caso el main aborta el programa).

TaskAcce http://www.megaupload.com/?d=ULIEUWCO

La segunda es la que se encarga de detectar el máximo o mínimo con el algoritmo descrito antes y enviar un mensaje.

El código se podría haber implementado de muchas maneras, pero se ha intentado acercar a lo que seria la programación orientada a objetos(POO).

En lugar de utilizar una función que se llame diferencia, se han creado dos archivos: differenciator.c y differenciator.h
Differenciator.h- Contiene los atributos ( una estructura ) y la declaración de los métodos del objeto( declaraciones de las funciones).
Differenciator.c- Contiene las definiciones de los métodos del objeto.

Para utilizar un objeto tipo diferentiator podríamos utilizar un programa de este tipo:

 include 
#include "differentiator.h"
Main(){
Differentiator diff1;
DifferentiatorConstructor( &diff1 );
while(i++){
DifferentiatorProcces( &diff1, i );
printf(“%d”, diff1.out );
}
}

La tarea TaskWatch
Ésta es la tarea central del emulador. Se encarga de mantener el reloj y sus menús actualizados en pantalla.
Recibe la tecla pulsada de la tarea TaskGetLeds, actualiza el estado del reloj y envía una serie de primitivas que representan la pantalla a la tarea TaskGraphics.
Está dividida, como las dos anteriores, en dos funciones vStartTaskWatch y vTaskWatch.
El código de la tarea en si es sencillo y toda la implementación del reloj se encuentra en una clase llamada Watch. La clase Watch se apoya sobre otra clase llamada Menu.

TASKWATCH_C  http://www.megaupload.com/?d=VNHYX50C

sta tarea es mas larga, pero su código es más sencillo de entender,
ya que la mayor parte del código solo trata de enviar las primitivas a la
tarea TaskWatch.

Todas las funciones Qglcd_… están definidas en el archivo TaskWatch.h más o menos como:

#define Qglcd_pixel( x, y, c )      \
xMessagePrimitive.function = __glcd_pixel;
xMessagePrimitive.intA = x;
xMessagePrimitive.intB = y;
xMessagePrimitive.intC = c;
xMessagePrimitive.time = xTaskGetTickCount
();
xQueueSend
( pxResources->xQueuePrimitive, ( void * )&xMessagePrimitive, portMAX_DELAY );

La clase Menu

La case Menu esta compuesta de dos archivos:
Menu.h que declara los métodos y atributos del objeto.
Menu.c que define los métodos del objeto.
Un objeto del tipo menú implementa una maquina de estados finitos(FSM) de Mealy. Está declarado de la siguiente manera:

typedef struct connection{
int newnode;
char functname
[5];
void
(*pfunction)(void*);
}connection;
//enum KEY_VALUE{NONE, APRESS,BPRESS,CPRESS,AHOLD,BHOLD,CHOLD}; 
typedef struct{
char name
[5];
// int number;
connection connections
[6];
}node;
typedef struct{
node *tree;
int state;
int size;

}Menu;

Y tiene los siguientes métodos:

Menu *MenuConstruct( Menu *this, node *tree, int size );
void MenuDestruct
( Menu *this );
void MenuProcessV
( Menu *this, int input, void * object );
char *MenuGetNodeName
( Menu *this );
char *MenuGetNodeChildName
( Menu *this, int input );
char *MenuGetNodeFunctionName
( Menu *this, int input );

En la función MenuConstructor se asigna al puntero tree la dirección de una estructura que contendrá la organización del menú. Esta es la usada para emular los menús del F91W:

Menú

Como el reloj tiene 6 posibles teclas (A,B,C cortos y A,B,C largos) cada estado de la maquina tiene 6 posibles acciones. Cada acción puede llamar a una cambiar de estado y/o llamar a una función apuntada por el parámetro pfunction.

Después de “construir” un objeto menú (MenuConstructor) solo debemos llamar a la función MenuProcessV. Ésta acepta 3 parámetros:
Menu *this: El menú que se pretende procesar.
int input: La tecla pulsada.
void * object: El parámetro(normalmente un objeto) que se le pasará a la función apuntada por pfunction.

Un objeto menú tiene en cada uno de sus nodos un nombre. Para obtener información sobre los nombres la clase tiene 3 métodos:
MenuGetNodeName: Devuelve el nombre del nodo actual.
MenuGetNodeChildName: Devuelve el nombre de un nodo inferior.
MenuGetNodeFunctionName, Devuelve el nombre de la función a la que apunta pfunction.

La tarea TaskWatch llama a la función MenuGetNodeName cada vez que el reloj cambia de menú y su texto es representado en formato Arial(24 pixels de alto).

La clase Watch

typedef struct Wacth{
Menu menu1;
rtccTimeDate timedate;
rtccTime alarm;
rtccTime stopwatch;
rtccTime splittime;
long start, stop, split, out;
int ChangeAlarmCounter, ChangeTimeCounter;
int PM24;
int ALM;
int SIG;
int RUN;
int SPL;
}Watch;

La clase Watch encapsula todo el funcionamiento interno del reloj. Almacena el valor de la hora, la alarma y el cronometro, así como variables de estado. Si por ejemplo ponemos el reloj en modo 24H se pone a uno el campo de Watch.PM24 = 1 y esto será usado en la representación del reloj.ub-3142430588617024″; /* Artículo reloj casio */ google_ad_slot = “5444473188”; google_ad_width = 336; google_ad_height = 280; //–> window.google_render_ad()

Fuente de alimentación 0-25V 2.5A

mayo 15, 2009 en 3:19 pm | Publicado en Electrónica, Microcontroladores | Deja un comentario

¿Quién no se ha planteado en alguna ocasión montar una fuente de alimentación de laboratorio?. De hecho, sólo hay que teclearlo en Google para encontrar cientos de esquemas, montajes, proyectos completos y todo tipo de información no queremos ser menos, y gracias a la contribución del amigo Valdorre,
presentamos esta magnífica fuente de alimentación de 0 a 25V y 2.5A.

La fuente está diseñada siguiendo como base un esquema publicado en el nº 260 de la revista Elektor con algunas modificaciones que hizo Valdorre:

  • eliminación la salida RS232
  • sustitución del 16F84 por un 16F873
  • programación en Assembler
  • ajuste de tensión y corriente con un encoder óptico

Sólo hay que mirar el frontal para darse cuenta del acabado detallista de la misma:

Fuente Frontal

Otras fotos de las “tripas” de la fuente:

Fuente lateral

Fuente superior

Como se observa perfectamente en las fotos, la fuente está construida con dos circuitos, el de control y el de potencia.

El primero tiene todos los controles y gestiona el display LCD. Este es su esquema:

Circuito de control

La otra PCB contiene los dispositivos de potencia:

Circuito de potencia

Ambos esquemas, junto con los diseños de las dos PCB en Eagle, el código fuente en ASM y el fichero HEX para el PIC, pueden descargarse aquí:

descarga Megaupload

Página siguiente »


Entries y comentarios feeds.