Tabla de contenido:

Programación concurrente Attiny85 o calabaza con ojos multicolores: 7 pasos
Programación concurrente Attiny85 o calabaza con ojos multicolores: 7 pasos

Video: Programación concurrente Attiny85 o calabaza con ojos multicolores: 7 pasos

Video: Programación concurrente Attiny85 o calabaza con ojos multicolores: 7 pasos
Video: ¿Qué Diablos es PROGRAMACIÓN CONCURRENTE? 2024, Noviembre
Anonim

Por jumbleview

El grito
El grito
El grito
El grito
Reemplazo de la batería de NiCd con fuente de alimentación externa
Reemplazo de la batería de NiCd con fuente de alimentación externa
Reemplazo de la batería de NiCd con fuente de alimentación externa
Reemplazo de la batería de NiCd con fuente de alimentación externa
Mango de cámara digital
Mango de cámara digital
Mango de cámara digital
Mango de cámara digital

Acerca de: Trabajo como ingeniero de software en una de las empresas del Área de la Bahía (California). Siempre que tengo tiempo, me gusta programar microcontroladores, construir juguetes mecánicos y hacer algunos proyectos de mejoras para el hogar. Más acerca de jumbleview »

Este proyecto muestra cómo controlar dos LED de ánodo común de tres colores de 10 mm (ojos multicolores de Pumpkin Halloween Glitter) con el chip Attiny85. El objetivo del proyecto es introducir al lector en el arte de la programación concurrente y en el uso de la biblioteca de prototipos de Adam Dunkels. Este proyecto asume que el lector conoce los controladores AVR de 8 bits, puede escribir algún programa en C y tiene algo de experiencia con Atmel Studio.

Código del proyecto publicado en GitHub:

Suministros

Antes de programar uno todavía necesita construir el circuito. Estos son los componentes:

  • Controlador Attiny85 (cualquier proveedor electrónico).
  • Dos LED de 10 mm de tres colores con ánodo común. LED de Adafruit
  • Resistencias 100 Ohm, 120 Ohm, 150 Ohm 0.125 o 0.250 Wt (cualquier proveedor electrónico).
  • Cabecera de seis pines para la interfaz AVR ISP. Se puede hacer con este cabezal Adafruit.
  • Algunas tablas de pan o tablas de plantilla impresas. Usé este
  • Interfaz AVR ISP MKII y Atmel Studio 6.1 (la versión posterior también debería funcionar).

Paso 1: Circut

Circut
Circut

El diseño utiliza cinco pines de chip:

  • Se utilizan dos pines para controlar los ánodos: cada ánodo LED conectado al pin dedicado.
  • Tres pines conectados (a través de resistencias) a cátodos de LED (el mismo cátodo de color de cada LED conectado al mismo pin)

Uno se preguntaría: ¿por qué no usar los seis pines de entrada / salida del chip para que los ánodos LED se conecten directamente a +5 v y cada cátodo tenga su pin dedicado? Eso hará que la programación sea sencilla. Por desgracia, existe el problema: el pin PB5 (RESET) es un pin débil capaz de proporcionar solo ~ 2 mA de la corriente, mientras que es necesario tener ~ 20 mA.

Por supuesto, uno puede construir un amplificador de transistor para este pin débil, pero yo mismo siempre que sea posible prefiero resolver el problema a través del código.

Paso 2: diagrama de tiempos

Diagrama de tiempo
Diagrama de tiempo

El diagrama de tiempos nos ayuda a comprender lo que necesitamos programar.

Las dos filas superiores del diagrama muestran el cambio de voltaje en los ánodos LED. El voltaje en los pines conectados a los ánodos LED oscila con una frecuencia de ~ 250 Hz. Esta oscilación de voltaje para el LED izquierdo es opuesta a la oscilación del LED derecho. Cuando el voltaje en el ánodo es alto, el LED correspondiente puede ser brillante. Cuando es bajo, el LED correspondiente está oscuro. Eso significa que cada LED puede brillar durante un intervalo de 2 milisegundos y estar oscuro durante otros 2 milisegundos. Debido a que el ojo humano tiene cierta inercia, el observador no percibe el parpadeo de 250 Hz. Las tres filas inferiores del diagrama muestran el cambio de voltaje en los pines conectados a los cátodos de los LED. Miremos la primera columna del diagrama. Muestra el caso cuando el LED izquierdo está en color rojo y el LED derecho en color verde. Aquí los cátodos ROJOS permanecen bajos mientras que el ánodo izquierdo está alto, el cátodo VERDE permanece bajo mientras que el ánodo derecho está alto y el cátodo AZUL permanece bajo todo el tiempo. Otras columnas en el diagrama muestran combinaciones de voltaje de cátodo y ánodo para varios colores.

Como podemos ver, existe una interdependencia en el estado de los pines. Sin algún marco, no sería fácil de resolver. Y ahí es donde la biblioteca protothread resulta útil.

Paso 3: programación. Macros y definiciones

Programación. Macros y definiciones
Programación. Macros y definiciones

El ejemplo en los pasos de programación representa una versión ligeramente simplificada. El programa se acorta y alguna definición simbólica se reemplaza por constantes explícitas.

Empecemos por el principio. El programa incluye archivos que vienen con Atmel Studio, así como el encabezado de la biblioteca protothread. A continuación, hay dos macros para manipular los niveles de los pines y algunas definiciones para dar nombres lógicos a las señales de los pines. Hasta ahora nada especial.

Paso 4: Programación. Bucle principal

Programación. Bucle principal
Programación. Bucle principal

Entonces miremos al final para ver qué contiene el procedimiento principal.

La función main después de hacer algo de inicialización permanece en un ciclo para siempre. En ese bucle, realiza los siguientes pasos:

  • Invoca la rutina protothread para el LED izquierdo. Cambia el voltaje de algunos pines.
  • Haz un retraso de dos milisegundos. No hay cambios en el voltaje de los pines.
  • Invoca protothread para el LED derecho. Cambia algo de voltaje en los pines.
  • Haga 2 MS de retraso. No hay cambios en el voltaje de los pines.

Paso 5: programación. Funciones auxiliares

Programación. Funciones auxiliares
Programación. Funciones auxiliares

Antes de que comencemos a discutir los protothreads, necesitamos ver algunas funciones auxiliares. Primero hay funciones para establecer un color particular. Son sencillos. Hay tantas funciones como la cantidad de colores admitidos (siete) y una función más para configurar el LED oscuro (NoColor).

Y hay una función más que será invocada directamente por la rutina protothread. Su nombre es DoAndCountdown ().

Técnicamente hablando, el uso de dicha función no es obligatorio, pero lo encontré conveniente. Tiene tres argumentos:

  • Puntero al ajuste de función del color del LED (como RedColor o GreenColor, etc.)
  • Valor inicial del contador inverso: número de cuántas veces se debe invocar esta función en una etapa de protothread particular.
  • Puntero para invertir el contador. Se supone que cuando hay un cambio en el color, el contador inverso es 0, por lo que en la primera iteración el código asignará a ese contador el valor inicial. Después de cada iteración, el contador se reduce.

La función DoAndCountdown () devuelve el valor del contador inverso.

Paso 6: Programación. Rutinas de Protothread

Programación. Rutinas de Protothread
Programación. Rutinas de Protothread

Y aquí está el núcleo del framework: la rutina de protothread. En aras de la simplicidad, el ejemplo se limita solo a tres pasos: para el cambio de color a ROJO, a VERDE y a AZUL.

La función se invoca con dos argumentos:

  • Puntero a la estructura de protothread. Esa estructura fue inicializada por main antes de que comenzara el bucle principal.
  • Puntero para invertir el contador. Main lo puso en 0 antes de que comenzara el bucle principal.

La función establece los voltajes para activar el LED izquierdo y luego inicia el segmento de protuberancia. Este segmento se encuentra entre las macros PT_BEGIN y PT_END. En su interior hay algún código que en nuestro caso solo repite macros PT_WAIT_UNTIL. Esta macros se realiza a continuación:

  • Invocación de la función DoAndCountdown. Eso establece el voltaje en los cátodos LED para emitir un color particular.
  • Resultado devuelto comparado con 0. Si la condición es 'falsa', la función protothread regresa inmediatamente y cede el control al bucle principal.
  • Cuando se invoca protothread la próxima vez, vuelve a ejecutar el código antes de PT_BEGIN, luego salta directamente dentro de las macros PT_WAIT_UNTIL de las que regresó la última vez.
  • Tales acciones se repiten hasta que el resultado de DoAndCountdown es 0. En ese caso no hay retorno, el programa permanece en protothread y ejecuta la siguiente línea del código. En nuestro caso, es el siguiente PT_WAIT_UNTIL pero, en general, podría ser casi cualquier código C.
  • En la ejecución inicial del segundo PT_WAIT_UNTIL, el contador inverso es 0, por lo que el procedimiento DoAndCountdown () lo establece en el valor inicial. Las segundas macros se ejecutarán nuevamente 250 veces hasta que el contador de retroceso llegue a 0.
  • El estado de struct pt se restablece tan pronto como el control alcanza las macros PT_END. Cuando la función protothread se invoca la próxima vez que el segmento protothread comienza, ejecuta la línea del código justo después de PT_BEGIN.

Existe una rutina de protrocadura similar para el LED derecho. En nuestro ejemplo, simplemente aplica un orden de colores diferente, pero si podemos hacerlo de manera completamente diferente: no hay un acoplamiento estrecho entre la rutina del LED izquierdo y derecho.

Paso 7: aspectos internos

Internos
Internos

El programa completo tiene menos de 200 líneas de código (con comentarios y líneas vacías) y ocupa menos del 20% de la memoria del código Attiny85. Si es necesario, es posible utilizar aquí varias rutinas protothread más y asignarles una lógica mucho más complicada.

La biblioteca Protothreads es la forma más simple de programación concurrente por computadora. La programación concurrente es un enfoque que permite dividir el programa en partes lógicas: a veces se les llama corrutinas, a veces subprocesos, a veces tareas. El principio es que cada una de estas tareas puede compartir la misma potencia de procesador manteniendo el código más o menos lineal e independiente de otras partes. Las tareas desde el punto de vista lógico se pueden ejecutar simultáneamente.

Para los controles de sistemas avanzados de tales tareas realizadas por el kernel del sistema operativo o por el tiempo de ejecución del lenguaje integrado en el ejecutable por el compilador. Pero en el caso de protothreads, el programador de aplicaciones lo controla manualmente usando la biblioteca de macros protothreads en rutinas de tareas e invocando dichas rutinas (generalmente fuera del bucle principal).

Probablemente quieras saber cómo funciona realmente protothread. ¿Dónde se esconde la magia? Los subprocesos se basan en una característica especial del lenguaje C: el hecho de que la instrucción de caso de cambio de C puede estar incrustada en if o en algún otro bloque (como while o for). Puede encontrar detalles en el sitio de Adam Dunkels

Los componentes electrónicos de este proyecto son muy simples. La foto de arriba te da una pista. Estoy seguro de que puedes hacerlo mejor.

Recomendado: