Busca y Sigue Luz

En este robot la parte motriz se resuelve con dos motores Rasti que realizan tracción diferencial. Como se usan orugas asociadas a cada motor, se puede evitar el uso de la "rueda loca" necesaria cuando se colocan dos ruedas. El robot apoya completamente en las dos orugas y debe tratar de balancearse para que su peso adelante-atrás sea equilibrado. En este caso, se colocaron 6 pilas recargables (logrando 6 x 1.2 V = 7.2 V) que balancean el peso de la placa Arduino con las dos shields.

Cuando al robot se lo ilumina con una linterna de mano, el robot avanza hacia esa luz. Si no la ve, empieza a buscarla moviéndose de un lado a otro, y en el momento que la encuentra avanza hacia esa luz.

A continuación se muestra el armado del robot. En las dos primeras imágenes se muestran los componentes electrónicos: Una placa Arduino UNO R3, una shield FSdirect, una shield FSmotor, y un porta-pilas para 6 pilas AA. Este porta-pilas fue armado pegando por sus bases dos portapilas de 3 unidades, uniendo el positivo con el negativo para hacer uno solo de 6 elementos, y colocándole un conector plug de 2.5 mm (centro positivo) adecuado para Arduino.

Luego se muestra la secuencia de armado del robot usando bloques plásticos Rasti. Se usan dos motores estándar Rasti y las ruedas dentadas y orugas del mismo sistema. En el caso de los motores se colocan los adaptadores de color rojo con la ficha (jack) 6P2C que irán conectados a los puertos de color rojo de la FSmotor. Una particularidad a tener en cuenta es que por la forma en que se colocaron los motores y la salida a ejes usada (Nº 2) es necesario conectar ambos motores en forma inversa a la normal, es decir con el cable blanco en el borne negativo y el cable azul en el borne postivo.

En las dos últimas imágenes se muestra la colocación de un puente con el sensor de luz LDR encima. El sensor es de color azul y se conecta a un puerto del mismo color en la shield FSdirect.

PROGRAMA

El programa en el lazo principal lee el valor del sensor LDR. Cuando ese valor supera un cierto umbral el robot avanza hacia adelante. Ese umbral debe determinarse en cada caso, pues depende del nivel de iluminación ambiente y de la potencia de la linterna o luz que debe seguir el robot. Si al leer el LDR no se supera el umbral, se entra en una secuencia de búsqueda de la luz, que en este caso se implementó como giros hacia la izquierda y hacia la derecha, con la duración de los giros cada vez mayor. Si busca mas de 5 veces sin encontrar la luz, entonces se detiene completamente, pero sigue activo leyendo el sensor de luz LDR.

PROGRAMA

/*

Actividad FreeSensors: Busca y sigue una luz

Utiliza dos motores Rasti de 6 Volt conectados a la shield

FSmotor y un sensor LDR conectado a la entrada analogica

AI1 de la shield FSdirect.

*/

#include <FreeSensors.h>

FSdirect sh1;

FSmotor sh2;

int sensor;

// Este umbral es superado por una linterna apuntada

// directamente a la LDR aun con luz ambiente diurna

int umbral = 700;

// M1 es el de la derecha, M2 es el de la izquierda

// vistos desde arriba en la direccion de avance

byte velocM1 = 255;

byte velocM2 = 255;

byte velocM1b = 200;

byte velocM2b = 200;

boolean andando;

boolean buscando;

boolean direccion;

int conta1;

int conta2;

int duracion;

void setup() {

sh1.begin();

sh2.begin(PCF_001);

andando = false;

buscando = false;

conta1 = 0;

conta2 = 0;

duracion = 100;

}

void loop() {

sensor = sh1.analogRead(AI1);

if (sensor>umbral) {

andando = true;

buscando = false;

conta2 = 0;

} else {

andando = false;

if (conta1>duracion) {

direccion = !direccion;

conta1 = 0;

conta2++;

}

if (conta2>=2) duracion = 150;

if (conta2>=4) duracion = 200;

if (conta2<6) {

buscando = true;

} else {

buscando = false;

}

}

if (andando) {

sh2.m1.forward(velocM1);

sh2.m2.forward(velocM2);

} else if (buscando) {

if (direccion) {

// giramos hacia la izquierda

sh2.m1.forward(velocM1b);

sh2.m2.backward(velocM2b);

} else {

// giramos hacia la derecha

sh2.m1.backward(velocM1b);

sh2.m2.forward(velocM2b);

}

conta1++;

} else {

sh2.m1.stop();

sh2.m2.stop();

}

delay(10);

}