Taller de Robótica CampusBot 2005. SESION 3. Ejemplos de programación del Skybot



Objetivos

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!


Contenido


Ejemplos básicos

Para los siguientes ejemplos desconectar el cable que une la Skypic con la CT293.

[ledp] Led parpadeante. Hacer que el led de la Skypic parpadee.

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

 PORTB^=LED;        //-- Cambiar led de estado

Esta línea cambia de estado sólo el bit RB1, dejando los demás igual. Lo que se consigue es que cada vez que se ejecuta el led pasa de un estado al contrario: de encendido a apagado y de apagado a encendido.

Es la instrucción abreviada de PORTB = PORTB ^ LED, donde ^ es el operador XOR (O exclusivo)

 pausa(RETRASO);    //-- Pausa

A continuación se llama una función que hemos definido 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 decrrementa una variable hasta llegar a 0. Cambiando el parámetro que se le paso conseguimos una pausa mayor o menor.

EXPERIMENTO: Modificar el valor de la constante RETRASO. Poniendo diferentes valores. Por ejemplo 0x8000, 0x4000... ¿Qué sucede?




Ejemplos básicos de motores y sensores


[motor-on] Activar los motores para que el robot vaya hacia adelante

Este programa simplemente hace que el robot avance. Para que se paré habrá que quitar la alimentación :-). Conseguimos que se mueva simplemente enviando.

Lo primero que se hace es configurar el PUERTO B para trabajar con el Skybot.

  //-- Configurar el puerto B para trabajar con el Skybot
  //-- RB0, RB1, RB2 y RB7 como entradas
  //-- RB3, RB4, RB5 y RB6 como salidas
  TRISB=0x87;

y después se activan los bits correspondientes del puerto B, enviado directamente un valor:

  //-- Activar los bits de los motores para que el robot avance
  PORTB=AVANZA;



[motor-off] Parar los motores

Este ejemplo es igual que el motor-on, pero en vez de enviar el valor AVANZA, se envía el valor STOP para que el robot se pare.

  //-- Parar el robot
  PORTB=STOP;

EXPERIMENTO: Modificar el valor que se envía al puerto B para que el robot se mueva de diferente manera. Para que el robot gire, los motores se activan en sentidos contrarios. Pero también girará si una de las ruedas se para y la otra avanza. Esto permite hacer giros de mayor radio y más suaves.



[sensor4] Prueba del sensor 4. Leer su estado y mostrarlo por el led

Este ejemplo es muy útil para comprobar si los sensores funcionan correctamente. El programa sólo lee el sensor 4 pero cambiando la constante SENSOR podemos leer los otros sensores, reflejando su estado por el led. La única excepción es el SENSOR 2 que comparte pin con el led. Si usamos el led, no podemos leer ese sensor :-(

//-- Indicar el sensor a comprobar. Esto se puede cambiar, pero no se puede
//-- poner el sensor 2 porque comparte pin con el led
#define   SENSOR SENSOR4

Si ponemos en esa constante el valor SENSOR3, el programa funcionará para ese sensor.

EXPERIMENTO: Cambiar el valor de la constante SENSOR para hacer pruebas con los sensores 1 y 3.



[sensores] Prueba de todos los sensores. Leer su estado y mostrarlo por 4 leds externos conectados al puerto A

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.



[motores-sensor3] Prueba de motores y sensores. El robot avanza cuando le sensor 3 lee negro. Se para si lee blanco.

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.

EXPERIMENTO: 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.




Temporización

[delay0.h] Librería para temporización (timer 0)

Esta librería se empleará desde otros programas en C (#include “delay0.h”). Tiene una función llamada delay0() que nos permite realizar pausas en unidades de 10ms. Para usar esta función, previamente hay que configurar el temporizador, llamando a timer0_configurar().

El microcontrolador PIC incluye en su interior una serie de periféricos que son muy útiles en robótica. Uno de ellos es el temporizador 0 (timer 0 en inglés). Es una especie de “cronómetro” que nos permite saber cuanto tiempo ha transcurrido desde la última vez que se empleó.

Tal y como está configurado en esta librería, la pausa máxima que podremos realizar es de 2560 ms, es decir, de 2.5 segundos aproximadamente. Y la pausa mínima es de 10 ms.

Esta es la función que hay que llamar para configurar el temporizador 0.

/************************************/
/* Configurar el temporizador 0     */
/************************************/
void timer0_configurar()

y esta es la función de pausa:

/************************************************/
/* Hacer una pausa en unidades de 10ms          */
/* ENTRADA:                                     */
/*   -pausa: Valor de la pausa en decenas de ms */
/************************************************/
void delay0(unsigned char pausa)



[ledp2] Led parpadeante con temporizador

Ejemplo de uso de la librería delay0.h. Se cambia el estado del led cada medio segundo.

Para usar esta librería debemos incluir el fichero delay0.h

//-- Para usar temporizaciones con el timer 0
#include "delay0.h"

y en el programa principal hay que configurar el temporizador 0:

//-- Configurar temporizador
  timer0_configurar();

El bucle principal es muy sencillo:

    delay0(50);    //-- Pausa de 0.5seg
    PORTB^=0x02;  //-- Cambiar el led de estado

Se hace una pausa de medio segundo y se cambia el estado del led. Eso se repite indefinidamente.

EXPERIMENTO: ¿Y si queremos hacer una rutina de pausa más larga para que el led cambie de estado cada 5 segundos? Ayuda: siempre podremos hacer una función que dentro de un bucle llame a delay0()...


El puerto serie en el PIC

Mediante el puerto serie podemos comuniar el robot con el PC. Para estos ejemplos debemos utilizar un terminal de comunicaciones configurado a 9600 baudios, como por ejemplo el minicom en Linux o el Hyperterminal en Windows.

[sci.h] Librería para enviar y recibir información por el puerto serie, a 9600 baudios.

Esta librería permite enviar caracteres y recibir caracteres, y también incluye una función para enviar cadenas.

Para usar esta librería debemos incluir el fichero sci.h

//-- Se usa la libreria de comunicaciones serie
#include "sci.h"

y en el programa principal hay que configurar el puerto serie:

//-- Configurar las comunicaciones serie
  sci_conf();



[sci-eco] Hacer eco por el puerto serie de todo lo recibido

Ejemplo que lee un caracter del puerto serie, cambia el estado del led, y lo vuelve a enviar.

Para leer carcteres del puerto serie se utiliza la función sci_read()

//-- Esperar a que llegue dato del PC
    c=sci_read();

Al llamarla, el microcontrolador se queda esperando hasta que llegue un carácter por el puerto serie. En ese momento lo devuelve la función y se almacena en la variable c.

Para enviar el caracter de vuelta se llama a sci_write(), pasando como parámetro el carácter recibido

 //-- ...y enviar de vuelta el caracter por el puerto serie
    sci_write(c);

EXPERIMENTO: Hacer que devuelva un carácter distinto del recibido. Por ejemplo que le sume 1.



[sci-cad] Enviar una cadena por el puerto serie cada vez que se recibe algo

Es un ejemplo muy parecido al sci-eco.c, pero en vez de un caracter se envia una cadena. Esto es muy útil para hacer programas que muestren un menú de opciones al usuario.

Para enviar una cadena hay que llamar a la función sci_cad():

//-- Enviar la cadena por el puerto serie
    sci_cad("Hola como estas...");

Esta función sólo es válida para enviar cadenas consantes. Si se quieren enviar cadenas localizadas en un array hay que invocar a la función sci_cad2(). En las próximas versiones del SDCC lo corregirán.




Mezclando todo

Lo bueno de tener pequeños ejemplos sueltos es que se puede aplicar la técnica de CYP para programa. Es la técnica del COPY Y PASTE :-). Tomando una pieza de aquí, otra de allá y añadiendo unas pocas cosillas más se pueden hacer programas muy interesantes.

[sci-sensor] Enviar el estado de un sensor por el puerto serie

Este ejemplo lee uno de los sensores (se puede especificar cuál cambiando la constante SENSOR) y envía su estado por el puerto serie. Si lee negro envía la letra 'N' y si lee blanco la 'B'. Es muy útil para probar los sensores.



[sci-menu] Mover el robot desde un menú de opciones que se ve en un terminal serie

Este es un ejemplo muy interesante. Al pulsar el botón de reset y comenzar a ejecutarse el programa, envía un menu por el puerto serie, que se visualiza si tenemos abierto un terminal de comunicaciones a 9600 baudios. Mediante estas opciones podremos mover el robot.

Las teclas empleadas son o,p,q,a y espacio.

EXPERIMENTO: Anadir más opciones al programa. Por ejemplo para que el robot realice giros en arco, en los que una rueda está parada y la otra avanzando.

[secuencia] El robot realiza una secuencia pregrabada

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 siga una secuencia de movimiento pregrabada, del tipo: ir hacia adelante durante 1 segundo, luego girar a la izquierda durante 0.3 segundos, luego ve hacia trás...

EXPERIMENTO: Modificar la secuencia para que describa un triangulo y que al terminar vuelva al punto inicial.




Descarga de ficheros


Ejemplos para el skybot

Fichero C

Ejecutable

HTML

Descripción

ledon.c

ledon.hex

ledon

PUERTO B: Programa “hola mundo”. Encender el led de la Skypic

ledp.c

ledp.hex

ledp

PUERTO B: Hacer que el led de la skypic parpadee

motor-on.c

motor-on.hex

motor-on

MOTORES: Activar los dos motores del robot.

motor-off.c

motor-off.hex

motor-off

MOTORES: Activar los dos motores del robot.

sensor4.c

sensor4.hex

sensor4

SENSORES: 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

sensores

SENSORES: 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

motores-sensor3

SENSORES y MOTORES: Cuando el sensor 3 lee negro el robot está parado. Si lee blanco comienza a avanzar.

delay0.h

--------------

delay0

TEMPORIZADOR 0: Rutina de pausa que usa el temporizador 0 (sin interrupciones). Para se incluido desde nuestros programas en c.

ledp2.c

ledp2.hex

ledp2

TEMPORIZADOR 0: Se usa el temporizador 0 para hacer que el led cambie de estado cada medio segundo.

sci.h

--------------

sci

PUERTO SERIE: Librería para enviar y recibir información por el puerto serie, a 9600 baudios.

sci-eco.c

sci-eco.hex

sci-eco

PUERTO SERIE: Se hace eco de todo lo recibido por el puerto serie

sci-cad.c

sci-cad.hex

sci-cad

PUERTO SERIE: Enviar una cadena por el puerto serie cuando se recibe un carácter

sci-sensor.c

sci-sensor.hex

sci-sensor

PUERTO SERIE y SENSORES: Leer el estado de un sensor y enviarlo por el puerto serie

sci-menu.c

sci-menu.hex

sci-menu

PUERTO SERIE y ROBOT: Mover el robot mediante un terminal de comunicaciones serie, a traves de un menu

secuencia.c

secuencia.hex

secuencia

ROBOT: El robot realiza una secuencia pregrabada

pic16f877.h

--------------

pic16f877

Cabecera con todas las definciones de los recursos del PIC

ejemplos1-linux.tgz

--------------

--------------

TODOS LOS EJEMPLOS para Linux. Con Makefile y proyecto para Anjuta.

ejemplos1-windows.zip

--------------

--------------

TODOS LOS EJEMPLOS para Windows. Con fichero Makefile




[Sesion 3]

Juan González

IEAROBOTICS