Guía Innobot Reto Seguidor de Línea – Depósito de Pelotas

 

Info

  • Principiantes
  • Edades: 11+

Temas STEAM

  • Tecnología
  • Ingeniería
  • Ciencia
  • Matemáticas
  • Artes

Logros y habilidades

  • Aplican  conceptos básicos de programación.
  • Afianzan  conocimientos adquiridos de funciones de programación.
  • Fortalecen  conocimientos del manejo de la interfaz Pygmalion IDE – CODE.
  • Recopilan conceptos anteriormente adquiridos.
  • Adaptan diseños mecánicos a la plataforma Innobot.
  • Desarrollan habilidades de trabajo en equipo, programación y solución de problemas.
  • Fortalecen conceptos previos de programación, como funciones, ciclos entre otros.

Recomendaciones

  • Compuerta mecánica (ya construida y unida al contenedor de pelotas).
  • Final de carrera (Microshitch).
  • Haber realizado el Tutorial Guía Innobot Reto Seguidor de Línea + pelotas – contenedor de pelotas, compuerta y microswitch
  • Realizar los cálculos correspondientes para que el robot pueda desplazarse aún teniendo un peso extra en el.
  • Los tiempos y las velocidades pueden variar de robot a robot debido a muchos factores, por ejemplo los motores, sensores, el peso, la carga de las baterías, entre otras cosas.

Introducción

En esta actividad se afianzarán las habilidades y la apropiación de conceptos y conocimientos de programación para crear un código para un robot seguidor de línea que deposite objetos en un lugar establecido teniendo en cuenta el diseño de una compuerta mecánica más un contenedor de pelotas.

Materiales

  • Pygmalion IDE
  • Computador.
  • Kit educativo de robótica Innobot.
  • Pelotas plásticas ( Tener en cuenta que las pelotas deben de tener un diámetro de 3.45 cm para que puedan salir por la compuerta.)

Desarrollo de la actividad

A continuación, encontraras el código en CODE para la programación del deposito de pelotas

Paso 1

Abrir el programa CODE.

Paso 2

Se programaran los motores M1, M2, M3, M4 con su velocidad, además de poner el rango de lectura en los sensores de línea J1 y J2; todo en el ciclo de programación inicial (void setup()).

/**********************************/
/* Company:       Pygmalion       */
/* Create Date:   22-06-2018      */
/* File Name:     Seguidor línea  */
/*                sin intersección (depositador de pelotas)*/
/* Revision:      v1.0            */
/**********************************/
void setup()
{
 
motorSpeed(M1, 50); // Velocidad motor Derecho
 
motorSpeed(M2, 50); // Velocidad motor Izquierdo
 
motorSpeed(M3, 70); // Velocidad motor derecho Compuerta
 
motorSpeed(M4, 70); // Velocidad motor derecho Compuerta
 
lineCompare(J1, 800);
 
lineCompare(J2, 800);

Paso 3

Se declara en el comando de inicio (void setup())  el puerto digital (pin 0) como ENTRADA ALTA.

 pinMode(0, INPUT_PULLUP); //Entrada digital 0 con permanencia alta
}

Paso 4

 En el ciclo infinito (void loop()) cuando el Puerto[0] (P[0]) de la tarjeta se encuentre en ALTO, es decir no ha llegado a la torre, ingresará y realizará la programación del seguidor de línea.

void loop()
{
 
if(digitalRead(0) == HIGH) //Cuando se cumpla a la condición ingresa a la lectura de la línea
 
 {

Paso 5

Programación seguidor de línea.

  if(lineRead(J1) == WHITE && lineRead(J2) == WHITE)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, FORWARD);
   }
 
   
if(lineRead(J1) == WHITE && lineRead(J2) == BLACK)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, REVERSE); 
   }
   
if(lineRead(J1) == BLACK && lineRead(J2) == WHITE)
   {
   
motorOn(M1, REVERSE);
   
motorOn(M2, FORWARD); 
   }
   
if(lineRead(J1) == BLACK && lineRead(J2) == BLACK)
   {
   
motorsOff(M1, M2); 
   }
  }

Paso 6

Cuando el Puerto[0] (P[0]) de la tarjeta se encuentre en BAJO, es decir, ha llegado a la torre apagará motores (M1,M2), activará los motores de la compuerta (M3,M4) y posteriormente los apagará.

if(digitalRead(0) == LOW)
  {
   
motorsOff(M1, M2);
   
motorOn(M3, REVERSE);
   
motorOn(M4, REVERSE);
   
delay(600);
   
motorsOff(M3, M4);

Paso 7

Cuando la función “for” se active,  sacudimos el robot para que así salga fácilmente las pelotas del contenedor.

for ( int i=0; i<15; i++)
    {
     
motorOn(M1, REVERSE);
     
motorOn(M2, FORWARD);
     
delay(100);
     
motorOn(M1, FORWARD);
     
motorOn(M2, REVERSE);
     
delay(100);
    }

Paso 8

Al acabar los pasos de la función “for”, se cerrará y apagará los motores de  la compuerta M3 y M4. Finalmente realiza el giro para devolverse al inicio.

motorOn(M3, FORWARD);
   
motorOn(M4, FORWARD);
   
delay(600);
   
motorsOff(M3, M4);
   
motorOn(M1, REVERSE);
   
motorOn(M2, REVERSE);
   
delay(500);
   
motorOn(M1, REVERSE);
   
motorOn(M2, FORWARD);
   
delay(5500);
  }
}

A continuación encontraras el código completo de un seguidor de línea más pelotas,  sin intersecciones en la pista.

    /**********************************/
/* Company:       Pygmalion       */
/* Create Date:   22-06-2018      */
/* File Name:     Seguidor línea  */
/*                sin intersección*/
/* Revision:      v1.0            */
/**********************************/
void setup()
{
 
motorSpeed(M1, 50); // Velocidad motor Derecho
  motorSpeed(M2, 50); // Velocidad motor Izquierdo
  motorSpeed(M3, 70); // Velocidad motor derecho Compuerta
  motorSpeed(M4, 70); // Velocidad motor derecho Compuerta
  lineCompare(J1, 800);
  lineCompare(J2, 800);

pinMode(0, INPUT_PULLUP); //Entrada digital 0 con permanencia alta
}

void loop()
{
 
if(digitalRead(0) == HIGH) //Cuando se cumpla a la condición ingresa a la lectura de la línea
  {
   if(lineRead(J1) == WHITE && lineRead(J2) == WHITE)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, FORWARD);
   }
 
   
if(lineRead(J1) == WHITE && lineRead(J2) == BLACK)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, REVERSE); 
   }
   
if(lineRead(J1) == BLACK && lineRead(J2) == WHITE)
   {
   
motorOn(M1, REVERSE);
   
motorOn(M2, FORWARD); 
   }
   
if(lineRead(J1) == BLACK && lineRead(J2) == BLACK)
   {
   
motorsOff(M1, M2); 
   }
  }
  
if(digitalRead(0) == LOW)
  {
   
motorsOff(M1, M2);
   
motorOn(M3, REVERSE);
   
motorOn(M4, REVERSE);
   
delay(600);
   
motorsOff(M3, M4);
   
for ( int i=0; i<15; i++)
    {
     
motorOn(M1, REVERSE);
     
motorOn(M2, FORWARD);
     
delay(100);
     
motorOn(M1, FORWARD);
     
motorOn(M2, REVERSE);
     
delay(100);
    }
   
motorOn(M3, FORWARD);
   
motorOn(M4, FORWARD);
   
delay(600);
   
motorsOff(M3, M4);
   
motorOn(M1, REVERSE);
   
motorOn(M2, REVERSE);
   
delay(500);
   
motorOn(M1, REVERSE);
   
motorOn(M2, FORWARD);
   
delay(5500);
  }
}

Variación con intersección

Se procederá a realizar la programación para un robot seguidor de línea más pelotas,  pero este contará con una intersección en su camino, lo cual varía su programación; para esta parte se añadirá un sensor de línea.

Paso 1 

Lo primero a realizar es declarar una VARIABLE la cual servirá como contador de intersecciones, posterior a esto se procede a programar la velocidad inicial de los motores M1, M2, M3 y M4 con la calibración de los sensores J1, J2 y J3. Luego se declara en el comando de inicio (void setup())  el puerto digital (pin 0) como ENTRADA ALTA.

   /*****************************************/
/* Company:       Pygmalion              */
/* Create Date:   22-06-2018             */
/* File Name:     Seguidor línea         */
/*                con intersección       */
/*                (depositador de pelotas*/
/* Revision:      v1.0                   */
/*****************************************/

int interseccion
= 0; // Contador de intersecciones
void
setup() {
 
motorSpeed(M1, 40);
 
motorSpeed(M2, 40);
 
motorSpeed(M3, 70);
 
motorSpeed(M4, 70);
 
lineCompare(J1, 800);
 
lineCompare(J2, 800);
 
lineCompare(J3, 800);
 
pinMode(0, INPUT_PULLUP);
}

Paso 2

En el ciclo infinito (void loop()) cuando el Puerto[0] (P[0]) de la tarjeta se encuentre en ALTO, es decir no ha llegado a la torre, ingresará y realizará la programación del seguidor de línea.

void loop() {
 
if(digitalRead(0) == HIGH)
  {

Paso 3

Programación seguidor de línea.

   if(lineRead(J1) == WHITE && lineRead(J2) == WHITE)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, FORWARD);
   }
 
   
if(lineRead(J1) == WHITE && lineRead(J2) == BLACK)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, REVERSE); 
   }
   
if(lineRead(J1) == BLACK && lineRead(J2) == WHITE)
   {
   
motorOn(M1, REVERSE);
   
motorOn(M2, FORWARD); 
   }

Paso 4

Mientras realiza el trayecto se encontrará la primera intersección, dando a entender que se llamará a la variable mencionada en un inicio y se dará la primer instrucción que será (respecto a la pista) el primer giro con una variación en la velocidad, posterior a el giro, que ya se haya pasado la primer intersección el robot retornará a sus velocidades iniciales.

Tener en cuenta: El contador de intersecciones se incrementará cada vez que pase por una intersección.

  if(interseccion == 0) //Cuando se encuentre la primera intersección
   {
    if(lineRead(J1) == BLACK && lineRead(J2) == BLACK) //En la primera intersección debe girar a la izquierda
    {
    motorSpeed(M1, 75); //Se aumenta las velocidades para dar el giro más rápido
    motorSpeed(M2, 75);
    motorOn(M1, FORWARD); //Los motores deben avanzar un poco para cuando gire quede colineal con la linea
    motorOn(M2, FORWARD);
   
delay(200);
   
motorOn(M1, FORWARD); //Gira a la izquierda 90 grados
    motorOn(M2, REVERSE);
   
delay(400);
    interseccion
+=1; //Se aumenta en 1 la variable intersección para saber que ya pasó la primer intersección
    }
   }
   motorSpeed(M1, 40); //Se retorna a la velocidad principal para tener la debida lectura de la línea
   motorSpeed(M2, 40);

Paso 5

Luego se programará el contador para arrojar un resultado equivalente a una segunda intersección que en este caso será el de la torre.

 if(interseccion == 1) //La segunda intersección es cuando llega a la torre
   {

Paso 6

Las instrucciones a seguir después de la segunda intersección, serán que los motores M1, M2 se ubicarán correctamente en frente de la torre.

   if(lineRead(J1) == BLACK && lineRead(J2) == BLACK)
    {
    interseccion
+=1; //Se aumenta la variable intersección para saber que ya paso de la segunda
    motorOn(M1, FORWARD); //Se mueven un poco los motores adelante para que quede el robot bien puesto en frente de la torre
    motorOn(M2, FORWARD);
   
delay(100);
    }
   }

Paso 7

El contador para arrojar un resultado equivalente a una tercera y última intersección que en este caso será el de la torre.

 

   if(interseccion == 2)//Es para la tercera y última intersección
   {

Paso 8

Al depositar las pelotas en la torre, el robot se devuelve por la pista y detectará una tercera intersección, los sensores J1 y J3 activarán una nueva variación en la velocidad, que le permitirá al robot realizar un giro a la derecha para seguir con su recorrido.

   if(lineRead(J1) == BLACK && lineRead(J3) == BLACK)// En esta sólo leerá negro los sensores derechos J1 y J3
    {
    motorSpeed(M1, 75);
    motorSpeed(M2, 75);
    motorOn(M1, REVERSE);//Se gira a la derecha
    motorOn(M2, FORWARD);
   
delay(400);
    interseccion
-=2;//Se devuelve la variable a cero para indicar que ya terminaron las intersecciones
    }
   }
   motorSpeed(M1, 40); //Variación de la velocidad a la inicial
   motorSpeed(M2, 40);
  }

Paso 9

Cuando el Puerto[0] (P[0]) de la tarjeta se encuentre en BAJO, entrará a realizar una función dada.

 

 if(digitalRead(0) == LOW)//Acciones que se ejecutarán cuando el switch se active
  {

Paso 10

Cuando el robot ha llegado a la torre apagará motores (M1,M2), activará los motores de la compuerta (M3,M4) y posteriormente los apagará.

   motorsOff(M1, M2);//Se apagan los motores de las ruedas porque el robot se debe quedar quieto
    motorOn(M3, REVERSE);//Se activan los motores de la compuerta para abrirla
    motorOn(M4, REVERSE);
   
delay(200);
   
motorsOff(M3, M4);//Se apagan los motores de la compuerta

Paso 11

Cuando la función “for” se active,  sacudimos el robot para que así salga fácilmente las pelotas del contenedor.

 for ( int i=0; i<15; i++)//Este ciclo es para que el robot se sacuda se activan los motores hacia contrarios
    {                        // durante un tiempo corto varias veces
      motorOn(M1, REVERSE);
     
motorOn(M2, FORWARD);
     
delay(75);
     
motorOn(M1, FORWARD);
     
motorOn(M2, REVERSE);
     
delay(75);
    }

Paso 12

Al finalizar el ciclo “for” se cierra la compuerta y se apagan los motores M3, M4 de la compuerta;  luego el robot se aleja de la torre realizando un giro de 180 grados para devolverse por la línea.

   motorOn(M3, FORWARD);//Se cierra la compuerta
    motorOn(M4, FORWARD);
   
delay(200);
   
motorsOff(M3, M4);//Se apagan los motores de la compuerta cuando se cierran
    motorOn(M1, REVERSE);//El robot retrocede para que cuando gire no choque con la torre
    motorOn(M2, REVERSE);
   
delay(700);
   
motorOn(M1, FORWARD);//El robot da un giro de 180 grados para devolverse por la línea
    motorOn(M2, REVERSE);
   
delay(1100);
  }
}

A continuación encontrarás el código completo de un seguidor de línea más pelota con intersecciones en la pista.

  /*****************************************/
/* Company:       Pygmalion              */
/* Create Date:   22-06-2018             */
/* File Name:     Seguidor línea         */
/*                con intersección       */
/*                (depositador de pelotas)*/
/* Revision:      v1.0                   */
/*****************************************/

int interseccion = 0; // Contador de intersecciones
void setup() {
 
motorSpeed(M1, 40);
 
motorSpeed(M2, 40);
 
motorSpeed(M3, 70);
 
motorSpeed(M4, 70);
 
lineCompare(J1, 800);
 
lineCompare(J2, 800);
 
lineCompare(J3, 800);
 
pinMode(0, INPUT_PULLUP);
}
void loop() {
 
if(digitalRead(0) == HIGH)
  {
   
if(lineRead(J1) == WHITE && lineRead(J2) == WHITE)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, FORWARD);
   }
     
if(lineRead(J1) == WHITE && lineRead(J2) == BLACK)
   {
   
motorOn(M1, FORWARD);
   
motorOn(M2, REVERSE); 
   }
   
if(lineRead(J1) == BLACK && lineRead(J2) == WHITE)
   {
   
motorOn(M1, REVERSE);
   
motorOn(M2, FORWARD); 
   }
  
if(interseccion == 0) //Cuando se encuentre la primera intersección
   {
    if(lineRead(J1) == BLACK && lineRead(J2) == BLACK) //En la primera intersección debe girar a la izquierda
    {
    motorSpeed(M1, 75); //Se aumenta las velocidades para dar el giro más rápido
    motorSpeed(M2, 75);
    motorOn(M1, FORWARD); //Los motores deben avanzar un poco para cuando gire quede colineal con la linea
    motorOn(M2, FORWARD);
   
delay(200);
   
motorOn(M1, FORWARD); //Gira a la izquierda 90 grados
    motorOn(M2, REVERSE);
   
delay(400);
    interseccion
+=1; //Se aumenta en 1 la variable intersección para saber que ya paso la primer intersección
    }
   }
   motorSpeed(M1, 40); //Se retorna a la velocidad principal para tener la debida lectura de la línea
   motorSpeed(M2, 40);
  
   if(interseccion == 1) //La segunda intersección es cuando llega a la torre
   {
    if(lineRead(J1) == BLACK && lineRead(J2) == BLACK)
    {
    interseccion
+=1; //Se aumenta la variable intersección para saber que ya paso de la segunda
    motorOn(M1, FORWARD); //Se mueven un poco los motores adelante para que quede el robot bien puesto en frente de la torre
    motorOn(M2, FORWARD);
   
delay(100);
    }
   }
  
if(interseccion == 2)//Es para la tercera y última intersección
   {
    if(lineRead(J1) == BLACK && lineRead(J3) == BLACK)// En esta solo leen negro los sensores derechos J1 y J3
    {
    motorSpeed(M1, 75);
    motorSpeed(M2, 75);
    motorOn(M1, REVERSE);//Se gira a la derecha
    motorOn(M2, FORWARD);
   
delay(400);
    interseccion
-=2;//Se devuelve la variable a cero para indicar que ya terminaron las intersecciones
    }
   }
   motorSpeed(M1, 40); //Variación de la velocidad a la inicial
   motorSpeed(M2, 40);
  }
  if(digitalRead(0) == LOW)//Acciones que se ejecutaran cuando el swicht se active
  {
    motorsOff(M1, M2);//Se apagan los motores de las ruedas porque el robot se debe quedar quieto
    motorOn(M3, REVERSE);//Se activan los motores de la compuerta para abrirla
    motorOn(M4, REVERSE);
   
delay(200);
   
motorsOff(M3, M4);//Se apagan los motores de la compuerta
    for ( int i=0; i<15; i++)//Este ciclo es para que el robot se sacuda se activan los motores hacia contrarios
    {                        // durante un tiempo corto varias veces
      motorOn(M1, REVERSE);
     
motorOn(M2, FORWARD);
     
delay(75);
     
motorOn(M1, FORWARD);
     
motorOn(M2, REVERSE);
     
delay(75);
    }
   
motorOn(M3, FORWARD);//Se cierra la compuerta
    motorOn(M4, FORWARD);
   
delay(200);
   
motorsOff(M3, M4);//Se apagan los motores de la compuerta cuando se cierran
    motorOn(M1, REVERSE);//El robot retrocede para que cuando gire no choque con la torre
    motorOn(M2, REVERSE);
   
delay(700);
   
motorOn(M1, FORWARD);//El robot da un giro de 180 grados para devolverse por la linea
    motorOn(M2, REVERSE);
   
delay(1100);
  }
}

Conceptos claves

Seguidor de Línea: Un seguidor de linea es un robot móvil que sigue una trayectoria marcada con una línea, la cual debe diferenciarse del entorno. La mayoría de veces la línea es de color negro con un fondo blanco pero esta línea también puede ser blanca con un fondo negro.
Su estructura puede variar, sin embargo, poseen ciertas partes importantes como lo son los sensores, motores, ruedas, fuentes de energía y una tarjeta de control; cada uno de estos componentes desempeñando un papel importante en el robot.

Camión volquete: También conocido como Camión de volteo, utilizado para el movimiento de tierras y para el acarreo de materiales en general. Está dotado de una caja abierta y resistente basculante que descarga por vuelco.

Tutoriales Relacionados