Está en la página 1de 41

Robot C2

Plataforma robótica Multipropósito

Guía de usuario

Introducción
C3 es un robot autónomo de morforlogía móvil, diseñado como plataforma
multipropósito para resolución de los principales retos de la mini-robótica. Se trata de un robot
de tipo diferencial, su tracción basa en dos motores de corriente directa, alimentado por
un paquete de baterías de 9 Voltios.

C3 utiliza un microcontrolador de la marca Atmel modelo Atmega328, con firmware de


Arduino, lo cual facilita su programación.
Advertencias de seguridad y precauciones de uso

C3 no es un juguete. Puede ser usado por niños y jóvenes bajo la supervisión y ayuda de un
adulto. El uso o abuso del producto es responsabilidad del usuario final. El distribuidor no se
hace responsable por daños o lesiones que éste pueda causar durante su uso.
Este producto no está diseñado para jugar, no debe usarse fuera de las condiciones de
trabajo. A continuación se indican las precauciones:
• Antes de comenzar por favor lea cuidadosamente el manual.
• Utiliza baterías alcalinas o recargables. En el caso de las alcalinas asegúrate que sean
nuevas, y si compras recargables verifica que tengan suficiente carga, de lo contradio al
programar lo puedes inutilizar para siempre.
• Condiciones de trabajo:
◦ superficie lisa, de preferencia melamina,
◦ interiores con luz controlada.
• No colocar la tarjeta de circuito impreso (PCB) sobre superficies metálicas.
• El robot C3 esta ensamblado y soldado con piezas que contienen plomo y estaño, por lo
cual es necesario lavarse las manos después de manipularlo.
• Los componentes del robot están expuestos, por lo que es importante no tocarlo con las
manos mientras está en funcionamiento. Si nuestras manos están mojadas puede
causarse un corto circuito y dañar uno o varios componentes.

Primeros pasos de C3

¿Qué necesitas?
• 6 baterías tipo AA Utilice de preferencia baterías alcalinas o recargables. Si trabajará
durante tiempos prolongados con el robot, le recomendamos usar baterías recargables
de Niquel-Metal Hidruro, NiMH. No olvide comprar el cargador correspondiente.
• Cable A – B USB. C3 no requiere un programador externo, todo el hardware
electrónico ya se incluye en el robot, pero para la comunicación entre la computadora y
el robot se requiere dicho cable.
• Computadora. Necesitas una computadora para programar el robot. Para ello se utiliza la
interfaz de programación de Arduino, plataforma libre, que funciona en cualquiera de
los siguientes sistemas operativos:
◦ Windows
◦ Mac
◦ Linux
• Material para pruebas. Es necesario que tenga a mano papel, cartulinas, cartoncillo y
cinta aislante negra o blanca, para improvisar pistas y probar el robot.
Conoce más de C3

Figura 1. Vista frontal de C3

C3 es un robot de morfología móvil de tipo diferencial, es decir se desplaza por medio de dos
ruedas con dos motores, uno para cada una. El cerebro de esta robot es un Arduino Uno R3, y
está encargado de procesar la información que le proveen los sensores para realizar
correcciónes a través de los motores, bajo el esquema básico de control.

Hardware de C3
En la figura 1 se muestra el hardware del robot. Observe que se cuenta con varios componentes
y dispositivos electrónicos. ¿Reconoce alguno?, a continuación se explican brevemente.
• Sensores reflectivos de contraste, son los encargados de percibir la información del
ambiente, en este caso el contraste, la diferencia entre o blanco y lo negro, lo que no
brilloso y lo opaco. Este dispositivo se compone de dos partes: emisor y receptor. Tanto
el primero como el segundo trabajan en el rango infrarrojo de la luz. Ésta no es
perceptible por el ojo humano, pero con ayuda de una cámara digital se observa.
• Sensores de contacto, a través de ellos se detectan obtáculos pequeños cercanos al piso,
con una altura mínima de 1.5 centímetros.
• LEDs. Diodos emisores de luz por sus siglas en inglés, son dispositivos que emiten una
luz al circular una corriente por sus terminales. C3 se usan como indicadores de
encendido.
• Driver para motor. Basado en un circuito integrado de Puente H, es el que proveen de
potencia a los motores, siendo la interfaz entre el microcontrolador y el motor.
• Botones. Son interruptores de encendido al contacto. El robot cuenta con uno para
reiniciar el microcontrolador (arduino)
• Motorreductores. Son motores de corriente directa (CD, como el de las baterías), con
una caja de engranes adaptada. Los usados en A3 tienen una reducción de 48:1, esto es,
por cada 48 vueltas que gire el motor, el eje del reductor girará 1 vuelta. De este modo
se incrementa el torque, fuerza, y se reduce la velocidad.
• Batería. Es la que provee de energía eléctrica a todo el robot, arduino, sensores, LEDs,
motores, pulsadores. En el caso de C3 se trata de 6 baterías tipo “AA”.

Arduino UNO R3
Es una placa basada en el mirocontrolador Atmega328 que generalmente se usa para hacer
prototipo.

Especificaciones
• Microcontrolador: Atmega328.
• Tensión de operación (nivel lógico): 5 Voltios.
• Tensión de entrada (recomendada): 7-12 Voltios.
• Tensión de entrada (límites): 6-20 Voltios.
• Pines E/S digitales: 14 (de los cuales 6 proveen de salida PWM).
• Entradas Analógicas: 8
• Corriente máxima por cada PIN de Entrada/Salida: 40mA
• Memoria Flash: 32KB.
• SRAM: 2KB
• EEPROM: 1KB.
• Dimensiones: 18.5 mm x 23.2 mm.

Alimentación
El Arduin puede ser alimentado usando el cable USB B , con una fuente externa no regulada de
6-20V, o con una fuente externa regulada de 5V. La fuente de alimentación es seleccionada
automáticamente a aquella con mayor tensión.

Memoria
El ATmega168 posee 16KB de memoria flash para almacenar el codigo (de los cuales 2KB son
usados por el bootloader); el ATmega 328 posee 32KB, (también con 2 KB usados por
el bootloader). El Atmega168 posee 1KB de SRAM y 512 bytes de EEPROM (la cual puede ser
leida y escrita con la librería EEPROM); el ATmega328 posee 2 KB de SRAM y 1KB de EEPROM.
Entrada y Salida
Cada uno de los 14 pines digitales del Nano puede ser usado como entrada o salida, usando las
funciones pinMode(), digitalWrite(), y digitalRead(). Operan a 5 voltios. Cada pin puede proveer
o recibir un máximo de 40mA y poseen una resistencia de pull-up (desconectada por defecto)
de 20 a 50 kOhms. Además algunos pines poseen funciones especializadas:
• Serial: 0 (RX) y 1 (TX). (RX) usado para recibir y (TX)usado para transmitir datos TTL vía
serie. Estos pines están conectados a los pines correspondientes del chip USB-a-TTL de
FTDI.
• Interrupciones Externas: pines 2 y 3. Estos pines pueden ser configurados para activar
una interrupción por paso a nivel bajo, por flanco de bajada o flanco de subida, o por un
cambio de valor. Mira la función attachInterrupt() para más detalles.
• PWM: pines 3, 5, 6, 9, 10, y 11. Proveen de una salida PWM de 8-bits cuando se usa la
función analogWrite().
• SPI: pines 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Estos pines soportan la comunicación
SPI, la cual, a pesar de poseer el hardware, no está actualmente soportada en el
lenguaje Arduino.
• LED: Pin 13. Existe un LED conectado al pin digital 13. Cuando el pin se encuentra en
nivel alto, el LED está encendido, cuando el pin está a nivel bajo, el LED estará apagado.
El Nano posee 8 entradas analógicas, cada unas de ellas provee de 10 bits de resolución (1024
valores diferentes). Por defecto miden entre 5 voltios y masa, sin embargo es posible cambiar el
rango superior usando la función analogReference(). También, algunos de estos pines poseen
funciones especiales:
• I2C: Pines 4 (SDA) y 5 (SCL). Soporta comunicación I2C (TWI) usando la librería Wire
(documentación en la web Wiring).
Hay algunos otros pines en la placa:
• AREF. Tensión de referencia por las entradas analógicas. Se configura con la función
analogReference().
• Reset. Pon esta linea a nivel bajo para resetear el microcontrolador. Normalmente se usa
para añadir un botón de reset que mantiene a nivel alto el pin reset mientras no es
pulsado.
Programando en Arduino
Para programa el robot luchador de sumo es necesario contar con el entorno de programación
de Arduino. Si aún no lo tiene lo puede descargar en: www.arduino.cc en la sección de
descargas. Es recomendable que la versión de arduino que descargue sea igual o posterior a la
1.0.1

Figura 5. Captura de pantalla de entorno de programación Arduino versión 1.0.1

Componentes de Arduino IDE

Figura 6. Icono “Verificar”


• Verificar. inspecciona el código generado, marca errores y posibles soluciones.
Figura 7. Ícono: “Cargar”
• Cargar: Cuando se presiona este botón se compila y ensambla el código contenido en la
ventana y se descarga a la tarjeta electrónica de Arduino. Este proceso puede tardar
algunos segundos o tal vez un para de minutos.

Figura 8. Ícono: “Nuevo”.


• Nuevo: crea un nuevo “sketch” en blanco.

Figura 9. Ícono: “Abrir”.


• Abrir: abre un “sketch”, código, ya existente.

Figura 10. Ícono: “Guardar”.


• Guardar: salva las modificaciones realizadas en el código.

Figura 11. Ícono: “Monitor Serial”.


• Monitor Serial: abre la aplicación de monitor serial, que puede servir para diferentes
propósitos.

Referencias del lenguaje


Los programas hechos con Arduino se dividen en tres partes principales:
• Estructura,
• valores (variables y constantes),
• funciones.
El lenguaje de programación Arduino se basa en C/C++.

Estructuras
Las dos estructuras principales son las siguientes:
• setup(), es la estructura donde se configura las entradas, salidas y los módulos. Es
llamado también como “inicialización”. Lo contenido en esta estructura se ejecuta
sólamente una vez al inicio del programa.
• loop(), es la estructura donde se escribe el código, y se repetirá infintas veces.

Valores
Constantes
• HIGH, alto,
• LOW, bajo,
• INPUT, entrada,
• OUTPUT, salida,
• True, verdadero,
• false, falso,

Variables:
• boolean, booleando,
• char, carácter,
• byte, 8 bits
• int, entero,
• unsigned int, entero sin signo,
• long, entero de 32 bits,
• unsigned long, entero 32 bits sin signo,
• float, punto flotante.

Funciones
• pinMode(), configura si el pin digital será salida o entrada,
• digitalWrite(), si el pin ha sido configurado como salida digital, su voltaje de salida será 0
o 5V.
• digitalRead(), lectura del valor digital del pin especificado,
• analogRead(), lectura del valor analógico del pin especificado,
• analogWrite(), configura la modulación por anchura de pulso de un pin (PWM),
• delay(), pausa en milisegundos.
• Serial, librería incluida para el uso y configuración del módulo serial.

Revisa la referencia del lenguaje de arduino para aprender más acerca de las estructuras,
variables y funciones de Arduino.
El primer programa en Arduino para C3
Un sencillo programa de demostración está disponible en los ejemplos de Arduino,
“Archivo/Ejemplos/01.Basics/Blink”.

Figura 12. El primer programa en Arduino


Este sencillo programa prende y apaga un LED, colocado en la patilla, pin 13.
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
*/
// Pin 13 has an LED connected on most Arduino boards.
int led = 13;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

Abierto el programa de ejemplo es necesario seleccionar la tarjeta correspondiente, en el caso


del robot seguidor de línea, se trata de un Arduino Nano Atmega328, para ello diríjase al menú
Herramientas/Tarjeta/Arduino Nano w/Atmega328.

Figura 13. Selección de tarjeta Arduino Nano Arduino Uno

Ahora se verificará que el código escrito sea correcto, presione el ícono verificar:
Lo que hará esta función será “traducir” todo lo codificado a un “idioma” que entienda el micro-
controlador. Observe los avisos y errores de salida mostrados. Si el programa se compila
correctamente, el mensaje de salida deberá ser como se muestra en la figura:

Figura14. Mensajes de salida


Una vez compilado y verificado el programa, y en vista que no existen errores o advertencias, se
procede a cargar el programa a la tarjeta de Arduino. Para ello antes es importante seleccionar
el puerto de comunicación serial “COM” correcto. Para ello se puede hacer lo siguiente:
• Abra el administrador de dispositivos,
• En la pestaña “Puertos (COM y LPT)”, verifique el puerto en el cual está ubicado el
Arduino. Generalmente tiene el nombre de “USB Serail Port”.

Figura 15. Verificación del puerto COM del Arduino


Una vez identificado, se selecciona en el IDE, Herramientas/Puerto serial/COMx

Figura 16. Selección del Puerto Serial


Cargue el programa a la tarjeta de Arduino presionando el ícono de cargar. Esta acción puede
tardar algunos segundos.

Figura 17. Carga de programa a tarjeta de Arduino

Si la carga fue exitosa se desplegará el siguiente mensaje:

Figura 18. Carga Exitosa


Ejemplos y proyectos
Ahora que sabe como compilar y cargar un prorama a la tarjeta de Arduino es tiempo de
aprender a diseñar y codificar programas más complicados. Comenzará con los más sencillos.

Ejemplo 1: Accionar de motores.


C3 cuenta con dos motores y dos ruedas para realizar sus movimientos. Los motores son
controlados por el arduino (microcontrolador) a través de un circuito integrado de potencia
denomidado inversor o puente H. Éste se encarga de proveer de corriente al motor e invertir el
sentido de giro del mismo.
Para cada motor del robot se tienen dos pines de salida para el control. El primer pin es para el
control de su dirección, es decir si gira para adelante o para atrás. El segundo sirve para indicar
la velocidad del motor y es llamado PWM.
En la siguiente tabla se muestra el funcionar del motor de acuerdo con los pines de control.
Direción PWM Movimiento de motor
HIGH HIGH Adelante
LOW HIGH Atrás
HIGH/LOW LOW Detenido

Teniendo encuenta la tabla anterior podemos escribir un código para que el robot se dirija hacia
adelante y luego hacia atrás. Se propone a continuación una forma de realizarlo.

/*
Prueba de Motores con control por anchura de pulso (PWM)
El siguiente programa es para hacer una prueba del movimiento del robot.
*/

//Alias para pines de control de Motor Derecho


int pwmtoder = 10; //Pin de velocidad
int mtoder = 12; //Pin de dirección
int velocidadDer = 127; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Alias para pines de control de Motor Izquierdo


int pwmtoizq = 11; //Pin de velocidad
int mtoizq = 13; //Pin de dirección
int velocidadIzq = 127; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo
//Configuración de Módulos y I/Os
void setup() {
//Se declaran como salida los pines de control de los motores
pinMode(pwmtoizq, OUTPUT);
pinMode(mtoizq, OUTPUT);

pinMode(pwmtoder, OUTPUT);
pinMode(mtoder, OUTPUT);

//Se pone en 0 la velocidad del motor, lo tanto el robot estará detenido durante 1 segundo
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
delay(1000); //Pausa o periodo de inactividad dado en miliseguntos (1000 = 1 segundo)
}

//Ciclo principal
void loop()
{
/*Recuerde que las variables velocidadDer y velocidadIzq indican la velocidad del motor,
y de acuerdo a la declaración del valor de las variables se encuentra en el valor 127,
es decir al 50% de la velocidad máxima del motor*/
analogWrite(pwmtoder, velocidadDer);
analogWrite(pwmtoizq, velocidadIzq);

/*Recuerde que si el pin de dirección derecho, mtoder,está en alto, HIGH, el motor rodará
hacia adelante. Por lo consiguiente si está en bajo, LOW, lo hará hacia atrás.
Si el pin de dirección izquierdo, mtoder, está en alto, HIGH, el motor rodará hacia
adelante. Por lo consiguiente si está en bajo, LOW, lo hará hacia atrás.
Entonces... si se ponen en alto tanto el mtoder como el mtoizq el motor se desplazará hacia
adelante*/
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, HIGH);
delay(1000); //Tiempo por el cual el robot irá hacia adelante (milisegundos)

/*Para hacer que el robot se detenga basta con poner la velocidad de los dos motores en
0, cero, no importando el sentido de giro de los motores.*/
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
delay(1000);//Tiempo por el cual el robot irá hacia adelante (milisegundos)

/*Para hacer que el robot se desplace hacia atrás es necesario poner la velocidad del motor
en la constante, variable velocidadDer y velocidadIzq, los indicadores de dirección mtoder y
mtoizq en bajo*/
analogWrite(pwmtoder, velocidadDer);
analogWrite(pwmtoizq, velocidadIzq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, LOW);
delay(1000); //Tiempo por el cual el robot irá hacia adelante (milisegundos)

/*Para hacer que el robot se detenga basta con poner la velocidad de los dos motores en
0, cero, no importando el sentido de giro de los motores.*/
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
delay(1000); //Tiempo por el cual el robot irá hacia adelante (milisegundos)
}
//Fin del programa

Ejercicio 1:
Desarrolle un código para hacer la siguiente secuencia de movimientos.
• Adelante,
• detenido,
• atrás,
• detenido,
• izquierda,
• detenido,
• derecha,
• detenido.

Tome como referencia la siguiente tabla de estados.


mtoder velocidadDer mtoizq velocidadIzq Movimiento
HIGH 127 HIGH 127 Adelante
LOW 0 LOW 0 Atrás
HIGH/LOW* 0 HIGH 127 Derecha
HIGH 127 HIGH/LOW* 0 Izquierda
HIGH/LOW* 0 HIGH/LOW* 0 Detenido

*HIGH/LOW, no importa el estado, ya que la velocidad es cero por lo consiguiente el motor se


detiene.
Ejemplo 2: Movimientos con funciones.
En el ejemplo anterior se realizaron los movimientos básicos del robot. En éste se hace
básicamente lo mismo con la diferencia de que se usan funciones. Éstas ya están creadas y
representan los movimientos: adelante, atras, drecha, izquierda, giroderecha, giroizquierda.
Para usarlas sólamente hay que llamarlas cuando se requieran.
Observe el siguiente código para entender el funcionamiento de las funciones ya creadas.

/*
Prueba de Motores con control por anchura de pulso (PWM)
El siguiente programa es para hacer una prueba del movimiento del robot.
Se tiene creado funciones básicas.
*/

//Alias para pines de control de Motor Derecho


int pwmtoder = 10;
int mtoder = 12;
int pwmvalder = 127; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Alias para pines de control de Motor Izquierdo


int pwmtoizq = 11;
int mtoizq = 13;
int pwmvalizq = 127; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Funciones
void adelante();
void atras();
void giroderecha();
void giroizquierda();
void derecha();
void izquierda();
void detenido();

//Configuración de Módulos y IO
void setup() {
pinMode(pwmtoizq, OUTPUT);
pinMode(mtoizq, OUTPUT);

pinMode(pwmtoder, OUTPUT);
pinMode(mtoder, OUTPUT);

digitalWrite(pwmtoizq, LOW);
digitalWrite(mtoizq, LOW);

digitalWrite(pwmtoder, LOW);
digitalWrite(mtoder, LOW);
delay(1000);
}

//Ciclo principal
void loop()
{
adelante();
delay(1000);
detenido();
delay(1000);
atras();
delay(1000);
detenido();
delay(1000);
derecha();
delay(1000);
izquierda();
delay(1000);
}

void adelante()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, HIGH);
}

void atras()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, LOW);
}

void giroderecha()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void derecha()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void giroizquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void izquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, 0);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void detenido()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
}
Ejemplo 3: Detección de obstáculos (sensor de contacto).

Fig. Detección de obstáculos pequeños

El Robot C3 tiene 2 sensores de contacto, para la detección de obstáculos pequeños. Estos


sensores son de tipo digital, solamente entregan dos valores, entregan 5 voltios, HIGH,
cuando no se encuentran presionados. En el momento que se encuentran presionados pasan de
alto, HIGH, a bajo a 0 Voltios.
Para obtener la lectura de los sensores es necesario utilizar la funcion “digitalRead”, la cual
regresa el estado del sensor.
A continuación se propone un código para realizar que el robot choque con los obstáculos y
luego los evada.

//Alias para pines de control de Motor Derecho


int pwmtoder = 10;
int mtoder = 12;
int pwmvalder = 127; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Alias para pines de control de Motor Izquierdo


int pwmtoizq = 11;
int mtoizq = 13;
int pwmvalizq = 127; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Funciones
void adelante();
void atras();
void giroderecha();
void giroizquierda();
void derecha();
void izquierda();
void detenido();

// the setup routine runs once when you press reset:


void setup() {
pinMode(2, INPUT);
pinMode(3, INPUT);

pinMode(pwmtoizq, OUTPUT);
pinMode(mtoizq, OUTPUT);

pinMode(pwmtoder, OUTPUT);
pinMode(mtoder, OUTPUT);

digitalWrite(pwmtoizq, LOW);
digitalWrite(mtoizq, LOW);

digitalWrite(pwmtoder, LOW);
digitalWrite(mtoder, LOW);
delay(1000);

// the loop routine runs over and over again forever:


void loop() {
// read the input on analog pin 0:
int sensorValue0 = digitalRead(2);
int sensorValue1 = digitalRead(3);
// print out the value you read:
if(sensorValue0 == HIGH && sensorValue1 == HIGH )
{
adelante();
}

if(sensorValue0 == HIGH && sensorValue1 == LOW )


{
atras();
delay(200);
derecha();
delay(1000);
}

if(sensorValue0 == LOW && sensorValue1 == HIGH)


{
atras();
delay(200);
izquierda();
delay(1000);
}
}

void adelante()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, HIGH);
}

void atras()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, LOW);
}

void giroderecha()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void derecha()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void giroizquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void izquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, 0);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void detenido()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
}
Ejemplo 4: Detección de obstáculos (sensor proximidad)

Figura . Detección de obstáculos grandes.

Para detectar objetos de tamaño grande C3 cuenta con 3 sensores de tipo infrarrojo
reflectivo. Esto es que funcionan emitiendo una luz infrarroja, a través de un LED, y si un objeto
se encuentra próximo se refleja y se recibe por medio de un fototransistor. De tal modo que con
este tipo de sensores no es necesario tener un contacto con el objeto para que pueda ser
detectado.
Los estados del sensor son los siguientes:
Estado Valor entregado
Obstáculo cercano LOW
Libre HIGH

Para realizar una prueba de los sensores de proximidad realice un programa en el cual use la
comunicación serial entre el arduino y la computadora. A continuación se propone el código
para realizar esta actividad.

// Inicio de programa
void setup() {
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);

pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}

// the loop routine runs over and over again forever:


void loop() {
// read the input on analog pin 0:
int sensorValue0 = digitalRead(4);
int sensorValue1 = digitalRead(5);
int sensorValue2 = digitalRead(6);
// print out the value you read:
if(sensorValue0 == HIGH)
{
Serial.print("Sensor izquierdo: ");
Serial.println("libre");
}
else
{
Serial.print("Sensor izquierdo: ");
Serial.println("Objeto cercano");
}

if(sensorValue1 == HIGH)
{
Serial.print("Sensor centro: ");
Serial.println("libre");
}
else
{
Serial.print("Sensor centro: ");
Serial.println("Objeto cercano");
}
if(sensorValue2 == HIGH)
{
Serial.print("Sensor derecho: ");
Serial.println("libre");
}
else
{
Serial.print("Sensor derecho: ");
Serial.println("objeto cercano");
}
delay(1000); // delay in between reads for stability
}

Verifique y cargue en la tarjeta arduino del robot el código. Enseguida abra el monitor serial y
visualice los resultados.

Figura. Visualización de datos en monitos serial.


Ejemplo 5: Visualización de valor de sensores en monitor serial
La tarjeta de C3 cuenta con 4 sensores del tipo reflectivo infrarrojo. Este tipo está
compuesto de dos componentes un emisor y un receptor. El primero es un LED infrarrojo, luz
que no podemos ver los ojos; el segundo es un fototransistor con filtro de luz de día.
El funcionamiento es el siguiente:

Figura 21. Sensor Reflectivo sobre superficie reflejante.

Cuando el LED infrarrojo se encuentre emitiendo luz, si la superfice es reflejante, por ejemplo
blanca, se refleja una cantidad de luz que es percebida por el fototransistor, que convierte la
señal luminosa en voltaje, permite un flujo de corriente entre sus terminales y por la
configuración de carga de emisor se obtiene un valor.

Figura 22. Sensor Reflectivo sobre superficie opaca

Por lo contrario si el la superficie es opaca, por ejemplo negra, se refleja poca luz, la cual es
percibida por el fototransisto, pero se genera poca corriente en sus terminales y por
consiguiente poco voltaje.
Este sensor no puede servir como un interruptor sin contacto, y se usa comúnmente en muchos
procesos de la industra y cotidianos, tal es caso de las llaves automáticas de agua usadas en los
baños públicos. La intensión es que cuando coloque su dedo frente al sensor este active el LED.
Una de las grandes ventajas de las tarjetas de Arduino es su simplicidad para establecer
conexión con una computadora. Esto se realiza gracias al convertivor USB a serial incluido en la
tarjeta. A demás el entorno de programación cuenta con una aplicación, monitor serial, que
sirve para visualizar, recibir y enviar información.
El siguiente programa obtiene el valor de los sensores reflectivos analógico, los cuantifica y los
despliega. La cuantificación es el proceso por el cual se le asigna un valor en bits a una señal.
Los convertidores CAD, Analógico a Decimal, cuantifican las señales, es decir entregan un valor
en número dependiendo de la resolución que posean. En el caso del microcontrolador que se
usa, Atmega328, la resolución es de 10 bits, es decir 1024 divisiones en la escala del 0 al 5V. Una
buen analogía es la siguiente: Suponga que tiene una escalera de 5 metros con 1024 escalones,
cada escalón le hará subir 0.0048 metros. Si otra persona le indica que tiene que pintar una
linea a 2.5 metros del piso, ¿Cuántos escalones tendrá que subir?, esto puede resolverse por
una simple regla de tres:
2.5metros∗1024escalones
Dato= =512escalones
5metros

A grosso modo eso es lo que hace un convertidor Analógico a Digital, convierte un voltaje en un
dato que pueda manipular.
Para realizar la calibración los sensores o para obtener información de ellos se puede realizar un
programa que muestre los datos en el monitor serial. A continuación se propone el código para
realizar esta tarea.

/*--------------------------------Inicio del código--------------------------------*/


void setup() {

pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}

// the loop routine runs over and over again forever:


void loop() {
// read the input on analog pin 0:
int sensorValue1 = analogRead(1);
int sensorValue2 = analogRead(2);
// int sensorValue2 = digitalRead(6);
// print out the value you read:

Serial.print("Sensor centro derecho: ");


Serial.println(sensorValue1);
Serial.print("Sensor centro izquierdo: ");
Serial.println(sensorValue2);
delay(1000); // delay in between reads for stability
}
/*--------------------------------Fin del código--------------------------------*/
Funcionamiento
Una vez compilado y descargado el código se deberá abrir el monitor serial dentro del IDE de
Arduino para ver los datos.

Figura 26. Recepción de datos por el monitor Serial

En la figura se puede observar los valores obtenidos sobre una superficie opaca, en la parte
superior, y en la posterior sobre una superficie reflejante. Estos datos son importantes para la
determinación del umbral para la detección del borde del dohyo.
Ejercicio
Desarrolle el código para un programa que muestre por el monitor serial el valor de los sensores
en Voltaje.

Sugerencia
Para obtener el valor en voltaje puede emplear la siguiente fórmula:
ValorObtenidoCAD∗5Voltios
Voltaje=
1024
Si en el ejemplo anterior se obtuvo el valor de 217 para el sensor de piso derecho su
equivalente en voltaje se puede obtener la siguiente manera:
217∗5Voltios
Voltaje= =1.05Voltios
1024
1.05 voltios es el valor que se deberá desplegar.
Ejemplo 5: Minisumo – Básico
Explicación del concurso
Consiste en un combate entre dos robots que discurrirá por una tarima, también denominada
dohyo o ring, y consiste en marcar puntos “Yukoh”.
Los combates se componen de dos asaltos de 3 minutos máximo, cada uno, más un terecer
asalto en caso de empate. El primer competidor en alcanzar dos puntos de Yukoh será el
ganador de la lucha. El competidor que gane un punto de yukoh en el tercer combate, será el
ganador.

Figura 29. Competición seguidor de línea, persecución

Construya una pista para pruebas


Es importante tener una pista o construir una con los siguientes materiales.
• Cartulina blanca,
• cinta de aislar negra,
• tijeras.

Para hacer pruebas dibuje un dohyo como el que se muestra en la figura. Por facilidad use una
cartulina blanca, fondo, y la linea que delimite el “ring” de color negro.

Se propone el siguiente código, copie y pegue en el área de código del IDE de Arduino.
//Alias para pines de control de Motor Derecho
int pwmtoder = 10;
int mtoder = 12;
int pwmvalder = 100; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Alias para pines de control de Motor Izquierdo


int pwmtoizq = 11;
int mtoizq = 13;
int pwmvalizq = 100; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

int sensorderc;
int sensorder;
int sensorizqc;
int sensorizq;

//Funciones
void adelante();
void atras();
void giroderecha();
void giroizquierda();
void derecha();
void izquierda();
void detenido();

//Configuración de Módulos y IO
void setup() {

pinMode(pwmtoizq, OUTPUT);
pinMode(mtoizq, OUTPUT);

pinMode(pwmtoder, OUTPUT);
pinMode(mtoder, OUTPUT);

digitalWrite(pwmtoizq, LOW);
digitalWrite(mtoizq, LOW);

digitalWrite(pwmtoder, LOW);
digitalWrite(mtoder, LOW);
delay(1000);
}

//Ciclo principal
void loop()
{
sensorderc = analogRead(1);
sensorizqc = analogRead(2);

if(sensorderc < 700 || sensorizqc < 700)


{
atras();
delay(200);
giroderecha();
delay(250);
}
else
{
adelante();
}

void adelante()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, HIGH);
}

void atras()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, LOW);
}

void giroderecha()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void derecha()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void giroizquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void izquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, 0);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void detenido()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
}
Ejemplo 5: Seguidor de línea – Básico
El seguimiento de una línea es una buena introducción en la programación de robots.

¿Por qué un seguidor de líneas?


Es fácil entender el funcionamiento y la lógica de programación para el seguimiento de una
línea. Optimizar el programa para hacer que el robot se deslice sobre una línea a la velocidad
más rápida es un reto que puse llevarle a algunos conceptor avanzados de programación.

Explicación del concurso


El concurso de velocidad consiste en una carrera de persecución entre dos robots en una pista
cerrada, comenzando en puntos opuestos y avanzando en el mismo sentido. El objeto, por
tanto, será la consecución de altas velocidades de marca en un recorrido perfectamente
establecido.

Figura 24. Competición seguidor de línea, persecución

Construya una pista para pruebas


Es importante tener una pista o construir una con los siguientes materiales.
• Cartulina blanca,
• cinta de aislar negra,
• tijeras.
Para hacer pruebas dibuje con la cita de aislar una pista sencilla, tal vez sea suficiente con un
rectángulo con las esquinas redondeadas o una elipse. No se recomienda vueltas con ángulos
rectos, 90 grados.
Se propone el siguiente código, copie y pegue en el área de código del IDE de Arduino.

//Inicio de programa
//Alias para pines de control de Motor Derecho
int pwmtoder = 10;
int mtoder = 12;
int pwmvalder = 100; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

//Alias para pines de control de Motor Izquierdo


int pwmtoizq = 11;
int mtoizq = 13;
int pwmvalizq = 100; //Esta variable es la que se modifica para variar la velocidad de giro del
motor. Va de 0 a 255, siendo 0 el mínimo y 255 el máximo

int sensorderc;
int sensorder;
int sensorizqc;
int sensorizq;

//Funciones
void adelante();
void atras();
void giroderecha();
void giroizquierda();
void derecha();
void izquierda();
void detenido();

//Configuración de Módulos y IO
void setup() {

pinMode(pwmtoizq, OUTPUT);
pinMode(mtoizq, OUTPUT);

pinMode(pwmtoder, OUTPUT);
pinMode(mtoder, OUTPUT);
digitalWrite(pwmtoizq, LOW);
digitalWrite(mtoizq, LOW);

digitalWrite(pwmtoder, LOW);
digitalWrite(mtoder, LOW);
delay(1000);
}

//Ciclo principal
void loop()
{
sensorderc = analogRead(1);
sensorizqc = analogRead(2);

if(sensorderc < 700 && sensorizqc < 700)


{
adelante();
}

if(sensorderc < 700 && sensorizqc > 700)


{
izquierda();
}

if(sensorderc > 700 && sensorizqc < 700)


{
derecha();
}
}

void adelante()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, HIGH);
}
void atras()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, LOW);
}

void giroderecha()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void derecha()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, LOW);
digitalWrite(mtoizq, HIGH);
}

void giroizquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, pwmvalizq);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}

void izquierda()
{
analogWrite(pwmtoder, pwmvalder);
analogWrite(pwmtoizq, 0);
digitalWrite(mtoder, HIGH);
digitalWrite(mtoizq, LOW);
}
void detenido()
{
analogWrite(pwmtoder, 0);
analogWrite(pwmtoizq, 0);
}

//Fin de programa
Ejemplo 6: Seguidor de línea con Control PID
Para seguir la línea con precisión es necesario aplicar métodos de control. La técnica usada en
este ejemplo es el control PID.
• Proporcional, es un valor propocional a la posición del robot sobre la línea. Si el robot
está centrado sobre la línea el error será 0, pero si se encuentra a la derecho o izquierda
el valor del error será positivo o negativo.
• Integral, es una memoria de todos los eventos anteriores. Una integral en sistemas
discretos, generalmente usados por micro-controladores y microprocesadores, se pude
expresar como la sumatoria de todos los puntos anteriores, lo que en sistemas continuos
es el área debajo de la curva.
• Derivativo, es la razón de cambio, la tendencia, el diferencia de los valores actuales y
anteriores.

El código propuesto.
//Inicio de programa
#include <QTRSensors.h> //Biblioteca para la lectura y calibración de los sensores de contraste

//Declaración de constantes
#define NUM_SENSORS 4 // Número de sensores
#define NUM_SAMPLES_PER_SENSOR 4 // Número de muestras por sensor
#define EMITTER_PIN 4 // Controlador de emisores LED's infrarrojos

//Los sensores reflectivos para detectar contraste de encuentran conectados en las entradas
//Analógicas A0 a A3
QTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3}, NUM_SENSORS,
NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS]; //Vector para almacenar señal de sensores

unsigned int sensors[5]; // Matriz para armazenar valores dos sensores

int MotorA = 11; //Alias para Motor B


int MotorB = 10; //Alias para Motor A

//Declaración de variables
int total = 0;
float average = 0;
int index = 0;
int last_proportional;
int integral;
void setup(){
//Configuración de entradas y salidas digitales
delay(500);

pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

digitalWrite(12, HIGH);
digitalWrite(13, LOW);

//Se prende el indicador LED conectado en el pin 13, para indicar que se
//inicia la calibración

//Rotación del robot para calibración


analogWrite(MotorA, 50);
analogWrite(MotorB, 50);

for (int i = 0; i < 200; i++) //Calibración durante 5 segundos


{
qtra.calibrate(); // Se hace las lecturas para obtener valores de máximos y mínimos
}
digitalWrite(13, HIGH); //Se apaga el LED indicando que se completo la programación

analogWrite(MotorA, 0);
analogWrite(MotorB, 0);
delay(1000);

void loop(){
while(1){
//Se obtiene el valor de cada uno de los sensores mediante la función qtra.readline();
unsigned int position = qtra.readLine(sensorValues);
//Determinación del término proporcional
int proportional = ((int)position) - 1500;
//Determinación del término derivativo
int derivative = proportional - last_proportional;

//Determinación del término integral


integral += proportional;

//Se almacena el estado anterior para determinar el próxmio término derivativo


last_proportional = proportional;

//Cálculo para determinar la velocidad de cada uno de los motores


int power_difference = proportional/5 + integral/20000 + derivative*3;

const int max = 120;


if(power_difference > max)
power_difference = max;
if(power_difference < -max)
power_difference = -max;
if(power_difference < 0)
set_motors(max+power_difference, max);
else
set_motors(max, max-power_difference);
}
}

// Accionamiento dos motores


void set_motors(int left_speed, int right_speed){
if(right_speed >= 0 && left_speed >= 0){
analogWrite(MotorA, left_speed);
analogWrite(MotorB, right_speed);
}
if(right_speed >= 0 && left_speed < 0){
left_speed = -left_speed;
analogWrite(MotorA, left_speed);
analogWrite(MotorB, 0);
}
if(right_speed < 0 && left_speed >= 0){
right_speed = -right_speed;
analogWrite(MotorA, 0);
analogWrite(MotorB, right_speed);
}
}

También podría gustarte