Taller de Interrupciones Organizacio n del Computador 1 Verano 2016 Introduccio n Para este taller se propone utilizar un ArduinoUNO como unidad de procesamiento principal para controlar un robot que sea capaz de seguir una lı nea blanca sobre un fondo negro. El desarrollo del mismo se realizara utilizando el simulador web www.123d.circuits.io. El robot El robot que se va a utilizar posee un ArduinoUNO, dos sensores infrarrojos, un pulsador y dos motores controlados por un driver (ver Fig. 1): El ArduinoUNO: es una placa de desarrollo que tiene como unidad de procesamiento un microcontrolador ATmega328. Esta placa cuenta con terminales (o pines) a las que podemos conectar sensores, motores, LEDs, etc. El ArduinoUNO cuenta tambie n con un LED incorporado en la placa que esta asociado al pin 13, este LED puede ser utilizado, por ejemplo, para debuguear el co digo. Los motores: sirven para mover el robot en lı nea recta (los dos motores con igual velocidad) o doblando en algu n sentido (diferentes velocidades en cada motor). El driver: manejan la corriente que necesitan los motores. En nuestra simulacio n los motores seleccionados cuentan con drivers internos, por lo que no es necesario incluirlos en el circuito. Los sensores infrarrojos: permiten medir cambios de color en el suelo. Cuando detectan un cambio de color estos sensores disparara n una interrupcio n. El pulsador: es un dispositivo de entrada que se debera leer por polling. Sensores Infrarrojos Motores Arduino UNO Driver Bumper o Boton Figura 1: El robot El simulador Para simular el robot se utilizara n componentes similares a los del mismo en un el simulador web www.123d.circuits.io. Pero antes es necesario hacer una introduccio n a los componentes que se utilizara n. 1
Figura 2: Protoboard El Protoboard es una plataforma de pruebas que permite interconectar componentes electro nicos sin la necesidad de utilizar soldadura. Las conexiones se hacen por medio de la minas meta licas internas que ejercen presio n sobre los terminales de los componentes. Algunos agujeros se encuentran conectados horizontalmente y otros verticalmente (ver Fig. 2). Los cables son los elementos por los cuales circula la corriente ele ctrica. Utilizaremos la siguiente convencio n de colores: rojo para los cables de 5V negro para los cables de 0V (masa) amarillo para las conexiones de entradas al ArduinoUNO naranja para las conexiones con los motores verde para conexiones internas del protoboard Las resistencias sirven para limitar la corriente que circula por un circuito y ası evitar que se queme un componente. Los botones o switches no son ma s que simples interruptores. Existen dos tipos, dependiendo si mantienen el valor una vez que se sueltan (funcionamiento similar al de una llave de luz) o no (funcionamiento similar al de un timbre). Antes de empezar Para poder utilizar el simulador se debe ingresar a la pa gina web www.123d.circuits.io y crear una cuenta. Al ingresar, hacer click en + New y elegir la opcio n New Electronics Lab. Esto nos llevara a una pa gina similar a la de la Fig. 3. En dicha Fig. se puede observar la interfaz del simulador. El mismo posee un protoboard y distintos controles que permiten agregar componentes en la pestan a + Components. Para este taller utilizaremos los componentes que figura en la seccio n Arduino Basic Kit. Cuando se agrega un ArduinoUNO en el simulador se habilita la opcio n de editar, cargar y ejecutar co digo desde la pestan a Code Editor. Adema s en la ventana Code Editor se puede acceder al Serial Monitor donde podremos ver salida de debug. Para comenzar la simulacio n es necesario tocar el boto n Start Simulation. Funciones importantes El lenguaje Arduino esta basado en C/C++. Referencia en www.arduino.cc/en/reference/homepage. Las funciones relevantes para este taller son: unsigned long millis() devuelve el nu mero de milisegundos desde que el arduino comenzo a correr el programa. void attachinterrupt(digitalpintointerrupt(pin), ISR, mode) : permite setear una interrupcio n, pin es la entrada del arduino a la cual esta conectada la interrupcio n. ISR es el nombre de la funcio n que va a atender la interrupcio n, mode es el tipo de interrupcio n, en este taller siempre se utilizara CHANGE. void analogwrite(pin, value) es el mecanismo que cuenta el ArduinoUNO para tener una salida analo gica. En pin se emite el valor value en el formato PWM (Pulse Width Modulation, en espan ol: Modulacio n por ancho de pulsos). La sen al analo gica que se emite puede variar entre el valor mı nimo 0 (que corresponde a 0V) y el ma ximo 255 (que corresponde a 5V). En el caso del taller el 0 corresponde a el motor detenido y el 255 a ma xima potencia. 2
Figura 3: Interfaz del simulador int digitalread(pin) lee el valor de una entrada digital pin, puede ser un 1 ó un 0. Serial.begin(speed) configura e inicializa la comunicación serial a la velocidad dada por speed. En el taller utilizaremos speed=9600 Serial.println( Esto es una salida de debug ) imprime texto en el puerto serial. Consigna 1) a) Construir el circuito que se muestra en la Fig. 4 y testear que los LEDs se prendan cuando se pulsan o activan los botones (no hace falta cargar código en el ArduinoUNO para esto). Nota: no usar el protoboard que viene originalmente. ArduinoUNO led pulsador motor left resistencia motor right botón 1 botón 2 Observaciones: Figura 4: Circuito completo las resistencias deben ser configuradas como de 220Ω (220 Ohms). el pulsador solo mantiene el valor mientras lo tenemos presionado los botones 1 y 2 mantienen su valor una vez que los soltamos algunos componentes tienen polaridad, con lo cual no son reversibles. Prestar especial atención a como se deben conectar. 3
Utilizaremos el pulsador para simular el pulsador del robot y los botones 1 y 2 para simular el comportamiento de los sensores infrarrojos. b) Utilizar el código de ejemplo anexo a este enunciado para testear la simulación. 2) Se deberán programar 3 comportamientos distintos de un robot siguiendo una línea. En todos los casos el robot siempre deberá tener guardado lo que está haciendo, llamaremos a esto estado interno. Las configuraciones posibles de los motores son: Avanzando ambos motores deben ser configurados con potencia 75 Girando izquierda se debe configurar el motor izquierdo con potencia 35 y el derecho con potencia 130 Girando derecha igual al anterior pero intercambiando los motores Detenido ambos motores reciben cero como potencia Los pines del ArduinoUNO están conectados de la siguiente manera: pin Conexión 2 Sensor izquierdo 3 Sensor derecho 5 Potencia motor derecho 6 Masa motor derecho 9 Masa motor izquierdo 10 Potencia motor izquierdo 12 Pulsador Los pines que van a masa de un motor deben setearse inicialmente en cero y no modificarse. Por último, el control de los motores se debe realizar en la rutina principal y no en una rutina de atención de una interrupción. Comportamiento 1 Utilizando 1 sensor infrarrojo (Sensor izquierdo) y el pulsador programar el ArduinoUNO para lograr el siguiente comportamiento: El robot deberá alternar entra las dos configuraciones de los motores: Girando izquierda y Girando derecha para poder seguir la línea. Se inicia en Girando derecha y se mantiena hasta que el sensor detecte un cambio (y produzca una interrupción). En ese momento debe cambiar a Girando izquierdahasta la próxima interrupción. Y así sucesivamente. El pulsador debe comportarse como interruptor ON/OFF, es decir, cuando el pulsador esté apretado el robot debe detenerse (configurado como Detenido) y cuando se suelta el robot debe seguir en el estado que estaba (siguiendo la línea). A continuación se muestran las dos máquinas de estados (ver Fig. 5) que reflejan el comportamiento esperado. Figura 5: Comportamiento 1 Comportamiento 2 Utilizando los 2 sensores infrarrojos y el pulsador programar el ArduinoUNO para lograr el siguiente comportamiento: 4
El robot arrancará configurado en Avanzando. Cuando detecte que se desvía de la línea deberá corregir su rumbo. Para ello, si el sensor izquierdo empieza a sensar blanco (lo cual produce una interrupción), se debe modificar a girando izquierda hasta que el mismo sensor vuelve a sensar negro (produciendo nuevamente una interrupción). Lo mismo sucede si el sensor que provoca una interrupción es el sensor derecho. El pulsador debe comportarse como interruptor ON/OFF, es decir, cuando el pulsador esté apretado el robot debe detenerse (configurado como Detenido) y cuando se suelta el robot debe seguir en el estado que estaba (siguiendo la línea). A continuación se muestra las dos máquinas de estados (ver Fig. 6) que reflejan el comportamiento esperado. Figura 6: Comportamiento 2 Comportamiento 3 Utilizando los 2 sensores infrarrojos y el pulsador programar el ArduinoUNO para lograr el siguiente comportamiento: El robot arrancará configurado en Avanzando. Cuando detecte que se desvía de la línea deberá corregir su rumbo. Para ello, si el sensor izquierdo empieza a sensar blanco (lo cual produce una interrupción), se debe modificar a girando izquierda hasta que el mismo sensor vuelve a sensar negro (produciendo nuevamente una interrupción). Lo mismo sucede si el sensor que provoca una interrupción es el sensor derecho. el pulsador debe comportarse como una pausa de 3 segundos, es decir, que cuando el pulsador es activado el robot configurarse como Detenido por 3 segundos y luego continuar con su comportamiento anterior. A continuación se muestra las dos máquinas de estados (ver Fig. 7) que reflejan el comportamiento esperado. Figura 7: Comportamiento 3 Anexo Código de ejemplo 1 2 /* Constantes que no cambian y son usadas para setear el numero de los pines */ 3 # define motorpina 5 // el n u m e r o d e l p i n de u n o de l o s c a b l e s de m o t o r 4 # define motorpinb 6 // el n u m e r o d e l p i n d e l o t r o c a b l e d e l m o t o r 5 # define sensorint 3 // el n u m e r o d e l p i n d e l s e n s o r q u e i n t e r r u m p e 5
6 # define sensorpoll 2 // el n u m e r o d e l p i n d e l p u l s a d o r 7 8 9 /* variables que cambian su valor : */ 10 bool andando = true ; 11 bool nitro = false ; 12 13 /* setup inicial */ 14 void setup () { 15 pinmode ( sensorpoll, INPUT_PULLUP ); // i n i c i a l i z o el p i n p u l s a d o r c o m o u n a e n t r a d a 16 pinmode ( motorpina, OUTPUT ); // i n i c i a l i z o el p i n A d e l m o t o r c o m o u n a s a l i d a 17 analogwrite ( motorpina,0) ; // p o n g o en 0 el p i n A d e l m o t o r 18 pinmode ( motorpinb, OUTPUT ); // i n i c i a l i z o el p i n B d e l m o t o r c o m o u n a s a l i d a 19 Serial. begin (9600) ; // c o n f i g u r o e i n i c i a l i z o la c o m u n i c a c i o n s e r i a l a 9 6 0 0 b a u d i o s 20 // c o n f i g u r o la i n t e r r u p c i o n d e l p i n s e n s o r I n t p a r a q u e l l a m e a la f u n c i o n m e I n t e r r u m p i e r o n 21 // c u a n d o se p r o d u c e un c a m b i o 22 attachinterrupt ( digitalpintointerrupt ( sensorint ), meinterrumpieron, CHANGE ); 23 } 24 25 /* loop del programa */ 26 void loop (){ 27 if( andando ){ // P r e g u n t o si e s t o y en e s t a d o a n d a n d o 28 if ( digitalread ( sensorpoll )){ // P r e g u n t o si el p u l s a d o r e s t a a p r e t a d o 29 nitro = true ; // Si e s t o y en e s t o s e s t a d o s p o n g o s e t e o el e s t a d o n i t r o 30 Serial. println (" nitro = true "); // M u e s t r o p o r s e r i a l q u e c a m b i e de e s t a d o 31 } 32 else { // Si el p u l s a d o r no e s t a a p r e t a d o 33 nitro = false ; // p o n g o n i t r o c o m o false 34 Serial. println (" nitro = false "); // M u e s t r o p o r s e r i a l q u e c a m b i e de e s t a d o 35 } 36 } 37 actualizarestado (); // l l a m o a la f u n c i o n q u e m a n d a p o t e n c i a a l o s m o t o r e s d e p e n d i e n d o d e l e s t a d o d e f i n i d o 38 } 39 40 /* funcion que actualiza la velocidad de los motores dependiendo del estado */ 41 void actualizarestado (){ 42 if( andando ){ // Si el e s t a d o es a n d a n d o 43 if( nitro ){ // y n i t r o es v e r d a d e r o 44 analogwrite ( motorpinb,250) ; // S e t e o la v e l o c i d a d de el m o t o r a 2 5 0 45 } 46 else { 47 analogwrite ( motorpinb,30) ; // Si n i t r o == 0 e n t o n c e s p o n g o v e l o c i d a d de 30 a l o s m o t o r e s 48 } 49 } 50 else { // Si a n d a n d o no es v e r d a d e r o 51 analogwrite ( motorpinb,0) ; // f r e n o el m o t o r p o n i e n d o v e l o c i d a d 0 52 } 53 } 54 55 /* funcion que se llama cuando se produce una interrupcion */ 56 void meinterrumpieron (){ 57 Serial. println (" Interrupcion "); // m u e s t r o p o r s e r i a l q u e h u b o u n a i n t e r r u p c i o n 58 if( andando ){ // si e s t o y a n d a n d o 59 andando = false ; // e n t o n c e s f r e n o 60 Serial. println (" andando = false "); // y m u e s t r o p o r s e r i a l q u e f r e n e 61 } 62 else { // Si e s t o y f r e n a d o 63 andando = true ; // c o m i e n z o a a n d a r 64 Serial. println (" andando = true "); // y m u e s t r o p o r s e r i a l q u e c o m e n z e a a n d a r 65 } 66 } 6