Taller-skybot:Sesión4:Programación Skybot:Ejemplos

De WikiRobotics
Saltar a: navegación, buscar

Introducción

El objetivo de este capítulo es mostrar ejemplos de programas en C para manejar diferentes recursos del robot. Editando, compilando, probando y modificando los ejemplos se aprenderá muy rápidamente a manejar el robot y en poco tiempo se podrá dar rienda suelta a la imaginación para hacer otras cosas... ¡Qué comience la fiesta!

Descargas

ejemplos-skybot.zip Todos los ejemplos

Ejemplos sueltos

ledon.c ledon.hex Encender el led de la Skypic
ledp.c ledp.hex Hacer que el led de la Skypic parpadee
pulsador-led.c pulsador-led.hex Mostrar por el led el valor negado del pulsador de pruebas
motor-on.c motor-on.hex Activar los motores del Skybot para que avance
sensor4.c sensor4.hex Ejemplo de lectura del sensor 4. Su estado se refleja en el led. Si lee blanco el led se apaga, si lee negro se enciente.
sensores.c sensores.hex Prueba de los 4 sensores. Se lee su estado y se envía al puerto A. Si se conectan 4 leds externos se podrá ver en ellos el estado de los sensores.
motores-sensor3.c motores-sensor3.hex Prueba de motores y sensores. El robot avanza cuando le sensor 3 lee negro. Se para si lee blanco
timer0-delay.h --- Rutina de pausa que usa el temporizador 0 (sin interrupciones). Para ser incluido desde nuestros programas en c.
ledp2.c ledp2.hex Hacer parpadear el led de la Skypic a la frecuencia de 1Hz, usando el temporizador 0
bumper.c bumper.hex Mostrar el estado de un sensor de contacto (bumper) por el LED
conversor-ad1.c conversor-ad1.hex Ejemplo de lectura del sensor de Luz: Se apaga el led en la oscuridad (y se muestra el nivel de luz en la tarjeta Freeleds conectada al puerto C)
secuencia.c secuencia.hex El skybot realiza una secuencia pre-grabada de movimientos
sci.h ---- Funciones para acceso al puerto serie
sci-eco.c sci-eco.hex Hacer 'eco' de todo lo recibido a través por el puerto serie
sci-skybot-test.c sci-skybot-test.hex Control del Skybot y lectura de los sensores a través de un terminal serie
skybot.h ---- Constantes y funciones para trabajar con el Skybot
linea.c linea.hex El robot Skybot sigue una línea negra
lapa.c lapa.hex Comportamiento de tipo lapa: El robot tiende a pegarse a los objetos que tiene delante
mogollon.c mogollon.hex Plantilla modelo para participar en el concurso del Mogollón!

Repositorio

Ejemplos básicos

Encender el led de la Skypic

  • Fichero: ledon.c
  • Descripción: Encender el led de la Skypic
  • Explicación:

Este es el ejemplo "hola mundo" pero con modificaciones para hacerlo más legible.

La directiva #define nos permite definir constantes. En este ejemplo se definen las constantes ENTRADA, LED y ON:

#define ENTRADA 1
#define LED     RB1
#define ON      1

Esto nos permite poder usar estas nuevas constantes en vez de sus valores. Ahora ya no nos tenemos que acordar de que el led de la skypic está en el bit RB1 ni de que para encenderlo hay que escribir un 1. Ahora simplemente haciendo:

LED = ON;

Se encenderá el led de la Skypic

Led parpadeante

  • Fichero: ledp.c
  • Descripción: Este ejemplo hace parpadear el led de la Skypic
  • Explicación:

En la función main() nos encontramos con:

LED=LED^1;

Esta línea cambia de estado el LED. Si estaba encendido lo apaga y vice-versa. El símbolo ^ es el operador XOR (O exclusivo).

pausa(RETRASO);    //-- Pausa

A continuación se llama a la función pausa() que la hemos definido nosotros para hacer una pausa. El microcontrolador ejecuta instrucciones muy rápido. Si cambiamos de estado el led muy rápidamente, nuestro ojo no lo apreciará y dará la impresión de que el led está siempre encendido. Por ello hay que introducir una pausa. En la función de pausa se decrementa una variable hasta llegar a 0. Cambiando el parámetro que se le paso conseguimos una pausa mayor o menor.

  • Ejercicios para practicar:
EJERCICIO 1: Modificar el valor de la constante RETRASO. Poniendo diferentes valores. Por ejemplo 0x8000, 0x4000... ¿Qué sucede?
EJERCICIO 2: Eliminar la llamada a la función pausa(). ¿Qué sucede?

Leyendo el pulsador de pruebas

  • Fichero: pulsador-led.c
  • Descripción: Mostrar por el LED de la skypic el estado del pulsador de pruebas
  • Explicación:

El pulsador de pruebas de la Skypic se encuentra en el bit RB1. Para hacer el programa más legible se define la constante PULSADOR:

 #define PULSADOR  RB0

El bucle principal simplemente lee el valor del PULSADOR y saca por el led el estado contrario: si esta apretado se enciende y se apaga en caso contrario:

LED = PULSADOR^1;

Ejemplos de motores y sensores

Activar los motores para que el robot avance

  • Fichero: motor-on.c
  • Descripción: Activar los motores del Skybot para que avance
  • Explicación:

Ejemplo de cómo activar los motores para que el Skybot se desplace hacia adelante. Esto se consigue enviando valores por el puerto B

Para hacer la programación más sencilla, se ha definido la constante SKYBOT:

#define SKYBOT PORTB

y las siguientes constantes contienen los valores necesarios para que el robot realice el resto de movimiento: Adelante, atrás, izquierda y derecha. Están definidos en hexadecimal por comodidad

 #define   AVANZA     0x1C
 #define   ATRAS      0x16
 #define   IZQUIERDA  0x1E
 #define   DERECHA    0x14
 #define   STOP       0x00

Para hacer que el robot avance bastará con ejecutar el siguiente comando:

SKYBOT=AVANZA;
  • Ejercicios para practicar:
EJERCICIO 3: Modificar el programa para que el Skybot gire, se pare o vaya hacia atrás.

Lectura del sensor 4

  • Fichero: sensor4.c
  • Descripción: Ejemplo de lectura del sensor 4. Su estado se refleja en el led. Si lee blanco el led se apaga, si lee negro se enciente.
  • Explicación:

Los sensores están conectados en los bits RB7, RB6, RB5 y RB0 del puerto B. Utilizaremos las siguientes constantes para usarlos:

#define   SENSOR1  RB0
#define   SENSOR2  RB5
#define   SENSOR3  RB6
#define   SENSOR4  RB7

Definimos la constante SENSOR para indicar el sensor que utilizaremos en el ejemplo, que en este caso será el 4:

#define   SENSOR SENSOR4

El programa principal es muy sencilla. Sólo hay que enviar al LED la lectura del sensor mediante al instrucción:

LED = SENSOR;
  • Ejercicios para practicar:
EJERCICIO 4: Modificar el programa para utilizar el sensor 3 en vez del 4

Lectura de los 4 sensores

  • Fichero: sensores.c
  • Descripción: Prueba de los 4 sensores. Se lee su estado y se envía al puerto A.
  • Explicación:

Este ejemplo es similar al sensor4 pero en este caso se leen todos los sensores y su estado se muestra por el PUERTO A. Como la Skypic tiene sólo un led, para poder probar este programa habrá que conectar 4 leds externos o bien utilizar alguna placa que ya los lleve, como por ejemplo la Freeleds.

Los bits del puerto A se configuran para salida:

 TRISA=0;

El puerto A puede funcionar como digital o analógico. En este ejemplo lo queremos usar como digital. Se configura con la siguiente instrucción:

 ADCON1=0x06;

El bucle principal muestra el estado de los sensores en los bits del puerto A usando las instrucciones:

RA0 = SENSOR1;
RA1 = SENSOR2;
RA2 = SENSOR3;
RA3 = SENSOR4;

Prueba de motores y sensores

  • Fichero: motores-sensor3.c
  • Descripción: Prueba de motores y sensores. El robot avanza cuando le sensor 3 lee negro. Se para si lee blanco.
  • Explicación:

Ejemplo de un comportamiento muy sencillo del robot. Si el sensor 3 lee negro, el robot está parado. Pero si lee blanco, se pone a avanzar. Cambiando el valor de la constante SENSOR podemos hacer la misma prueba con cualquiera de los otros tres sensores.

Para leer el estado del sensor se han definido las constantes BLANCO y NEGRO:

#define NEGRO  1
#define BLANCO 0

Para comprobar si el sensor toma un valor concreto utilizamos la instrucción if:

if (SENSOR==BLANCO) {...}
  • Ejercicios para practicar:
EJERCICIO: Colocar el robot sobre una superficie blanca (por ejemplo un folio). Colocar en un trozo de papel un trozo de cinta aislante negro. El robot avanzará pero si le ponemos el trozo negro debajo del sensor 3 se parará. Si lo desplazamos hacia adelante el robot volverá a avanzar hasta situarse otra vez sobre él. Dará la impresión de que está siguiente el trozo de papel negro que le estamos poniendo :-). En este ejemplo sólo se moverá en línea recta.

Modificar el programa para que avance cuando el sensor lea negro y se pare cuando sea blanco

Sensores de contacto (BUMPERS)

  • Fichero: bumper.c
  • Descripción: Mostrar el estado de un bumper por el led
  • Explicación:

Los sensores de contacto están conectados en los pines RA1 y RA2 del puerto. Por eso establecemos las siguientes definiciones:

#define BUMPER1 RA1
#define BUMPER2 RA2

El puerto A hay que configurarlo como entradas digitales, para ellos ejecutamos:

 TRISA = 0xFF;
 ADCON1=0x0E;

Para mostrar el estado del bumper en el led hacemos la asignación:

 LED = BUMPER;
  • Ejercicios para practicar:
EJERCICIO: Modificar el programa para mostrar por el led el otro bumper

Sensor de Luz: Endender el led en la oscuridad

  • Fichero: conversor-ad1.c
  • Descripción: Si está oscuro, se enciende el led de la Skypic. En caso contrario se apaga
  • Explicación:

Ejemplo de manejo del sensor de Luz del Skybot que está conectado al canal RA0 del conversor analógico-digital del PIC. Del sensor se lee un valor de 8 bits, comprendido entre 0 (mucha luz) y 255 (oscuridad)

Cuando el valor de luz leido supera el umbral de oscuridad, definido por la constante UMBRAL_OSCURIDAD se enciende el led de la skypic. Además, el valor leido se envía al puerto C y se puede visualizar si se conecta una tarjeta freeleds.

#define UMBRAL_OSCURIDAD 0xFC

La función conversor_ad_conf() configura el puerto A para que el pin RA0 funcione como una entrada analógica. La función conversor_ad_read() lee el sensor de luz.

Se utiliza la variable luz para almacenar la lectura del sensore de luz. Está declarada al comienzo del programa:

unsigned char luz;

El bucle principal es muy sencillo. Se lee el sensor de luz, se almacena en la variable luz, se saca por el puerto C y se comprueba si su valor supera el umbral de oscuridad. Si es así el led se enciende y en caso contrario se apaga.

 luz = conversor_ad_read();
 PORTC = luz;
 if (luz>=UMBRAL_OSCURIDAD)
   LED=1;
 else
   LED=0;
  • Ejercicios para practicar:
EJERCICIO: Modificar el programa para que el robot avance mientras haya suficiente luz y se pare en la oscuridad. Modificar el valor de la constante UMBRAL_OSCURIDAD para adaptarlo a la luz ambiental.

Temporización

Led parpadeante con temporización

  • Fichero: ledp2.c
  • Descripción: Se hace parpadear el led a la frecuencia de 1Hz, usando el temporizador 0
  • Explicación:

Ejemplo de uso de la librería timer0_delay.h para cambiar el estado del led cada medio segundo. Para usar esta librería hay que poner esta instrucción:

#include "timer0-delay.h"

Para realizar las pausas se utiliza el temporizador 0. El microcontrolador PIC tiene varios temporizadores que funcionan como cronómetros, permitiéndonos hacer cálculos de tiempo en nuestro programas.

Para usar el temporizador 0 debemos configurarlos llamando a la siguiente función:

timer0_configurar();

Las pausas se realizan llamando a la función timer0_delay() pasando como argumento el tiempo en centésimas de segundo. En este ejemplo se quiere cambiar el estado del led cada medio segundo, es decir, cada 50 centésimas:

timer0_delay(50);
  • Ejercicios para practicar:
EJERCICIO: Hacer un programa para que el led permanezca encendido durante 50 centésis y se apague durante 10
EJERCICIO: Hacer que el led parpadee a frecuencias más altas. Disminuir el valor de la pausa. Probar con 50, 25, 10, 5...

Secuencia de movimiento pregrabada en el Skybot

  • Fichero: secuencia.c
  • Descripción: El Skybot realiza una secuencia de movimientos pregrabada
  • Explicación:

Este es uno de los ejemplos más divertidos :-). Ya sabemos cómo mover el robot. También podemos esperar un determinado tiempo. Tenemos todos los elementos para hacer que el robot realice una secuencia de movimiento pregrabada del tipo: ir hacia adelante durante 1 segundo, luego girar a la izquierda durante 0.3 segundos, luego ir hacia trás...

Probar el ejemplo y observar cómo se mueve el Skybot. Una vez terminada la secuencia habrá que pulsar el botón de RESET para que la vuelva a realizar.

  • Ejercicios para practicar:
EJERCICIO: Modificar la secuencia para que describa un triangulo y que al terminar vuelva al punto inicial.

Puerto serie en el PIC

Hacer eco a través del puerto serie

  • Fichero: sci-eco.c
  • Descripción: Ejemplo de uso de las funciones del puerto serie. Todos los caracteres recibidos se devuelven
  • Explicación:

La comunicación mediante puerto serie es muy interesante para intercambiar información con el PC de manera muy rápida y sencilla. Para utilizarlo necesitamos incluir el fichero sci.h:

#include "sci.h"

Antes de utilizarlo hay que configurarlo. Esto se hace llamando a la siguiente función:

 sci_conf();

El puerto serie se configura para trabajar a 9600 baudios. Para enviar una cadena de caracteres desde la Skypic al PC se usa la función sci_cad():

sci_cad("Haciendo eco...");

Los datos recibidos se almacenan en la variable c, definida al comienzo del programa:

unsigned char c;

La recepción de datos se hace llamando a la función sci_read():

c=sci_read();

El bucle principal lee los recibido por el puerto serie, lo saca por el puerto B para ser visualizado si se conecta una tarjeta freeleds y finalmente lo re-envía de nuevo al PC mediante la función sci_write():

PORTB=c;
sci_write(c);
Icono aviso.png Para probar este programa hay que arrancar un terminal de comunicaciones en el PC. Por ejemplo el Hyperterminal de Windows o el Gtkterm de Linux. Es necesario configurarlo para trabajar a 9600 baudios

Control del Skybot a través del puerto serie

  • Fichero: sci-skybot-test.c
  • Descripción: Control de Skybot y lectura de sensores mediante el puerto serie
  • Explicación:

Es un ejemplo sencillo que nos permite controlar el skybot desde un terminal de comunicaciones en nuestro PC. Al hacer un reset aparecerá un menú de opciones:

 Menu
 ----
 Teclas q,a,o,p,ESPACIO.- Mover Skybot
 Teclas 1,2,3,4.- Leer sensores 3,4 y bumpers

Mediante las teclas q,a,o,p y ESPACIO moveremos el robot hacia adelante,atras, izquierda, derecha y parado respectivamente. Las teclas 1-4 nos permiten obtener el estado de los sensores de infrarrojos 3 y 4 y los bumpers 1 y 2 respectivamente.

El bucle principal lee la tecla pulsada por el usuario y la almacena en la variable c. A continuación utiliza la instrucción switch() para ejecutar la acción oportuna.

Comportamientos sencillos en el Skybot

Seguir la línea negra

Skybot-siguelineas.jpg

El robot Skybot siguiendo una línea negra
(Vídeo)

  • Fichero: linea.c
  • Descripción: El robot Skybot sigue una línea negra
  • Explicación:

Todas las constantes relacionadas con el Skybot se han almacenado en el fichero skybot.h, así como también la función configurar_skybot() para configurar los puertos A y B para trabajar con el Skybot. Por eso, para programar el skybot ponemos lo siguiente:

#include "skybot.h"

Se definen las constantes IZQUIERDO y DERECHO para indicar en qué sensores se han colocado en cada lado del Skybot. Esto debe ser modificado por el usuario según dónde haya conectado cada sensor. Por defecto su valor se establece a:

 #define IZQUIERDO SENSOR4
 #define DERECHO   SENSOR3

Lo primero que se hace es configurar el skybot:

 configurar_skybot();

El bucle principal comprueba el estado de los sensores izquierdo y derecho. Se implementa el algoritmo mostrado en la siguiente tabla:

Sensor Izquierdo Sensor derecho Acción a tomar
NEGRO NEGRO ADELANTE
BLANCO NEGRO DERECHA
NEGRO BLANCO IZQUIERDA
BLANCO BLANCO STOP

Esta tabla se implementa fácilmente mediante instrucciones if encadenadas.

 if (IZQUIERDO==NEGRO  && DERECHO==NEGRO)  {     
   SKYBOT=AVANZA;
 }
 else if (IZQUIERDO==BLANCO && DERECHO==NEGRO)  { 
   SKYBOT=DERECHA;
 }
 else if (IZQUIERDO==NEGRO  && DERECHO==BLANCO) { 
   SKYBOT=IZQUIERDA;
 }
 else {                                           
   SKYBOT=STOP;
 }

El operador && significa 'y'. La primera línea se traduce por: "Si el sensor izquierdo lee negro y el derecho negro entonces avanza"

Comportamiento lapa: pegarse a los objetos

  • Fichero: lapa.c
  • Descripción: El robot se convierte en una lapa y tiende a pegarse a los objetos ;-)
  • Explicación:

Ejemplo de comportamiento tipo lapa: según el estado de los sensores de contacto (bumpers) el Skybot tiende a pegarse hacia el objeto que tiene delante.

Se utilizan las constantes BUMPER_IZDO y BUMPER_DECHO para indicar qué bumpers están colocados en cada lado

 #define BUMPER_IZDO  BUMPER2  //Bumper izquierdo
 #define BUMPER_DECHO BUMPER1 //Bumper derecha

El comportamiento del robot está dado por la siguiente tabla:

Bumper Izquierdo Bumper derecho Acción a tomar
ON OFF IZQUIERDA
ON OFF DERECHA
OFF OFF AVANZA
ON ON STOP

Se implementa mediante ifs encadenados:

   if (BUMPER_IZDO==ON && BUMPER_DECHO==OFF) {
     SKYBOT=IZQUIERDA;
   }
   else if (BUMPER_IZDO==OFF && BUMPER_DECHO==ON) {
     SKYBOT=DERECHA;
   }
   else if (BUMPER_IZDO==OFF && BUMPER_DECHO==OFF) {
     SKYBOT=AVANZA;
   }
   else {
     SKYBOT=STOP;
     LED=ON;
   }

Plantilla para el concurso del MOGOLLÓN!

  • Fichero: mogollon.c
  • Descripción: Programa modelo para participar en el concurso del mogollón
  • Explicación:

El concurso del mogollón es el final del taller. Más información en la sesión 5

Enlaces

Noticias

  • 29/Junio/2010: Primera versión finalizada
  • 23/Junio/2010: Comenzada esta página. Migración de la documentación en HTML.