Seguidor de Lineas

El robot seguidor de lineas mecánicamente consiste en una estructura con dos ruedas para realizar tracción diferencial, y una rueda de giro libre (rueda loca) que sirve solo como apoyo. Para seguir una linea (negra sobre un piso blanco) se detecta el rebote-infrarrojo a corta distancia del piso. Pueden usarse distintas cantidad de sensores infrarrojos, dando lugar a distintos programaciones del robot, en este caso se usaron 3 sensores infrarrojos.

El armado se realizó con bloques plásticos Rasti, usando dos motores DC y cajas reductoras. Se hizo de forma desmontable, para poder reemplazar fácilmente las pilas. Se usaron 5 pilas recargables de 1.2 V, que juntas nos dan 6 V cuando están plenamente cargadas. En la Fig. 1 se puede ver el armazón con los dos motores y ruedas, la caja portapilas realizadas también con ladrillos, y el conjunto de una Arduino UNO R3 con dos shields encima: una Direct y una Motor.

En la Fig. 2 se muestra el detalle de los tres sensores infrarrojos (en bloques azules) y delante de los mismos se colocó un led blanco que se usó para probar iluminar la pista para mejorar la respuesta ante distintas condiciones de iluminación ambiente. La utilidad de ese led blanco es dependiente del grado de iluminación ambiente. En la parte trasera se puede ver el apoyo utilizado, que finalmente fue un tornillo de cabeza esférica que se comportó mejor que las ruedas locas anteriormente usadas.

En la Fig. 3 se puede ver el conjunto con el porta-pilas colocado, y en la Fig. 4 el conjunto completo armado listo para funcionar. El sensor de toque de la parte posterior sirve para arrancar y para pausar el movimiento de los motores.

Finalmente en la Fig. 5 se puede ver al robot al comienzo de la vuelta, y en la Fig. 6 trabajando. El led verde en el frente se programó para que se encendiera cuando ambas ruedas iban hacia adelante, y que se apagara en todos los otros casos.

Fig. 1

Fig. 2

Fig. 3

Fig. 5

Fig. 6

Fig. 4

PROGRAMA

PROGRAMA

/*

Actividad FreeSensors: Seguidor de linea

Usa tres módulos de rebote infrarrojo (TCRT5000) y 2 motores Rasti 6V conectados

a una shield FSmotor (pueden tener distintas velocidades relativas).

La entrada de boton sirve para detener y rearrancar el robot, un led verde indica

cuando se mueve hacia adelante, y un led blanco ilumina el camino cerca de los

sensores.

*/

#include <FreeSensors.h>

FSdirect P1;

FSmotor P2;

// Lecturas analogicas sensores infrarrojos

int sensDer;

int sensCen;

int sensIzq;

int umbral = 800;

// Variables booleanas sensores infrarrojos

boolean blancoDer;

boolean negroCen;

boolean blancoIzq;

// Variables auxiliares

boolean boton;

boolean parado;

boolean inicio;

boolean final;

boolean retrocediendo;

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

byte velocM1 = 200;

byte velocM2 = 200;

void setup() {

P1.begin();

P1.pinMode(DIO1, OUTPUT); // LED verde

P1.pinMode(DIO2, OUTPUT); // LED blanco

P1.pinMode(DIO4, INPUT); // Boton

P1.digitalWrite(DIO1, LOW); // LED verde empieza apagado

P1.digitalWrite(DIO2, HIGH); // LED blanco empieza y queda prendido

P2.begin(PCF_010);

P2.m1.stop();

P2.m2.stop();

parado = true;

inicio = true;

final = false;

retrocediendo = false;

}

void loop() {

sensDer = P1.analogRead(AI1);

delay(10);

sensCen = P1.analogRead(AI2);

delay(10);

sensIzq = P1.analogRead(AI3);

delay(10);

blancoDer = sensDer > umbral;

negroCen = sensCen < umbral;

blancoIzq = sensIzq > umbral;

boton = (P1.digitalRead(DIO4)==HIGH);

if (boton) {

delay(300);

if (parado) {

parado = false;

} else {

P2.m1.stop();

P2.m2.stop();

P1.digitalWrite(DIO1, LOW);

parado = true;

}

}

if (parado) return;

if (retrocediendo) {

delay(750);

P2.m1.stop();

P2.m2.stop();

retrocediendo = false;

}

if (!blancoIzq && negroCen && !blancoDer) {

if (inicio) {

// Todos en negro sobre la linea de inicio: Arrancar

P2.m1.forward(velocM1);

P2.m2.forward(velocM2);

P1.digitalWrite(DIO1, HIGH);

delay(1000);

inicio = false;

} else {

// Todos en negro sobre la linea de final: Detenerse

if (final) {

P2.m1.stop();

P2.m2.stop();

} else {

delay(200);

final = true;

}

}

}

if (blancoIzq && !negroCen && blancoDer) {

// Todos en blanco: Retroceder 0.75 seg. y detenerse

if (!retrocediendo) {

P2.m1.backward(150);

P2.m2.backward(150);

retrocediendo = true;

}

P1.digitalWrite(DIO1, LOW);

inicio = false;

final = false;

}

if (blancoIzq && negroCen && blancoDer) {

// Sobre la linea: Continuar

P2.m1.forward(velocM1);

P2.m2.forward(velocM2);

P1.digitalWrite(DIO1, HIGH);

inicio = false;

final = false;

}

if (!blancoIzq && !negroCen && blancoDer) {

// Se sale para la derecha: girar a la izquierda

P2.m1.forward(velocM1);

P2.m2.backward(velocM2);

P1.digitalWrite(DIO1, LOW);

inicio = false;

final = false;

}

if (blancoIzq && !negroCen && !blancoDer) {

// Se sale para la izquierda: girar a la derecha

P2.m1.backward(velocM1);

P2.m2.forward(velocM2);

P1.digitalWrite(DIO1, LOW);

inicio = false;

final = false;

}

}