Guia Seguidor de Linea
Guia Seguidor de Linea
Guia Seguidor de Linea
INDUSTRIALES Y DE TELECOMUNICACIN
Titulacin:
INGENIERO INDUSTRIAL
NDICE
Captulo 1.
1.1.
Introduccin ................................................................................................... 19
1.2.
Objetivos ........................................................................................................ 20
Captulo 2.
2.1.
2.1.1.
2.1.2.
Pista ........................................................................................................ 24
2.1.3.
2.2.
Antecendetes .................................................................................................. 27
2.2.1.
2.2.2.
Pololu 3pi................................................................................................ 28
2.2.3.
n00b0t ..................................................................................................... 30
2.2.4.
Pocketbot 2 ............................................................................................. 31
2.2.5.
Conclusiones........................................................................................... 33
2.3.
2.3.1.
Roomba................................................................................................... 34
2.3.2.
Kiva ........................................................................................................ 35
2.3.3.
Captulo 3.
3.1.
Microcontrolador ........................................................................................... 38
3.1.1.
Qu es arduino? .................................................................................... 40
ii
3.1.2.
Ventajas .................................................................................................. 40
3.1.3.
3.1.4.
3.1.5.
3.1.6.
3.2.
Ruedas ............................................................................................................ 51
3.2.1.
3.2.2.
3.2.3.
Eleccin .................................................................................................. 55
3.3.
Motores .......................................................................................................... 56
3.3.1.
3.3.2.
3.3.3.
3.3.4.
Eleccin motor........................................................................................ 60
3.4.
3.4.1.
Qu es un puente en H? ........................................................................ 62
3.4.2.
ULN2803 ................................................................................................ 66
3.4.3.
L298N ..................................................................................................... 68
3.4.4.
L6205N ................................................................................................... 69
3.4.5.
3.5.
3.5.1.
QTR-8RC ............................................................................................... 78
3.5.2.
3.6.
Bluetooth ........................................................................................................ 83
3.6.1.
Configuracin ......................................................................................... 85
iii
3.6.2.
3.7.
Pruebas ................................................................................................... 86
Alimentacin .................................................................................................. 88
3.7.1.
3.7.2.
3.8.
Resumen......................................................................................................... 90
Captulo 4.
Diseo ..................................................................................................... 92
4.1.
4.2.
4.3.
4.4.
4.5.
4.6.
Captulo 5.
Captulo 6.
6.1.
6.2.
6.3.
6.3.1.
6.3.2.
Captulo 7.
7.1.
7.1.1.
7.1.2.
7.1.3.
7.1.4.
7.1.5.
7.1.6.
7.2.
7.3.
7.4.
7.5.
7.5.1.
7.5.2.
7.5.3.
7.5.4.
7.6.
Captulo 8.
8.1.
8.1.1.
8.1.2.
8.1.3.
8.1.4.
8.1.5.
8.1.6.
8.1.7.
8.1.8.
8.2.
8.2.1.
8.2.2.
Captulo 9.
10.3.
10.4.
10.5.
Captulo 11. Puntos fuertes y futuras mejoras del robot .......................................... 184
11.1.
vii
Lista de figuras
ix
Figura 3-20: Funda protectora para motor micro metal (2 und) ................................... 62
Figura 3-21: Esquema de un puente en H ..................................................................... 63
Figura 3-22: Giro en un sentido del motor ................................................................... 63
Figura 3-23: Giro en el otro sentido del motor ............................................................. 64
Figura 3-24: Situaciones no posibles ............................................................................ 64
Figura 3-25: Relacin entre el voltaje y la velocidad del motor en funcin del tiempo
............................................................................................................................................. 65
Figura 3-26: Esquema del ULN2803 ............................................................................ 66
Figura 3-27: Posible solucin para el ULN2803 .......................................................... 67
Figura 3-28: Esquema del L298N ................................................................................. 68
Figura 3-29: L298N ...................................................................................................... 69
Figura 3-30: Esquema del L6205N ............................................................................... 70
Figura 3-31: Relacin de pines del L6205N ................................................................. 70
Figura 3-32: Esquema de conexin del L6205N .......................................................... 72
Figura 3-33: Montaje para la prueba del L6205N ........................................................ 74
Figura 3-34: Resultado obtenido en la prueba .............................................................. 75
Figura 3-35: Matriz de sensores Pololu Zumo ............................................................. 76
Figura 3-36: Disposicin de los sensores de n00b0t .................................................... 77
Figura 3-37: QTR-8RC ................................................................................................. 77
Figura 3-38: Esquema de funcionamiento del QTR-8RC ............................................ 78
Figura 3-39: Divisin de la matriz QTR-8RC en dos ................................................... 79
x
xi
Figura 4-6: Conexionado entre el Arduino Pro Mini y el L6205N y el QTR-8RC ...... 98
Figura 4-7: Conexin entre Arduino Pro Mini y programador y mdulo bluetooth .... 99
Figura 4-8: Esquema en Eagle del L6205N y los componentes que necesita ............ 100
Figura 4-9: Conexin entre el L6205N y sus componentes........................................ 101
Figura 4-10: Disposicin de los taladros de la rueda loca y conexin entre Arduino Pro
Mini y L6205N .................................................................................................................. 102
Figura 4-11: Resultado final del PBC ......................................................................... 103
Figura 4-12: Resultado final con plano de masa ........................................................ 103
Figura 4-13: Representacin 3D del diseo. Vista isomtrica 1 ................................ 104
Figura 4-14: Representacin 3D del diseo. Vista isomtrica 2 ................................ 104
Figura 4-15: Representacin 3D del diseo vista de alzado ....................................... 105
Figura 4-16: Representacin 3D del diseo. Vista posterior ...................................... 105
Figura 4-17: Impresin del PBC ................................................................................. 106
Figura 4-18: Prototipo. Vista ismetrica .................................................................... 106
Figura 4-19: Prototipo. Vista de alzado. Comparacin con un boli Bic ..................... 107
Figura 4-20: Prototipo. Vista posterior ....................................................................... 107
Figura 4-21: PBC. Izquierda vista posterior. Derecha vista de alzado ....................... 108
Figura 4-22: Esquema unifilar final del robot ............................................................ 109
Figura 5-1: Colocacin de los motores ....................................................................... 111
Figura 5-2: Colocacin de los conectores hembras y machos .................................... 112
Figura 5-3: Colocacin de los LEDs delanteros y los componentes del L6205N ...... 113
xii
Figura 7-1: Diagrama del sketch empleado por el robot para seguir lneas ................ 129
Figura 7-2: Diagrama del sketch para calibrar los sensores infrarrojos ...................... 133
Figura 7-3: Diferencia entre los valores devueltos por los sensores infrarrojos con y sin
mapear ................................................................................................................................ 134
Figura 7-4: Deteccin de las marcas de bifurcacin ................................................... 135
Figura 7-5: Valores de los pesos que tiene cada sensor .............................................. 136
Figura 7-6: Obligacin de giro del robot segn las marcas de bifurcacin ................ 137
Figura 7-7: Diagrama de bloques de un controlador PID ........................................... 138
Figura 7-8: Representacin del tiempo de pico, del pico de sobreoscilacin y del
tiempo de estabilizacin..................................................................................................... 139
Figura 7-9: Resultados ante diferentes parmetros ..................................................... 143
Figura 7-10: Comprobacin de los signos al aplicar el PWM en el robot .................. 146
Figura 7-11: Circuito que se emplear para la prueba ................................................ 147
Figura 7-12: Efecto deseado en la prueba ................................................................... 147
Figura 7-13: Resultados de la prueba. De izquierda a derecha y de arriba abajo: Kp=1,
Kp=3, Kp=5, Kp=7, Kp=8, Kp=9 ......................................................................................... 149
Figura 7-14: Resultado de la prueba para Kp=10........................................................ 150
Figura 7-15: Resultados empleando los parmetros obtenidos en el mtodo de ZieglerNichols. Arriba se representa el error y abajo los PWM de los motores ........................... 151
Figura 7-16: Resultados empleando Kp=15. Arriba se representa el error y abajo los
PWM de los motores.......................................................................................................... 152
xiv
Figura 7-17: Resultados empleando Ki=250. Arriba se representa el error y abajo los
PWM de los motores.......................................................................................................... 153
Figura 7-18: Resultados empleando Kd=1. Arriba se representa el error y abajo los
PWM de los motores.......................................................................................................... 154
Figura 7-19: Salida del trazado del robot.................................................................... 155
Figura 8-1: Diagrama del funcionamiento del control remoto del robot. A la izquierda
se representa el sketch del robot. A la derecha se representa la aplicacin Android ......... 156
Figura 8-2: Logo de Basic4Android ........................................................................... 157
Figura 8-3: Logo de Amarino ..................................................................................... 158
Figura 8-4: Logo de Processing .................................................................................. 159
Figura 8-5: Conexin Processing y Eclipse ................................................................ 159
Figura 8-6: Exportacin de proyectos Android en Processing ................................... 160
Figura 8-7: Ventana de permisos de Eclipse .............................................................. 162
Figura 8-8: Interfaz de la aplicacin Android de seleccin de dispositivo a conectar 163
Figura 8-9: Representacin de los ejes de los acelermetros en un dispositivo Android
........................................................................................................................................... 165
Figura 8-10: Valores de los acelermetros en dos instantes consecutivos estando el
dispositivo Android en reposo sobre la mesa .................................................................... 167
Figura 8-11: Valores que puede tomar el acelermetro del eje x. Representacin de 9
........................................................................................................................................... 167
Figura 8-12: Problema de formatos entre Arduino y Android.................................... 168
Figura 8-13: Origen de coordenadas y dimensiones mximas en una pantalla de un
dispositivo Android............................................................................................................ 170
xv
xvi
Lista de tablas
xviii
CAPTULO 1.
J. L. Prez Motos
INTRODUCCIN Y OBJETIVOS
1.1. INTRODUCCIN
El presente proyecto abarca el diseo, construccin y configuracin de un robot
sigue lneas, as como la configuracin de una va de comunicacin inalmbrica
mediante un enlace Bluetooth y un dispositivo Android. Como su propio nombre indica,
un robot sigue lneas es un dispositivo mvil capaz de seguir una trayectoria marcada en
el suelo de forma autnoma.
El robot deber contar con una serie de sensores para deducir en qu posicin se
encuentra el robot en relacin al camino que debe seguir. Para ello el sistema ser
gobernado por un microcontrolador, el cual tendr un algoritmo de control que ser el
encargado de variar la velocidad de los motores para corregir la posicin del robot.
Como se ha comentado anteriormente, el robot se podr comunicar con otros
dispositivos a travs de tecnologa bluetooth.
Pgina 19 de 231
J. L. Prez Motos
1.2. OBJETIVOS
El objetivo ltimo es dotar al robot de lo necesario para que pueda seguir una
trayectoria sin desviarse de ella. Para ello se debern conseguir otros objetivos:
1.
2.
3.
4.
5.
Manipulacin de sensores.
Control de motores.
Diseo de un algoritmo de control.
Programacin de un microcontrolador.
Comunicacin entre el sistema y dispositivos externos mediante bluetooth.
Pgina 20 de 231
CAPTULO 2.
J. L. Prez Motos
Laberinto
En esta modalidad los robots deben resolver un laberinto lo antes posible. Para
ello se les permite dar dos vueltas. La primera de ellas es de reconocimiento. En ella
el robot deber grabar en su memoria interna los giros que debe de realizar para que
en la segunda vuelta complete el recorrido en el menor tiempo posible.
Pgina 21 de 231
J. L. Prez Motos
Velocistas
En esta modalidad los robots realizan una carrera de persecucin por parejas
dentro de un circuito cerrado. Los robots comienzan en puntos opuestos del trazado y
ambos avanzan en el mismo sentido. La prueba acaba cuando uno de los dos llega a
contactar con el otro.
Generalmente existe una primera ronda en la que los participantes recorren el
circuito en solitario y solo los que consigan mejor tiempo pasarn a la siguiente fase
de la competicin.
Pgina 22 de 231
J. L. Prez Motos
Los robots velocistas no estn obligados a mantenerse sobre una lnea, sino que
los robots pueden elegir por cul de cualquiera de las dos lneas ir o incluso pueden ir
entre ambas. El robot quedar descalificado si toca cualquier lnea roja.
Rastreadores
Esta modalidad es una mezcla de las dos anteriores. Los robots debern
completar un circuito lo antes posible, pero este circuito est lleno de curvas y
bifurcaciones.
Pgina 23 de 231
J. L. Prez Motos
robots ms completos ya que deben combinar una gran capacidad de deteccin, un buen
seguimiento del camino y ejecutar con rapidez las maniobras.
En los siguientes apartados se pasar a analizar en profundidad las caractersticas
que tienen las pruebas de rastreadores y diferentes modelos de rastreadores ya
existentes.
Los robots rastreadores debern ser autnomos. No podrn recibir datos que
alteren su comportamiento. La organizacin permite que los robots enven datos
siempre y cuando se informe a los jueces y homologadores de dicha
caracterstica. Como excepcin se permite que los robots dispongan de un
sistema de detencin a distancia, ya sea por infrarrojos o radiofrecuencia, dicho
sistema podr ser controlado por un juez de pista o miembro del equipo.
El robot deber tener unas dimensiones tales que quepan dentro de una caja de
20x20 cm con los sensores de contacto (microrruptores) plegados en caso de que
fuera necesario. Su altura podr ser cualquiera. No se permite disear el robot de
forma que cuando comience la carrera se separe en diferentes piezas.
El peso mximo de los robots ser de 2000 gramos incluyendo todas las partes.
2.1.2. PISTA
Las pistas consistirn en una superficie de color blanco con una lnea negra
(camino a seguir) de una anchura de 202mm. Las marcas estarn formadas del
mismo material que la lnea del circuito, su anchura ser la misma que la del
camino a seguir y su longitud ser de 405mm. El espacio entre marcas
equivaldr a 203mm.
Pgina 24 de 231
J. L. Prez Motos
El robot deber seguir siempre una de las lneas de las que conste el camino. En
caso de salirse dispondr de 15 segundos para reincorporarse al circuito a una
distancia inferior a 100 mm desde el punto en el que se sali. Si pasado este
tiempo no se ha reincorporado o lo ha hecho en otro lugar de la pista, el
responsable del equipo tiene la opcin de situar el robot en el inicio de la pista
sin para el tiempo. En caso contrario quedar eliminado.
Antes de una bifurcacin se marcar el camino que debe tomar el robot con una
marca en los laterales del camino.
Pgina 25 de 231
J. L. Prez Motos
En el caso de que dos robots compitan en pistas simtricas, cada uno recorrer
una de las dos pistas, luego los robots se cambiarn de pista y se sumarn los
tiempos de cada turno. De cada carrera e dos robots se clasificar el ms rpido.
Quedar a decisin de la organizacin, segn el nmero de robots inscritos, si el
sistema de competicin ser estilo liguilla o campeonato con eliminacin de la
competicin de los robots no clasificados.
En caso de que solo se habilite una pista, se permitir hacer varias rondas (a
definir por la organizacin), ofreciendo as la posibilidad de mejorar los tiempos
marcados. Se contabilizar el mejor tiempo de los obtenidos. La clasificacin
ser por tiempo.
Pasado un tiempo mnimo de tres minutos desde el inicio del asalto los jueces
podrn parar y finalizar la carrera cuando lo consideren oportuno. Quedar bajo
criterio del juez el robot ganador de la carrera, teniendo en cuenta los siguiente
parmetros de decisin:
1. Ser el nico robot que permanezca en movimiento.
2. Mxima proximidad a la llegada.
3. No haber perdido la lnea en ninguna ocasin durante la carrera.
Pgina 26 de 231
J. L. Prez Motos
2.2. ANTECENDETES
A continuacin se proceder a describir diferentes robots rastreadores que se han
ido encontrando en la bibliografa. Con este anlisis se pretende recoger ideas para el
diseo del robot, as como analizar las fortalezas y debilidades de estos diseos previos.
J. L. Prez Motos
Por otro lado, al incluir en el diseo del robot una carcasa hace que este resulte
mucho ms robusto, aunque tambin lo hace ms pesado, lo que tendr repercusiones en
el consumo de energa elctrica y la autonoma del robot.
J. L. Prez Motos
Pgina 29 de 231
J. L. Prez Motos
2.2.3. N00B0T
Este robot fue desarrollado en el foro de la Asociacin de Robtica y Domtica de
Espaa[14] por el usuario dip6, por lo que fue totalmente diseado y construido por
hobby. Como se puede ver en la siguiente imagen, el diseo externo est muy
influenciado por el Pololu 3Pi.
Al igual que el Pololu 3Pi monta un ATmega328, los motores son de corriente
continua, y tiene en diferentes puntos de la periferia del robot 5 sensores infrarrojos para
detectar la lnea y emplea cuatro pilas AAA para alimentar a todo el sistema. A
diferencia del Pololu 3Pi incluye dos sensores infrarrojos extras, uno a cada lado, que
tienen como finalidad leer las marcas que aparecen en los circuitos de los rastreadores
para indicar qu camino deben tomar.
Pgina 30 de 231
J. L. Prez Motos
2.2.4. POCKETBOT 2
El PocketBot 2 es un robot diseado y construido por Ondej Stank, estudiante
checo que present este robot como Proyecto Final de Carrera[16]. La principal
caracterstica de este robot son sus dimensiones, ya que, como el propio Ondej Stank
dice, es un robot que cabe dentro de una caja de cerillas.
Pgina 31 de 231
J. L. Prez Motos
Pgina 32 de 231
J. L. Prez Motos
El PocketBot 2 es otro gran robot que puede ser de gran utilidad sobre todo en
temas de conectividad.
2.2.5. CONCLUSIONES
Todos los robots estudiados incluyen elementos comunes en sus diseos que habr
que tener en cuenta a la hora de elegir los componentes que tenga el robot.
Microcontrolador:
la
mayora
de
los
robots
estudiados
emplean
J. L. Prez Motos
2.3.1. ROOMBA
Quizs sea el robot rastreador ms conocido de todo el mundo. La finalidad de este
robot es la de limpiar la casa de forma autnoma.
Pgina 34 de 231
J. L. Prez Motos
Figura 2-15: Trayectoria seguida por un robot Roomba para limpiar una habitacin
2.3.2. KIVA
Este robot es fabricado por Kiva Systems[18] y tiene como finalidad la de organizar
almacenes. Multitud de grandes compaas como Amazon, Toys R Us, Staples o GAP
emplean robots Kiva en sus almacenes.
Pgina 35 de 231
J. L. Prez Motos
Pgina 36 de 231
J. L. Prez Motos
Pgina 37 de 231
CAPTULO 3.
J. L. Prez Motos
ELECCIN DE COMPONENTES
En los siguientes apartados se van a exponer las razones por las que se eligieron los
diferentes componentes que forman el robot. En todo momento se tuvieron en cuenta
una serie de caractersticas que definan al robot. Estas caractersticas son:
1. Pequeo tamao: se pens que el robot fuera ms pequeo que el Pololu 3Pi,
el cual abarca una superficie de unos 70cm2.
2. Ligero: de nuevo se pens que el robot fuera ms ligero que el Pololu 3Pi,
que tiene un peso de 243gr con pilas[20].
3. Veloz: se puso como meta superar los 70cm/s del PocketBot 2.
4. Barato: se intent que el coste total del robot fuera inferior a los 100 del
Pololu 3Pi.
3.1. MICROCONTROLADOR
Un microcontrolador es un circuito integrado que est formado por las tres unidades
funcionales de un ordenador: microprocesador, memoria y perifricos de entrada y
salida[4].
La forma en la que funciona un microcontrolador se determina por el programa
almacenado en su memoria. Este programa se puede disear y escribir en diferentes
lenguajes de programacin y tras una compilacin, se descarga en la memoria interna
del microcontrolador en lenguaje ejecutable. Esto, unido a su alta flexibilidad, hacen
que los microcontroladores se empleen en multitud de aplicaciones: automatizacin,
robtica, domtica, medicina, aeronutica, automocin, telecomunicaciones, etc.
Las principales caractersticas de los microcontroladores son:
Pgina 38 de 231
J. L. Prez Motos
Memoria de Programa: puede ser una memoria ROM (Read Only Memory),
EPROM
(Electrically
Programable
ROM),
EEPROM
(Electrically
Generador de Reloj: cristal de cuarzo que produce unos impulsos con una
determinada frecuencia y genera una seal oscilante. Esta frecuencia suele ir
desde 1 a 40 MHz.
Otras opciones:
- Conversores Analgicos-Digitales (A/D, analog-to-digital) para convertir
un nivel de voltaje en un cierto pin a un valor digital manipulable por el
programa del microcontrolador. Estos conversores A/D suelen tener una
resolucin tpica de 10 bits, aunque existen versiones de 12, 16 o 32 bits.
- Moduladores por Ancho de Pulso (PWM, Pulse Width Modulation) para
generar ondas cuadradas de frecuencia fija pero con ancho de pulso
variable. Aunque cualquier salida digital del microcontrolador puede ser
programada para hacer esta funcin mediante el uso de interrupciones y
temporizadores, muchos microcontroladores incluyen algunas salidas
especialmente dedicadas a este efecto, lo cual simplifica su uso.
Pgina 39 de 231
J. L. Prez Motos
3.1.1. QU ES ARDUINO?
Arduino[21] es una plataforma de hardware y software open source que est basado
en una placa que permite conectar sensores y actuadores mediante entradas y salidas
analgicas y digitales y en un entorno de desarrollo basado en el lenguaje de
programacin Processing.
Al ser open source tanto su diseo como su distribucin es libre. Es decir, puede
utilizarse libremente para desarrollar cualquier tipo de proyecto sin tener que adquirir
ningn tipo de licencia. El texto de la referencia de Arduino est publicado bajo la
licencia Creative Commons Reconocimiento-Compartir bajo la misma licencia 3.0. Los
ejemplos de cdigo de la referencia estn liberados al domino pblico.
3.1.2. VENTAJAS
Las razones por las que se eligi Arduino como plataforma sobre la que desarrollar
el proyecto fueron cuatro:
Verstil: una misma placa de Arduino puede servir para proyectos de domtica,
robtica, control de sistemas o como programador de otros microcontroladores.
Pgina 40 de 231
J. L. Prez Motos
Pines:
- Terminales de alimentacin y de referencia (naranja): a travs de estos
pines se puede alimentar a la placa al mismo tiempo que sirven como
referencia de tensin para los circuitos.
- Terminales digitales (azul, rojo, morado y verdes): estos pines tomarn
los valores de 0s y 1s. Se pueden configurar como pines de entrada o de
salida. Las entradas analgicas tambin se pueden configurar como
digitales.
- Terminales PWM (azul): mediante estos pines se pueden generar
seales PWM. El ciclo de trabajo de la seal se puede ajustar con una
resolucin de 1 byte (desde 0 hasta 255).
Pgina 41 de 231
J. L. Prez Motos
analgicos
(verde):
estos
terminales
cuentan
con
generalmente
los
Microcontrolador:
las
placas
Arduino
emplean
LED encendido: LED que indica si la placa tiene alimentacin suficiente como
para funcionar.
LED: este LED est unido mediante una resistencia interna (resistencia pull-up)
al terminal 13. Permite comprobar el correcto funcionamiento de la salida digital
Pgina 42 de 231
J. L. Prez Motos
J. L. Prez Motos
Pgina 44 de 231
J. L. Prez Motos
Todo sketch est formado por tres partes. Para explicar estas partes se va a utilizar
como ejemplo un sencillo sketch que permite encender y apagar el LED que incorpora
la placa[3].
Declaracin de variables
Lo primero que se debe hacer al empezar a escribir un sketch es definir las variables
y constantes que formarn el sketch.
Configuracin de la placa
En este caso se ha definido el pin 13 (ya que se haba declarado la variable LED
con el valor de 13) como un pin de salida.
Una vez configurada la placa se llega al bucle del sketch, es decir, lo que va a estar
continuamente ejecutndose. Se emplea la sintaxis void loop(). Aqu las funciones ms
utilizadas son las funciones de lectura y de escritura de pines: digitalWrite, digitalRead,
analogRead, analogWrite.
Pgina 45 de 231
J. L. Prez Motos
En este caso en primer lugar se escribe un 1 lgico en el pin 13, despus se espera 1
segundo, despus se escribe un 0 lgico en el pin 13 y se vuelve a esperar 1 segundo.
Este bucle se estara repitiendo indefinidamente mientras no reseteemos la placa o le
quitemos la alimentacin.
De esta forma en apenas 10 lneas ha sido posible controlar el LED interno de la
placa Arduino. Una vez que se ha comprendido como se enciende y como se apaga un
LED es posible poder manipular otros dispositivos como por ejemplo sensores o
motores.
Figura 3-5: Diferentes modelos de Arduino a escala. Fila superior de izquierda a derecha: Mega,
Pro Mini y LilyPad. Fila inferior de izquierda a derecha: UNO, Micro y Leonardo
Tras una primera criba se decidi se iba a estudiar a fondo tres modelos de ellos:
Mega, UNO y Pro Mini.
Pgina 46 de 231
J. L. Prez Motos
Arduino Mega
Posee una memoria interna de tipo flash de 256 KB que permite guardar cdigos
realmente extensos (8 KB son empleados por el bootloader). Adems cuenta con 8 KB
de SRAM y 4 KB de EEPROM, al cual se puede acceder desde la librera EEPROM.
Todo esto hace que este modelo sea el ms apropiado para los proyectos ms
complejos en los que se necesiten multitud de entradas y salidas o ms memoria. Por
otro lado se trata del Arduino de mayor tamao.
Arduino UNO
Pgina 47 de 231
J. L. Prez Motos
Pgina 48 de 231
J. L. Prez Motos
La gran diferencia del Arduino Pro Mini con respecto al Arduino UNO es su
tamao, ya que en muy poco espacio se dispone de prcticamente todas las opciones
que ofrece el Arduino UNO. Esto hace que sea el modelo ms apropiado a la hora de
realizar proyectos en los que el tamao sea un factor clave. Es necesario destacar que
por razones de coste esta placa no incorpora el circuito integrado de interfaz Serie-USB,
con lo cual ser necesario disponer de hardware adicional para programarlo.
Modelo
Arduino Mega
Arduino UNO
Micro
ATmega2560
ATmega328
ATmega328
Tensin de
funcionamiento
5V
5V
5V
Tensin recomendada
7 - 12 V
7 - 12 V
7 - 12 V
Tensiones lmite
6 - 20 V
6 - 20 V
6 - 20 V
Corriente pines
entrada/salida
40 mA
40 mA
40 mA
Pines digitales
54 (14 PWM)
16 (6 PWM)
16 (6 PWM)
Pines analgicos
16
Puertos serie
Memoria interna
256 KB (8 KB bootloader)
32 KB (0'5 KB bootloader)
32 KB (0'5 KB bootloader)
SRAM
8 KB
2 KB
2 KB
EEPROM
4 KB
1 KB
1 KB
Frecuencia
16 MHz
16 MHz
16 MHz
Ventajas
Econmico
Reducido tamao
Pgina 49 de 231
Desventajas
Gran tamao
J. L. Prez Motos
Tras este anlisis se desech el modelo Arduino Mega. Para este proyecto no se
van a emplear multitud de sensores, por lo que se desaprovecharan gran cantidad de
entradas y salidas. Por el contrario, se dese desde un principio que el robot fuera lo
ms pequeo posible, por lo que los 55 x 110 mm del Arduino Mega hicieron que
finalmente se desechara la opcin de este modelo.
J. L. Prez Motos
tener que comprar un dispositivo externo para poder programarlo son compensadas con
la diferencia de tamao que tiene este modelo con respecto a los otros dos.
Como ya se ha explicado, el Arduino Pro Mini carece de conversor Serie USB,
por lo que para poder programarlo se adquiri el conversor Serie - USB FTDI232.
Figura 3-10: De izquierda a derecha: Arduino UNO, Arduino Pro Mini y conversor Serie USB
FTDI232
3.2. RUEDAS
Pgina 51 de 231
J. L. Prez Motos
Configuracin Diferencial
Consta de dos ruedas paralelas entre s con traccin independiente. En teora esta es
la mecnica ms fcil de construir ya que nicamente se necesitan ruedas de traccin, ya
que los giros se consiguen con la diferencia de velocidades y sentidos de ambas ruedas.
Para darle estabilidad al conjunto se suelen usar una o dos ruedas locas que
aguantarn el peso del robot impidiendo que este se incline y entre en contacto con la
pista. Sin embargo pueden dar problemas en pistas irregulares ya que se puede perder
traccin.
De esta forma su principal ventaja es que es muy fcil de construir. Manipulando
las velocidades de ambas ruedas se puede conseguir que el robot se desplace y adems
gire sin tener que manipular otro elemento. Adems permite que el robot pueda girar
sobre punto medio del eje formado por ambas ruedas. Esto permite que el robot
responda mejor en ruedas cerradas.
Sin embargo esta disposicin presenta varios inconvenientes. La principal de ellas
es que las ruedas de traccin no pueden ir a la mxima velocidad siempre. Por ejemplo
en las curvas la rueda interior deber frenar o incluso invertir el sentido de giro para que
el robot pueda girar. Adems, para asegurar el movimiento rectilneo del robot se deber
comprobar que ambas ruedas giran a la misma velocidad.
Pgina 52 de 231
J. L. Prez Motos
Configuracin en Triciclo
Configuracin Ackerman
Es la configuracin que tienen los coches, es decir, cuatro ruedas siendo dos de
ellas de direccin y dos de traccin. Pueden existir diferentes configuraciones segn
donde se encuentren las ruedas de traccin.
Pgina 53 de 231
J. L. Prez Motos
En un coche las ruedas de direccin generalmente son las delanteras ya que son las
ruedas ms cercanas al conductor. Sin embargo, en un robot estas pueden sin ningn
tipo de problema las traseras. Las ruedas de traccin tambin suelen ser las delanteras.
Sin embargo en robots las ruedas de traccin suelen ser distintas a las de direccin para
simplificar el diseo.
La ventaja de la traccin delantera es que se aprovecha mucho mejor la energa en
curva porque la fuerza se transmite en la direccin de esta por lo que sern ms fciles
de controlar. Sin embargo, si la potencia es elevada se hace difcil de manejar el
vehculo de esta manera ya que tienden a subvirar.
Las principales ventajas que ofrece la configuracin Ackerman son que las ruedas
de traccin pueden ir a mxima velocidad siempre que el radio de giro sea lo
suficientemente grande y que ofrece una gran estabilidad.
Por otro lado, el radio de giro en esta configuracin no es muy pequeo, por lo que
se ha de frenar antes de entrar en una curva.
Pgina 54 de 231
Imagen
J. L. Prez Motos
Modelo
Dimetro
Precio
32 mm
5'95
42 mm
5'90
60 mm
6'90
Modelo
Altura mx
Precio
1 cm
3'15
3 cm
5'10
Imagen
3.2.3. ELECCIN
Tras este anlisis se eligi el sistema diferencial. Es el sistema ms sencillo de
implementar adems de que al estar formado por nicamente dos ruedas es el que
permite que el diseo del robot sea lo ms pequeo posible.
Ya que se seleccion el sistema diferencial se necesitaba una rueda loca que diera
estabilidad al sistema. De las estudiadas se seleccion la TAMIYA que adems de
ofrecer una altura mxima mayor, esta se puede ajustar con diferentes aadidos que trae
el kit.
Pgina 55 de 231
J. L. Prez Motos
3.3. MOTORES
Un motor elctrico es una mquina que transforma la energa elctrica en
movimiento, y generalmente en movimiento rotativo. Hay muchos tipos diferentes, pero
los ms empleados en robtica son los motores paso a paso y los motores de corriente
continua pudiendo estos ltimos encontrarse en su variante con escobillas (la
tradicional) o sin escobillas (brushless).
Pgina 56 de 231
J. L. Prez Motos
J. L. Prez Motos
De esta forma, si se consigue que la corriente circule por las bobinas en el orden y
con la frecuencia adecuada se podr conseguir que el motor avance un paso en uno u
otro sentido.
La principal ventaja que presenta este tipo de motores se la precisin en el giro, por
lo que le movimiento del robot ser ms preciso. Cuanto menor sea el paso del motor
mayor ser la precisin. Adems un motor paso a paso responde a pulsos de entrada
digitales, lo que permite un control en lazo abierto, haciendo un control ms simple.
Pgina 58 de 231
J. L. Prez Motos
J. L. Prez Motos
Tal que V viene en m/s, R en m y N en rpm. Teniendo en cuenta que el radio de las
ruedas escogidas es de 16 mm se tiene:
Pgina 60 de 231
J. L. Prez Motos
Modelo
Reductora
Torque
Precio
10:1
0,2 kgcm
1250 rpm
13'20
30:1
0,3 kgcm
440 rpm
13'20
Segn las ruedas escogidas de 16 mm de radio los motores ofreceran una velocidad
de 2 m/s el modelo con reductora de 10:1 y de 074 m/s el modelo con reductora de
30:1. Debido a que el robot no va a ser un velocista sino un rastreador, por lo que al fin
y al cabo la velocidad no es el punto ms importante en el diseo del robot, se escogi
el modelo con una reductora de 30:1 ya que ofreca un par mejor.
Por ltimo, para poder fijar los motores se adquirieron un par de fundas protectoras
para este tipo de motores.
Pgina 61 de 231
J. L. Prez Motos
3.4.1. QU ES UN PUENTE EN H?
Un puente en H es un circuito electrnico de potencia que est formado por una
serie de transistores, los cuales permitirn pasar o cortar la corriente en un determinado
Pgina 62 de 231
J. L. Prez Motos
sentido[1]. Como se acaba de comentar, los puntos de trabajo de los transistores sern el
de corte (OFF) o saturacin (ON), y estos puntos de trabajo sern controlados mediante
sus terminales de Base (en el caso de transistores BJT) o de Puerta (en el caso de
transistores MOSFET).
Para el caso unipolar, la etapa se compone de cuatro transistores que actan como
interruptores, los cuales pueden estar en dos estados, abierto (ON) y cerrado (OFF).
Cuando un interruptor est abierto no permite el paso de corriente a travs de l, en
cambio cuando est cerrado s lo permitir.
Variando los puntos de trabajo de los interruptores se puede conseguir que el motor
gire en un sentido u otro, o que se quede parado al fijar los dos terminales del motor a
una misma tensin.
Si el puente en H tiene los interruptores 1 y 4 cerrados mientras que los
interruptores 2 y 3 permanecen abiertos, se permite el paso de la corriente de izquierda a
derecha. De esta forma el motor gira en un sentido.
J. L. Prez Motos
Tambin hay que tener en cuenta que no todas las combinaciones son correctas, ya
que algunas posiciones crean cortocircuitos. Es decir, los interruptores de una misma
rama (1-3 y 2-4) no podrn estar cerrados al mismo tiempo.
Pgina 64 de 231
J. L. Prez Motos
Estado
I1
I2
I3
I4
Resultado
Abierto
Abierto
Abierto
Abierto
Cerrado
Abierto
Abierto
Cerrado
Abierto
Cerrado
Cerrado
Abierto
Cerrado
Cerrado
Abierto
Abierto
Fast stop
Tabla 3.5: Estados de los motores en funcin de los estados de los interruptores
Figura 3-25: Relacin entre el voltaje y la velocidad del motor en funcin del tiempo
Pgina 65 de 231
J. L. Prez Motos
3.4.2. ULN2803
El ULN2803 es un circuito integrado que contiene 8 transistores en configuracin
Darlington con sus respectivos diodos de retroceso.
J. L. Prez Motos
J. L. Prez Motos
3.4.3. L298N
El L298N es un circuito integrado formado por dos puentes en H separados.
Cada uno de estos puentes permite obtener hasta 2 A (o 4 A si se conectan en paralelo
ambos puentes), por lo que se pueden utilizar para alimentar a los motores.
Pgina 68 de 231
J. L. Prez Motos
3.4.4. L6205N
El L6205N es un circuito integrado formado por 2 puentes en H completos. En el
mismo empaquetado se incluyen tambin los diodos de libre circulacin[24].
Sus principales caractersticas son que funciona con tensiones de alimentacin
desde los 8 V hasta los 52 V y puede ofrecer corrientes de salida de hasta 28 A. Por lo
Pgina 69 de 231
J. L. Prez Motos
que puede ser utilizado para alimentar los motores. Este integrado emplea transistores
de tipo MOSFET en lugar de los BJT del L298N
J. L. Prez Motos
J. L. Prez Motos
20. ENA: Enable del Puente A. Un nivel bajo en este pin apagar todos los
transistores que forman el Puente A. Si no se va a emplear se deber conectar a +5 V a
travs de una resistencia.
J. L. Prez Motos
Valor
C1
120nF
C2
120nF
CBOOT
220nF
CP
15nF
CENA
6'8nF
CENB
6'8nF
D1
1N4148
D2
1N4148
RENA
100k
RENB
100k
RP
120
Un L6205N.
Dos motores.
Placa de prototipos.
Osciloscopio.
Cables y componentes.
Pgina 73 de 231
J. L. Prez Motos
Pgina 74 de 231
J. L. Prez Motos
En cuanto a la programacin, se pens que sera mejor dejar ambos enables siempre
en H, de esta forma desde Arduino se mandaran las seales PWM a cada input. As, si
tras los clculos el valor es positivo se manda el PWM al IN1 y se manda un 0 al IN2.
SI el valor fuera negativo se manda el PWM al IN2 y se manda un 0 al IN1.
Finalmente se comprob el perfecto funcionamiento de ambos puentes:
Pgina 75 de 231
J. L. Prez Motos
Tambin es posible adquirir cada sensor infrarrojo por separado y colocar cada uno
de ellos donde ms le convenga al robot. El sensor por excelencia es el CNY70, del cual
se puede encontrar multitud de informacin por internet. La principal ventaja de esta
configuracin es que puedes ser ms creativo con la distribucin de los sensores y
colocarlos de la forma ms eficiente posible. Sin embargo, estas configuraciones
requieren una cantidad de espacio generosa, ya que se necesita montar circuitera
Pgina 76 de 231
J. L. Prez Motos
Otro factor importante a tener en cuenta a la hora de elegir los sensores infrarrojos
es su distancia al suelo. Esta viene determinada por el tipo de sensor y por el tipo de
lectura que se realiza. En la mayora de las ocasiones la lectura es digital, es decir, se
leen 0s y 1s. En general, cuanto ms pegado est el sensor al suelo mejores lecturas
realizar.
Por ltimo es importante determinar la distancia que hay entre los sensores y el eje
de los motores. Cuanto ms alejados estn los sensores del eje de los motores antes se
anticipar la llegada de una curva, pero, sin embargo, los motores debern de hacer ms
fuerza para mover o corregir el robot, por lo que en principio responder peor. De esta
forma hay que encontrar un equilibrio entre la distancia a la que se encuentran los
motores entre s y la distancia que existe entre los sensores y el eje de los motores.
Finalmente se eligi como sensor infrarrojo el QTR-8RC Reflectance Sensor Array.
Las razones por las que se eligi este sensor son las ya explicadas con respecto a una
matriz de sensores infrarrojos.
J. L. Prez Motos
3.5.1. QTR-8RC
La matriz de sensores infrarrojos QTR-8RC est diseada especficamente para la
utilidad que se le va a dar en este robot, es decir, para detectar lneas, aunque se puede
emplear para otros propsitos como por ejemplo sensor de proximidad.
Est formada por ocho parejas de emisores infrarrojos y de receptores
(fototransistores) espaciados entre s 95 mm. Cada fototransistor emplea un circuito de
descarga de un condensador, el cual permite que un pin digital del microcontrolador
analice la cantidad de luz que le llega al sensor segn el tiempo que tarde en descargarse
el condensador. Cuanta ms rpida sea la descarga del condensador mayor ser la
reflectividad del objeto al que mira el sensor. Mayor reflectividad implica mayor
cantidad de luz en la base del fototransistor, lo que inmediatamente provoca un
incremento en la corriente de colector, que descarga ms rpidamente el
condensador[25].
Pgina 78 de 231
J. L. Prez Motos
Todas las salidas son independientes, pero los LEDs estn dispuestos en parejas
para reducir a la mitad el consumo. Los LEDs se controlan mediante un transistor
MOSFET, cuya puerta normalmente est en alto, permitiendo apagar los LEDs al poner
en bajo la puerta del MOSFET. Se puede reducir el consumo del sensor apagando los
LEDs cuando no se est usando el sensor o ajustando el brillo de los LEDs mediante un
PWM.
Las resistencias que componen la matriz hacen que esta funcione a 5V, con un
consumo de cada LED de 20 25mA, haciendo un consumo total de la matriz de
100mA. Aadir que la matriz se puede dividir en dos submatrices, dejando en una seis
sensores y en la otra dos.
Voltaje de funcionamiento: 33 5 V
Distancia ptima: 3 mm
Peso: 309 g
Pgina 79 de 231
J. L. Prez Motos
Pgina 80 de 231
J. L. Prez Motos
Pgina 81 de 231
J. L. Prez Motos
Figura 3-42: Esquema del sketch empleado para la prueba del QTR-8RC
Es necesario hacer notar que es necesario calibrar los sensores. Cada sensor tiene
diferentes valores mximos y mnimos, por lo que a menos de que se guarden los
valores en la memoria EEPROM, cada vez que se acceda a los sensores habr que
calibrarlos.
A continuacin se muestra la pantalla del puerto serie. En vez de realizarlo sobre
una superficie blanca y con una pista negra, se ha empleado el dedo para ir tapando los
sensores:
En la primera lnea se muestran los valores mximos que ha visto cada sensor. En la
segunda lnea estn los valores mnimos. Despus, al haber mapeado los valores entre 0
y 9, se muestra el camino que ha ido siguiendo el dedo (all por donde pasaba el dedo se
Pgina 82 de 231
J. L. Prez Motos
3.6. BLUETOOTH
Desde un primer momento uno de los objetivos ms ambiciosos del proyecto fue el
tema de la comunicacin del robot con un ordenador. Un robot sigue lneas no es como
por ejemplo un brazo robtico que tiene su base siempre fija en el mismo sitio, si no que
este se encuentra en movimiento, por lo que la conexin con el ordenador a travs de
cables se desech desde un primer momento.
Primero se pens en guardar los datos dentro de una tarjeta SD y despus volcar los
datos a un ordenador ya que existen shields[26] para Arduino los cuales permiten grabar
y leer datos desde una tarjeta SD. Se desech esta opcin por dos razones. La primera
de ellas era que se buscaba un sistema ms directo en el que se pudiera comprobar el
funcionamiento del robot en vivo. La segunda de ellas, una vez ms, fue el tamao de
estos shields ya que son bastante grandes.
J. L. Prez Motos
J. L. Prez Motos
3.6.1. CONFIGURACIN
El mdulo bluetooth vena sin configurar, por lo que lo primero que se hizo fue
configurarlo. Para poder configurarlo se deben emplear comandos AT[28]. Los pasos
para configurar el bluetooth son los siguientes:
1. Asegurarse de que el mdulo no est vinculado a ningn dispositivo, esto es,
que la luz roja del mdulo est parpadeando.
2. Dejar libres los pines de la comunicacin Serial de la placa Arduino, pines TX
y RX.
3. Cargar el programa.
4. Cuando se indique conectar el TX del mdulo bluetooth con el RX de la placa
Arduino y el RX del mdulo bluetooth con el TX de la placa Arduino.
5. Empezar la comunicacin con el mdulo (AT).
6. Cambiar el nombre del mdulo (AT+NAME).
7. Ajustar la velocidad de comunicacin (AT+BAUD):
AT+BAUD
Velocidad Transmisin
(Baudios)
1200
2400
4800
9600
19200
38400
57600
115200
Pgina 85 de 231
J. L. Prez Motos
/*********************************************************************************
*
Cambio de la configuracin del mdulo bluetooth
*
*
mediante comandos AT
*
*********************************************************************************/
//Variable para control de configuracin
boolean conf = false;
int espera = 1000;
void setup(){
pinMode(13,OUTPUT);
Serial.begin(57600);
digitalWrite(13, LOW);
}
void loop(){
if (conf){
// Parpadeo para verificar su funcionamiento
digitalWrite(13, HIGH);
// Enciende el LED
delay(espera);
// Espera
digitalWrite(13, LOW);
// Apaga el LED
delay(espera);
// Espera
}
else{
digitalWrite(13, HIGH); // Empieza el tiempo de espera para reconectar
Serial.println("Configuracin del mdulo bluetooth");
Serial.println("Conecte el TX del mdulo BT al RX del Arduino y el RX del
mdulo BT al TX del Arduino");
delay(15000);
// Espera de 15 segundos (se puede cambiar)
digitalWrite(13, LOW); // Tiempo de espera agotado para reconectar
Serial.print("AT");
delay(espera);
Con esta configuracin el nombre del mdulo bluetooth ser BTarduino, funcionar
a 57600 baudios y el pin de vinculacin ser 4242.
3.6.2. PRUEBAS
Tras la configuracin del mdulo bluetooth se pas a probar el mdulo. Para ello se
ide un sketch a travs del cual se manejara el LED de una placa Arduino UNO. Segn
el valor que se recibiera se encendera el LED, se apagara o parpadeara. Para poder
realizar la comunicacin con la placa Arduino se emple la aplicacin BlueTerm[29]
para Android que est disponible en su Play Store. Esta aplicacin lo que hace es enviar
Pgina 86 de 231
J. L. Prez Motos
y recibir datos entre el mvil y el dispositivo con el que est vinculado. As se emple el
siguiente montaje y se volc el siguiente cdigo en la placa de Arduino (ANEXO A.4).
Figura 3-48: Diagrama del sketch empleado para la prueba de funcionamiento del mdulo
bluetooth
Pgina 87 de 231
J. L. Prez Motos
3.7. ALIMENTACIN
Pgina 88 de 231
Componente
J. L. Prez Motos
20
Voltaje
recomendado
Consumo (mA)
De 7 a 12
Motor
360
L6205N
52
De 8 a 52
10
QTR-8RC
3'3
100
Bluetooth
3'3
J. L. Prez Motos
3.8. RESUMEN
En la siguiente tabla se detalla la lista de componentes empleados en el sistema:
Cantidad
Componente
Descripcin
Microcontrolador
Programador
Ruedas de traccin
Rueda de apoyo
Motores
Controlador motores
QTR-8RC
JY - MCU V1.06
Mdulo bluetooth
Soporte motores
Pila 9V recargable
Condensador 120 nF
Condensadores de polister
Condensador 220 nF
Condensador de polister
Condensador 15 nF
Condensador cermico
Condensador 6'8 nF
Condensadores cermicos
1N4148
Diodos
Resistencia 100 k
Resistencias
Resistencia 120
Resistencia
Pgina 90 de 231
J. L. Prez Motos
Pgina 91 de 231
CAPTULO 4.
J. L. Prez Motos
DISEO
Tras seleccionar todos los componentes que formaran el robot se pas a disear
propiamente el robot. Para unir todos los componentes se pensaron dos mtodos. El
primero de ellos, el ms sencillo, consista en utilizar una placa de topos para montar en
ella la mayora de los elementos y despus emplear una base para colocar las diferentes
ruedas que componen el robot. El segundo mtodo consista en disear una tarjeta de
circuito impreso (PBC, Printed Circuit Board) que diera sustento tanto a los elementos
elctricos como a los mecnicos.
La principal ventaja que ofrece el primer mtodo sobre el segundo es que le da al
robot ms versatilidad. Si se desea construir un robot para que realice diferentes tareas
es ms interesante esta opcin ya que cambiando la base sobre la que va el motor se
puede conseguir que este funcione de una forma o de otra. Por otro lado, la principal
ventaja que ofrece el segundo mtodo sobre el primero es que se pueden conseguir
diseos realmente pequeos. Al eliminar conexiones entre placa y base del robot se
gana en espacio, por lo que el diseo del robot resulta ms compacto.
Finalmente se escogi la opcin de disear un PBC en el que se incluyeran todos
los componentes del robot. Se estaba intentando realizar el robot ms pequeo posible,
por lo que esta opcin era la ms idnea, adems de que le daba al robot un aspecto
mucho ms profesional.
En los siguientes apartados se desarrollar cmo se llev a cabo el diseo del robot.
Destacar que se fue realizando en paralelo tanto el diseo elctrico como el diseo en s
del PBC. Esto se debi a que hasta no ver fsicamente como quedaban los componentes
en relacin a los dems no se eligieron las conexiones.
Como programas de diseo se emple para el diseo elctrico Eagle[30] y para el
diseo del PBC DesignSpark[31]. El primero de ellos tiene unas libreras con multitud
de componentes, adems de ser ms llamativo visualmente hablando, por lo que se
pens en l como software para diseo elctrico. El gran inconveniente de este
programa es que es se necesita adquirir una licencia para poder exprimir al mximo el
programa. De todas formas, la versin Freeware permite realizar esquemas elctricos,
Pgina 92 de 231
J. L. Prez Motos
por lo que en este aspecto no supone ninguna restriccin. El segundo nos permite de una
forma muy intuitiva disear PBCs, adems de ser un software libre. Por lo que se
decidi que fuera este el encargado del diseo del PBC. La conexin entre ellos permite
convertir archivos de Eagle a archivos de DesignSpark, pero no a la inversa.
Pgina 93 de 231
J. L. Prez Motos
Mdulo bluetooth: comparte los cuatro pines centrales del programador, por lo
que se pens en utilizar los mismos pines.
Tras este anlisis, se observ que sobraba algn pin del Arduino Pro Mini, por lo
que se pens en aprovechar dos ellos aadiendo al sistema dos diodos LED que servirn
para ofrecer informacin en forma de luz, como por ejemplo que haya terminado cierto
proceso, o que el robot debe girar. Para evitar que el diodo se queme se incluirn junto a
ellos dos resistencias de 220 para limitar as la corriente a unos 20 mA.
Adems, al necesitarse un total de 13 pines digitales, y al estar siendo utilizados los
pines digitales 0 y 1 (TX0 y RX1 respectivamente) se necesitaran configurar al menos
dos pines analgicos como digitales.
Despus se hizo un primer boceto en el que se colocaron todos los componentes y
que sirvi para hacerse una primera idea del diseo final que se buscaba.
Pgina 94 de 231
J. L. Prez Motos
Pgina 95 de 231
J. L. Prez Motos
El L6205N tiene diversas conexiones tanto con el Arduino como con los motores,
por lo que se pens situarlo en una zona intermedia de ambos componentes. Los
componentes que necesita este circuito integrado se colocaran en los alrededores de l.
Se pens en colocar la pila en la parte superior del PBC que dejasen libre tanto la
bola loca como el QTR-8RC y de esta forma ahorrar espacio. Estos dos elementos irn
por debajo del PBC mientras que la pila ir en la parte superior.
Por ltimo se pens que todo el plano del PBC formara un plano de masa, de esta
forma dara ms estabilidad elctrica al conjunto.
Figura 4-4: Diferentes representaciones del Arduino Pro mini. De izquierda a derecha: Eagle,
DesignSpark, realidad
Para poder realizar los diferentes diseos se han empleados los esquemas que hay
disponibles en la pgina de Arduino. El esquema elctrico era demasiado detallado, por
Pgina 96 de 231
J. L. Prez Motos
Pgina 97 de 231
J. L. Prez Motos
De esta forma se fij la posicin relativa del Arduino Pro Mini con respecto al
L6205N y al QTR-8RC.
Pgina 98 de 231
J. L. Prez Motos
Figura 4-7: Conexin entre Arduino Pro Mini y programador y mdulo bluetooth
Solo habra que tener especial cuidado en que en el mdulo bluetooth los terminales
Vcc y GND estn al revs.
Pgina 99 de 231
J. L. Prez Motos
Figura 4-8: Esquema en Eagle del L6205N y los componentes que necesita
J. L. Prez Motos
J. L. Prez Motos
pila ira en una plataforma superior. Tras varias pruebas, se lleg a la siguiente
configuracin:
Figura 4-10: Disposicin de los taladros de la rueda loca y conexin entre Arduino Pro Mini y
L6205N
J. L. Prez Motos
J. L. Prez Motos
De esta forma se consigui que no hiciera falta aadir ningn cable externo adems
de los que conectan los motores con el L6205N. Adems se realiz un 3D del diseo:
J. L. Prez Motos
J. L. Prez Motos
Tras esto se mont un prototipo para comprobar que todos los componentes
encajaban:
J. L. Prez Motos
J. L. Prez Motos
J. L. Prez Motos
J. L. Prez Motos
De esta forma la asignacin de pines del Arduino Pro Mini qued como sigue:
Funcin
Pin Arduino
pines digitales 0, 1
pines digitales 0, 1
Leds delanteros
pin digital 19
pines digitales 7, 8
Pin Arduino
Funcin
digital 0
digital 1
digital 2
digital 3 (PWM)
digital 4
digital 5 (PWM)
digital 6 (PWM)
digital 7
digital 8
digital 9 (PWM)
digital 10
Led izquierdo
digital 11
QTR-8RC sensor 3
digital 12
QTR-8RC sensor 5
digital 13
digital 14
QTR-8RC sensor 4
digital 15
QTR-8RC sensor 2
digital 16
Led derecho
digital 17
QTR-8RC sensor 0
digital 18
QTR-8RC sensor 1
digital 19
CAPTULO 5.
J. L. Prez Motos
J. L. Prez Motos
Una vez colocados todos los conectores se soldaron a la placa los diferentes
componentes, tales como los LEDs delanteros, los componentes que conforman el
circuito del L6205N y el interruptor que controla la alimentacin.
J. L. Prez Motos
Figura 5-3: Colocacin de los LEDs delanteros y los componentes del L6205N
Despus se atornill al PBC la rueda loca. Esta se encuentra muy prxima al QTR8RC, por lo que se prefiri montar este componente antes que la matriz de sensores
infrarrojos.
J. L. Prez Motos
J. L. Prez Motos
Por ltimo se atornill en la parte superior del robot una superficie para ofrecer
sustento a la pila. La pila se colocar sobre la parte delantera del robot para darle a este
ms estabilidad.
J. L. Prez Motos
CAPTULO 6.
PRUEBAS
DE
J. L. Prez Motos
LOS
COMPONENTES
DEL
ROBOT
En este apartado se van a desarrollar las diferentes pruebas a las que se someti al
robot para comprobar su perfecto funcionamiento.
Como ya se ha explicado con anterioridad, el Arduino Pro Mini carece de conversor
Serie USB, por lo que hay que emplear un conversor externo para programar el
Arduino. Para este proyecto se emple el conversor FTDI232[32].
Sensores infrarrojos.
Motores y LEDs.
Bluetooth.
J. L. Prez Motos
Figura 6-2: Diagrama del sketch empleado para la prueba de funcionamiento del QTR-8RC
Para poder mostrar los valores de forma clara, en primer lugar se calibran los
sensores para obtener los valores mximos y mnimos de cada sensor para despus
poder mapearlos. Adems se incluye un filtro para evitar valores indeseados. De esta
forma se consigue que los sensores que estn justo encima de la lnea muestren un valor
distinto de cero mientras que los sensores situados fuera de la lnea muestran cero.
Figura 6-3: Valores obtenidos en funcin de la posicin relativa del robot con respecto a la lnea
J. L. Prez Motos
Como los resultados obtenidos fueron satisfactorios, se pas a probar los motores.
6.2. MOTORES
Una vez comprobados los sensores infrarrojos se probaron los motores y los LEDs.
Conviene recordar del apartado 3.2 que se escogi que el robot empleara un sistema
diferencial. Esto quiere decir que para que el robot gire se deben aplicar diferentes
velocidades a cada rueda.
Adems, como se explic en el apartado 3.4, para controlar tanto la velocidad de
giro como el sentido de giro de las ruedas se va a emplear el circuito integrado L6205N.
Este permite que las ruedas giren como uno desee en funcin de las entradas de control
que reciba. Estas entradas de control se las proporciona el Arduino Pro Mini en forma
de pulsos PWM. Las seales PWM son seales cuadradas que mantienen constante su
periodo pero varan el tiempo que la seal est a nivel alto.
J. L. Prez Motos
De esta forma, las salidas PWM del Arduino Pro Mini ofrecen seales de 490Hz y
se controlan mediante un byte, es decir, valores de 0 a 255. As, para frenar el motor se
le dar al valor de control un 0, mientras que para hacer que vaya a su mxima
velocidad se le dar un 255[10].
Para probar los motores y los LEDs lo que se hizo fue programar que el robot
siguiera ciertas trayectorias y emplear los LEDs a modo de intermitentes: si el robot iba
recto se encenderan los dos LEDs, si giraba a la derecha que se encendiera el LED
derecho y si giraba a la izquierda que se encendiera el LED izquierdo.
De esta forma, se program que el robot realizara todas las posibles situaciones
(ANEXO A.6):
Marcha adelante.
Marcha atrs.
Giro a la izquierda.
Giro a la derecha.
cuenta con dos entradas, una para cada motor. La funcin en s consiste en analizar cada
una de las entradas por separado. Primero se comprueba si el valor es mayor o menor
Pgina 120 de 231
J. L. Prez Motos
que cero. Si es mayor o igual que cero se lleva el valor correspondiente a la entrada 1
del puente. Sin embargo, si la entrada es negativa se lleva a la entrada 2 del puente. De
esta forma se consigue controlar el sentido de giro de los motores.
Adems, como ya se ha explicado, los valores estn limitados entre 0 y 255. De
esta forma se emplea la funcin constrain, que lo que hace es estudiar si un valor est
entre dos lmites. Si el valor es mayor que el lmite superior, el valor tomar el valor del
lmite superior. Si el valor es inferior que el lmite inferior, el valor tomar el valor del
lmite inferior.
/*
********************************************************
*
Funcin para mover los motores segn el PWM
*
********************************************************
*/
void motor(int out1, int out2){
if (out1 >= 0){
analogWrite(in1A, constrain(abs(out1), 0, vMax));
analogWrite(in2A, 0);
}
else{
analogWrite(in1A, 0);
analogWrite(in2A, constrain(abs(out1), 0, vMax));
}
if (out2 >= 0){
analogWrite(in1B, constrain(abs(out2), 0, vMax));
analogWrite(in2B, 0);
}
else{
analogWrite(in1B, 0);
analogWrite(in2B, constrain(abs(out2), 0, vMax));
}
}
6.3. BLUETOOTH
Por ltimo se comprob que el bluetooth funcionara de forma correcta. Adems se
aprovech esta prueba para estudiar el comportamiento del robot al mezclar diferentes
componentes. As, en primer lugar se comprob la conectividad por bluetooth entre el
robot y el ordenador y despus la conectividad por bluetooth entre el robot y un mvil
Android.
J. L. Prez Motos
Sealar que al emplear tanto el mdulo bluetooth como el conversor los mismos
pines para enviar y recibir datos no podrn estar conectados al mismo tiempo. De esta
forma cada vez que se quiera programar el robot habr que desconectar el mdulo
bluetooth y una vez cargado el programa en el robot volver a conectar el bluetooth. Esta
accin se podra haber facilitado mediante la inclusin de un interruptor que
desconectara el mdulo bluetooth del interfaz serie durante la programacin y as no
hara falta separar fsicamente el mdulo bluetooth del robot para programarlo.
En primer lugar se realiz el sketch que ejecutara el robot. Para evitar que cada vez
que se iniciase el cdigo se calibrasen los sensores, se realizaron un par de medidas
sobre la pista que posteriormente se utilizara para observar los resultados para obtener
los valores mximos y mnimos de cada sensor.
Despus hubo que obtener el tiempo que tardaba Matlab en procesar los datos.
Matlab no realiza los clculos instantneamente, sino que presenta un pequeo retardo,
Pgina 122 de 231
J. L. Prez Motos
Figura 6-7: Diagrama del sketch empleado para la prueba de conexin entre robot y ordenador
Una vez configurado el robot se enviarn los datos por bluetooth, pero simulando
un puerto serie que se debe conocer. Para ello se debe vincular el ordenador con el
mdulo bluetooth. Lo que hay que hacer es que el ordenador detecte el mdulo
bluetooth y despus introducir la contrasea que este tiene asociada, en este caso 4242:
Despus hay que hacer clic con el secundario en el icono del bluetooth del rea de
notificacin y hacer clic en Abrir configuracin. Por ltimo en la pestaa Puertos COM
Pgina 123 de 231
J. L. Prez Motos
est el puerto que se debe utilizar. El puerto que se tiene que utilizar es el que en el
nombre tenga la extensin Dev B, en este caso es el puerto COM6:
Una vez obtenido el puerto asociado al bluetooth del robot se empieza a realizar el
programa de Matlab (ANEXO A.8). En primer lugar se crea un objeto serie en Matlab y
se abre para empezar a leer[33]:
%borrar previos
delete(instrfind({'Port'},{'COM6'}));
%crear objeto serie
s = serial('COM6','BaudRate',57600,'Terminator','CR/LF');
%abrir puerto
fopen(s);
Como se puede ver, la primera lnea de cdigo lo que hace es eliminar cualquier
aplicacin que est usando el puerto COM6. Despus se crea el objeto serie. En este
caso se va a denotar con s. En este punto habr que indicarle los baudios a los que
J. L. Prez Motos
funciona el mdulo bluetooth, en este caso 57600. Por ltimo se abre el puerto con la
funcin fopen.
%Tiempo que dura la medicin en segundos
tmax = 20;
%Inicializar
t = 0;
El ncleo del programa es el bucle de medida, en el cual iremos leyendo del puerto
serie los datos en el formato que hemos especificado en la funcin fscanf. En este caso,
desde el robot se est enviando el estado de los seis sensores de forma consecutiva
separando cada valor mediante un espacio. Despus se emplea la funcin bar para
dibujar el diagrama de barras en funcin de los valores de los sensores y con la funcin
drawnow se muestra por pantalla el diagrama de barras. Si no se incluyera solo se
mostrara el ltimo resultado. Aclarar tambin el funcionamiento de tic y toc. Son dos
variables internas que usa Matlab. Con tic se empieza a ejecutar un reloj interno y con
toc se puede acceder al valor de este reloj. De esta forma, si se le va dando en cada ciclo
a t el valor de toc se podr conocer cundo se ha alcanzado el tiempo mximo.
clc;
%% Cerrar y eliminar el puerto creado
fclose(s);
delete(s);
clear s;
J. L. Prez Motos
J. L. Prez Motos
Figura 6-11: Diagrama del sketch empleado para la prueba de funcionamiento de la conexin
entre robot y Android
Como los resultados obtenidos fueron satisfactorios, se concluy que todas las
partes del robot funcionaban correctamente y se empez a programar el sigue lneas.
J. L. Prez Motos
CAPTULO 7.
J. L. Prez Motos
SIGUE LNEAS
Figura 7-1: Diagrama del sketch empleado por el robot para seguir lneas
Declaracin de variables.
Seguimiento de la lnea.
Algoritmo PID.
J. L. Prez Motos
J. L. Prez Motos
J. L. Prez Motos
Todos los sensores no presentan las mismas lecturas ante una misma situacin.
De esta forma, al realizar una calibracin inicial se pueden detectar cules son
Pgina 132 de 231
J. L. Prez Motos
las mximas y las mnimas medidas que realiza cada sensor y despus ponderar
las medidas en funcin de estos valores. De otra forma lo que para un sensor
puede significar estar sobre la lnea negra para otro simplemente puede
significar estar parcialmente sobre la lnea negra.
Se puede emplear el robot para que siga la lnea negra sobre otras superficies
que no sean necesariamente blancas. Cuando se empez a realizar pruebas con el
robot era bastante laborioso tener que estar usando solo superficies blancas. De
esta forma se puede emplear cualquier color, evitando evidentemente el negro.
As, simplemente utilizando cinta aislante negra y el parqu de tu casa uno se
puede construir su propio trazado.
Figura 7-2: Diagrama del sketch para calibrar los sensores infrarrojos
Una vez entrado en la fase de calibracin, lo primero que se hace es encender los
dos LEDs delanteros para indicar que el robot est en la fase de calibracin. Despus se
fuerza al robot a girar sobre s mismo a una determinada velocidad y durante dos
segundos los sensores realizan mediciones. Estas mediciones se comparan con las
mximas y mnimas medidas que ha presentado cada sensor hasta ese momento con la
J. L. Prez Motos
Figura 7-3: Diferencia entre los valores devueltos por los sensores infrarrojos con y sin mapear
Al mapear los valores de los sensores se consigue una medida ms fidedigna con la
realidad. Sin mapear es posible que un sensor que est sobre la lnea negra ofrezca una
medida menor a la que ofrece un sensor que no est sobre la lnea negra.
J. L. Prez Motos
Tras mapear los sensores se filtran estos valores con la funcin filtro. Es posible
que por el motivo que sea los sensores ofrezcan una medida que se salga de los lmites
establecidos. Este filtro evita que eso suceda. Adems, este filtro permite contabilizar
cuntos sensores estn sobre la lnea. Si resulta que no hay ningn sensor sobre la lnea
negra es que el robot se ha salido del trazado. Este caso se tratar en el apartado 7.6. Por
otro lado, si al menos un sensor ve lnea se ejecuta la funcin si_linea.
Con esta funcin lo que se pretende es barajar las opciones posibles existentes si el
robot est sobre la lnea. Lo primero que hace esta funcin es detectar si hay marcas de
bifurcaciones en los laterales del trazado. Si se recuerda del apartado 2.1.2, se marca en
los laterales del trazado con pequeas marcas la direccin que deber tomar el robot en
la siguiente bifurcacin.
As, lo que hace esta funcin es detectar si el robot se encuentra en alguna de estas
posiciones. Si se encuentra en alguna de ellas se ejecuta la funcin si_marca, la cual
guarda qu marca era y obliga al robot a seguir recto. Por otro lado, si el robot no se
encuentra en ninguna de esas posiciones ejecuta la funcin calculo_posicion.
Esta funcin es la que permite determinar la posicin del robot en relacin a la lnea
negra. Para ello aplica la siguiente ecuacin:
Pgina 135 de 231
J. L. Prez Motos
)
)
En ella se tiene en cuenta tanto el valor de cada sensor como el peso que tiene
asociado cada sensor. De esta forma, el valor que tiene que seguir el robot para ir
completamente recto es 25.
Tras obtener la posicin relativa del robot con respecto a la lnea, se estudia si el
robot est en una bifurcacin. Como se explic en el apartado 6.1, el nmero mximo de
sensores que pueden detectar la lnea negra al mismo tiempo es tres. Por lo tanto, en el
momento en el que ms de tres sensores detecten lnea es que hay presente una
bifurcacin. De esta forma, para obligar al robot a tomar una cierta direccin se cambia
el valor que tiene que seguir el robot a 0, a 25 o a 50 en funcin de si tiene que ir a la
izquierda, seguir recto o ir a la derecha. As se consigue que el robot site la mayora de
sus sensores sobre la direccin que debe tomar y cuando vuelva a seguir el camino de
forma normal (consigna de 25) ya estar sobre el camino a seguir.
J. L. Prez Motos
Figura 7-6: Obligacin de giro del robot segn las marcas de bifurcacin
Tras detectar las posibles bifurcaciones se calcula el error. Para calcularlo se aplica
la siguiente ecuacin:
(
Adems se almacena el ltimo error que ha tenido el robot por si este se sale de la
trayectoria y de esta forma poder volver a la lnea.
Una vez repasadas todas las posibles configuraciones que pueden aparecer si el
robot est sobre la lnea se aplica el control PID. Debido a su importancia se explicar
en el siguiente apartado.
7.5. PID
Cuando se estudiaron los diferentes robots sigue lneas ya existentes prcticamente
la totalidad de ellos empleaban un control PID para corregir la posicin del robot y
hacer que este siga la trayectoria de forma correcta. Pero ninguno de ellos contaba con
ninguna herramienta para obtener los valores ptimos de las constantes que forman este
control, sino que simplemente iban probando diferentes valores hasta que consideraban
que el robot segua lo suficientemente bien la lnea.
Pgina 137 de 231
J. L. Prez Motos
En los siguientes apartados se har una breve introduccin sobre el control PID,
despus se describir una herramienta para obtener valores ptimos de las constantes y
por ltimo se aplicar esta herramienta en el robot.
En el clculo del controlador PID intervienen tres parmetros, los cuales pueden ser
interpretados en funcin del tiempo. La parte proporcional P depende del error actual, la
parte integral I depende de la suma de todos los errores pasados y la parte derivativa D
es la prediccin de errores futuros, basndose en la tasa de cambio actual. La suma
ponderada de los tres trminos permiten ajustar un proceso mediante un elemento de
control como por ejemplo la velocidad que debe alcanzar un motor de corriente
continua.
J. L. Prez Motos
Tiempo de pico tp: es el tiempo que tarda la seal de salida del sistema en
alcanzar el pico mximo de sobreoscilacin.
Tiempo de estabilizacin ts: tiempo que tarda la seal de salida del sistema en
entrar en la banda del 5% alrededor del valor final y ya no vuelve a salir de ella.
Figura 7-8: Representacin del tiempo de pico, del pico de sobreoscilacin y del tiempo de
estabilizacin
J. L. Prez Motos
7.5.1.1.
TRMINO PROPORCIONAL
Siendo e el error en un instante de tiempo, cuanto mayor sea este error ms rpida
ser la respuesta y viceversa.
Un controlador proporcional no siempre alcanzar su valor objetivo, ya que no se
eliminar el error de estado estacionario. Para eliminarlo hay que emplear el trmino
integral.
7.5.1.2.
TRMINO INTEGRAL
J. L. Prez Motos
( )
7.5.1.3.
TRMINO DERIVATIVO
El trmino derivativo calcula la variacin del error mediante la pendiente del error
en cada instante de tiempo, es decir, la primera derivada con respecto al tiempo y
multiplica esa variacin del error con la ganancia derivativa Kd, la cual indica la
cantidad de accin derivativa respecto de toda la accin de control.
( )
7.5.1.4.
Los trminos proporcional, integral y derivativo son sumados para hallar la salida
del controlador PID, sabiendo que u(t) es la salida, la ecuacin que define al algoritmo
es la siguiente:
( )
( )
J. L. Prez Motos
( )
( )
( )
( )
( )
Estabilidad
Parmetro
Kp
Aumenta
Aumenta
Aumenta
Disminuye
Disminuye
Ki
Disminuye
Aumenta
Aumenta
Lo elimina
Disminuye
Aumenta
Disminuye
Disminuye
No afecta
Aumenta
Kd
Tiempo de
Sobreoscilacin
estabilizacin
Error en
estado
estacionario
Tiempo de
pico
Tabla 7.1: Efectos en el sistema que tiene el aumento de cada uno de los parmetros
J. L. Prez Motos
J. L. Prez Motos
J. L. Prez Motos
Controlador
Kp
Ki
Kd
Kc/2
PI
Kc/2'2
1'2Kp/Tc
PID
0'6Kc
2Kp/Tc
KpTc/8
J. L. Prez Motos
como la diferencia entre el error actual y el error anterior en cada instante de tiempo. Al
igual que en la parte integral, hay que aadir un trmino que convierta los milisegundos
en segundos. De esta forma se obtiene:
Como se puede observar, el resultado que se obtiene se lleva a cada motor. Sealar
que a cada motor se le aplica la correccin del controlador PID con signos diferentes.
De esta forma se consigue que cuando se produzca un error el robot tienda a volver a la
posicin correcta. Para entenderlo mejor se va a suponer el siguiente supuesto:
}
Debido a que el robot presenta un error actual inferior al error anterior est
acercndose a la posicin central. Adems, como este error es positivo, recordando los
pesos que se le da a cada sensor del apartado 7.4, la lnea se encuentra en la parte
derecha del robot. As, para que el robot se vuelva a centrar este necesita girar a la
derecha. Para conseguir eso debe ir ms rpido su rueda izquierda, el motor B. Por lo
tanto, en principio, los signos asignados a cada motor estn bien escogidos.
J. L. Prez Motos
Tras obtener la expresin que emplear el Arduino Pro Mini para ejecutar el
controlador PID se procedi a pensar en el circuito que se emplear en la prueba. En el
mtodo de Ziegler-Nichols se debe someter al sistema a una entrada escaln. En este
caso se pens que se podra emplear el siguiente circuito:
En un primer lugar el robot encuentra una zona recta sin perturbaciones. Despus
encuentra el escaln. Y por ltimo vuelve a una zona recta sin perturbaciones. Es
importante que en ningn momento el robot deje de detectar la lnea, por lo que el
escaln no debe ser muy grande. De esta forma, segn el mtodo de Ziegler-Nichols, lo
que se pretende es que tras el escaln el robot empiece a oscilar de una forma constante:
Adems, para evitar que el robot tuviera que calibrarse cada vez que iniciaba la
prueba, se hicieron varias medidas sobre el circuito y se hizo una media con los valores
mximos y mnimos obtenidos para cada sensor.
Tambin se realiz un programa en Matlab para interpretar los datos (ANEXO
A.11). En primer lugar, al igual que en el apartado 6.3.1, se cre un objeto serie y se
abri. Tambin se defini el tiempo mximo, as como el nmero de muestras que se
toma por segundo.
%borrar previos
delete(instrfind({'Port'},{'COM6'}));
%crear objeto serie
s = serial('COM6','BaudRate',57600,'Terminator','CR/LF');
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');
%abrir puerto
fopen(s);
% parmetros de medidas
tmax = 10; % tiempo de captura en s
rate = 33; % resultado experimental
J. L. Prez Motos
Tras esto, de nuevo con la ayuda de las variables tic y toc, se ejecuta el bucle de
toma de datos.
% ejecutar bucle cronometrado
tic
while t<tmax
t = toc;
% leer del puerto serie
puerto = fscanf(s,'%d %d')';
v1(i)=puerto(1)/25;
v2(i)=puerto(2)/25;
% dibujar en la figura
x = linspace(0,i/rate,i);
set(l1,'YData',v1(1:i),'XData',x);
set(l2,'YData',v2(1:i),'XData',x);
drawnow
% seguir
i = i+1;
end
En primer lugar se lee el puerto serie que se ha creado al inicio del programa y se le
indica la forma en la que le llegan los datos. El primer dato es el error, mientras que el
segundo es la referencia que sigue, en este caso se busca que el error sea 0. Tras esto se
dibujan los resultados. De esta forma se obtuvieron las siguientes grficas:
J. L. Prez Motos
Figura 7-13: Resultados de la prueba. De izquierda a derecha y de arriba abajo: Kp=1, Kp=3,
Kp=5, Kp=7, Kp=8, Kp=9
J. L. Prez Motos
En esta ltima grfica se puede observar como el sistema tras la primera oscilacin
el sistema sigue oscilando de forma constante. De esta forma, los resultados que se
obtuvieron fueron:
As, una vez definidos los parmetros del PID se tena prcticamente completo el
sketch. Para finalizarlo se trat qu debera realizar el robot en caso de salirse del
trazado.
J. L. Prez Motos
Se puede observar que con el PID obtenido por el mtodo de Ziegler-Nichols que,
aunque aparece una sobreoscilacin del 40%, el tiempo de estabilizacin es de tan solo
03 segundos. Adems se puede apreciar en la grfica de los motores que se encuentran
prcticamente todo el rato girando a la velocidad nominal (en este caso 100). Por lo que
se puede concluir que este controlador es muy apropiado para la finalidad de este robot.
J. L. Prez Motos
Figura 7-16: Resultados empleando Kp=15. Arriba se representa el error y abajo los PWM de los
motores
J. L. Prez Motos
Figura 7-17: Resultados empleando Ki=250. Arriba se representa el error y abajo los PWM de
los motores
J. L. Prez Motos
Figura 7-18: Resultados empleando Kd=1. Arriba se representa el error y abajo los PWM de los
motores
J. L. Prez Motos
CAPTULO 8.
J. L. Prez Motos
Figura 8-1: Diagrama del funcionamiento del control remoto del robot. A la izquierda se
representa el sketch del robot. A la derecha se representa la aplicacin Android
J. L. Prez Motos
Se puede ver que el sistema est formado por dos partes. Por un lado el robot (a la
izquierda) (ANEXO.A.12) y por otro lado la aplicacin Android (ANEXO A.13). En
primer lugar se va a explicar cmo se realiz la aplicacin Android y despus el
programa del robot.
Pero la gran desventaja de este programa es que no es software libre, por lo que hay
que pagar una licencia para poder utilizar el programa en plenas condiciones. Existe una
versin de prueba, pero no permite cargar ningn tipo de librera, por lo que est muy
J. L. Prez Motos
limitado. El precio de esta licencia oscila entre 50 y 500, por lo que se desech esta
opcin.
Buscando ms se lleg a dar con Amarino[36]. Amarino est formado por una
librera de Arduino junto a una aplicacin Android. De esta forma se puede comunicar
de una forma sencilla un dispositivo Android con una tarjeta de Arduino. As, mediante
una conexin bluetooth, se pueden controlar los diferentes pines del Arduino: nombrar
los pines como pines de entrada o salida, controlar los pines digitales PWM,
J. L. Prez Motos
J. L. Prez Motos
Tras esto se debe abrir Eclipse y seguir la siguiente ruta: File -> New -> Project ->
Android Project from Existing Code. Tras esto se elige la ruta donde ha exportado
Processing el cdigo y ya se tiene disponible el cdigo en Eclipse.
Una vez comprobada la conexin entre Processing y Eclipse se pas a desarrollar la
aplicacin Android.
8.1.1.1.
J. L. Prez Motos
acc_sensor: esta variable de tipo Sensor permite elegir el tipo de sensor que se
quiere emplear. En la actualidad existen multitud de tipos de sensores en los
dispositivos Android, tales como acelermetros, de temperatura, giroscopios, de
luz, magnticos...
8.1.1.2.
ins: esta variable de tipo InputStream permite recibir datos del robot. El formato
de estos datos es el byte.
ons: esta variable de tipo OutputStream permite enviar datos al robot. El formato
de estos datos es el byte.
J. L. Prez Motos
8.1.2. CONFIGURACIN
En la funcin setup se declaran diferentes propiedades de la aplicacin. Con la
funcin size se obtiene el ancho y alto de la pantalla del telfono. Esto ser de gran
utilidad a la hora de querer representar cosas por pantalla ya que no todos los
dispositivos Android tienen las mismas dimensiones. As, al asignar el ancho y el alto
de la pantalla a unas variables se podrn ofrecer datos por pantalla en relacin a estas
medidas.
Tambin se fijar que la posicin de la pantalla sea apaisada con la funcin
orientation y que el tipo de fuente que emplee la aplicacin sea la que emplea por
defecto el telfono. Adems se evitar que la pantalla se apague mientras se est
ejecutando la aplicacin al emplear el flag FLAG_KEEP_SCREEN_ON.
Por ltimo se instancian dos variables, pwmA y pwmB, y se definen todas sus
variables para ms adelante poder representar el estado de los motores.
J. L. Prez Motos
Para mostrar los dispositivos de una forma en la que se puedan escoger de forma
sencilla, se mostrar de cada dispositivo tanto el nombre como como la direccin mac
del dispositivo.
J. L. Prez Motos
Sin embargo, la conexin que se va a realizar no es una conexin al uso, sino que se
va a simular un puerto serie. Para ello hay que variar los primeros trminos. As se
obtiene que el UUID para realizar una conexin bluetooth simulando un puerto serie es
el siguiente[41]:
Una vez definido correctamente el UUID solo queda conectar el socket e indicar
cul ser la forma de recibir y enviar datos. Para ellos se emplean las extensiones
getInputStream y getOutputStream, respectivamente. De esta forma, la conexin queda
establecida.
socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString("000011010000-1000-8000-00805F9B34FB"));
Method m = dispositivo.getClass().getMethod("createRfcommSocket", new Class[] {
int.class });
socket = (BluetoothSocket) m.invoke(dispositivo, 1);
socket.connect();
ins = socket.getInputStream();
ons = socket.getOutputStream();
un acelermetro es[42]:
Esto quiere decir que, si el dispositivo Android se encuentra en reposo, la media del
acelermetro ser
como medida
J. L. Prez Motos
La lectura de los acelermetros no es algo que se realice de forma puntual, sino que
es un proceso que se va a estar realizando continuamente en segundo plano. Es por ello
por lo que la configuracin del acelermetro se incluye dentro de la funcin onResume.
En primer lugar lo que se debe hacer es definir el SensorManager, ya que es el
encargado de permitir los accesos a los sensores del telfono:
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Despus se debe crear una variable que recoja los datos que le enven los sensores.
Esta ser la variable que recoja las variaciones de los acelermetros:
accSensorEventListener = new MySensorEventListener();
Despus se eligen los sensores de los que se quiera extraer informacin. En este
caso solo se tendrn en cuenta los acelermetros. Si se deseara algn otro sensor solo
habra que cambiar el TYPE:
acc_sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
J. L. Prez Motos
Por ltimo se asocia el SensorEventListener, junto al sensor tipo de sensor que hace
referencia y al SensorManager empleado. Adems tambin hay que indicar el tipo de
delay
que
se
le
quiere
dar
la
aplicacin.
Existen
cuatro
tipos:
SENSOR_DELAY_GAME,
velocidad
recomendada
para
juegos;
por lo que habr que incluir algn filtro para evitar lecturas no deseadas.
Por ltimo estos valores tienen mucho ruido, por lo que habr que incluir otro
filtro para filtrar este ruido.
J. L. Prez Motos
Figura 8-10: Valores de los acelermetros en dos instantes consecutivos estando el dispositivo
Android en reposo sobre la mesa
Figura 8-11: Valores que puede tomar el acelermetro del eje x. Representacin de 9
Pgina 167 de 231
J. L. Prez Motos
El segundo filtro que se realiza es para evitar que el ruido haga que se tome una
mala medida. Para ello lo que se hace es tomar como dato que se enviar al robot la
media de las dos ltimas medidas.
El ltimo filtro, el de limitar los valores para que estn entre
, se llevar a cabo
en el propio robot. Es el filtro que menos acta, ya que es raro que un acelermetro
ofrezca como resultado ms de 10. As que tras realizar diversas pruebas se obtuvieron
mejores resultados cuando este filtro lo realizaba directamente el robot.
J. L. Prez Motos
De forma anloga, los valores que recibir el dispositivo Android sern los PWM
de los motores del robot. En Arduino estos valores oscilarn entre 0 y 255, por lo que de
nuevo hay que procesar los datos para que ambas plataformas se entiendan.
Una vez que los datos son procesados se procede al envo y recepcin de datos.
Para el envo de datos se emplea la variable ons, que es de tipo OutputStream, y la
funcin write de la siguiente forma:
ons.write(valor,0,valor.length);
As, se escribe en el puerto serie los datos que hay en la variable valor (vector de
dos componentes que almacena los valores de los acelermetros filtrados), desde la
posicin 0 del vector y se le indica la longitud total que tiene que enviar[45].
Anlogamente, para recibir datos del robot se emplea la variable ins, que es de tipo
InputStream, y la funcin read de la siguiente forma:
while(ins.available() > 0){
ins.read(ardu,0,ardu.length);
}
De esta forma, lee cuntos bytes hay en el InputStream y los coloca en el vector
ardu (vector de cuatro componentes que almacena los PWM y los signos de los motores
del robot), desde la posicin 0 y hasta la longitud total del vector ardu.
J. L. Prez Motos
J. L. Prez Motos
En tercer lugar se desarroll el movimiento del crculo. Este estara relacionado con
los acelermetros. Adems se pens que para que fuera ms visual la transparencia del
crculo fuera variando tambin cuanto ms se alejase de la situacin de reposo. Como ya
se ha explicado, al final result ms complicado obtener las relaciones matemticas que
lo que es dibujar el crculo en s:
strokeWeight(2);
stroke(2,52,77);
fill(0, 255, 255, 10 + sqrt(ax*ax+ay*ay)*245/15);
ellipse(constrain(map(ax,
-10,
10,
width/2-l/2+width/40,
width/2+l/2-width/40),
width/2-l/2+width/20, width/2+l/2-width/20),
constrain(map(ay, -10, 10, height/2-l/2+width/40, height/2+l/2-width/40), height/2l/2+width/20, height/2+l/2-width/20),width/20, width/20);
J. L. Prez Motos
Figura 8-15: Representacin de los acelermetros. En este caso el robot ira marcha atrs y hacia
la derecha
J. L. Prez Motos
Figura 8-16: Interfaz final de la aplicacin Android. En este caso el robot estara trazando una
circunferencia en sentido contrario a las agujas del reloj
Dentro de este archivo se deber aadir una variable de tipo string cuyo nombre sea
app_name y el nombre de la aplicacin. En este caso se le va a llamar Robot Control
Remoto.
Pgina 173 de 231
J. L. Prez Motos
Para esta aplicacin se ha decidido emplear como logo el diagrama que representa a
los acelermetros. De esta forma, se debe guardar el logo que se haya creado dentro de
la ruta res/drawable, res/drawable-hdpi y res\drawable-ldpi desde el explorador de
archivos.
J. L. Prez Motos
deben configurar los diferentes pines que controlan el puente en H como pines de salida
y en tercer lugar preparar los motores. Para ello se ponen todas las entradas a nivel bajo
y se activan los enables de ambos puentes. Adems se apagan ambos LEDs delanteros
del robot.
En los apartados siguientes se describir cmo recibe y enva datos el robot.
.
giro = Serial.read() - 10;
vel = Serial.read() - 10;
filtro(vel, -10, 10);
filtro(giro, -10, 10);
Una vez obtenidos los valores se mapean para poder traducirlos en velocidades de
los motores. Hay que recordar que estos estn acotados desde 0 hasta 255. Tambin hay
que tener en cuenta que la direccin del acelermetro del eje x es inversa con respecto al
movimiento del robot. Esto quiere decir que un valor positivo de este acelermetro
corresponde con que el robot vaya marcha atrs. Para solucionar esto, la variable de la
velocidad se mape con los lmites cambiados Adems, tras diversas pruebas, se ajust
para que el giro mximo fuera solo de un 20%. Giros mayores hacan que el robot se
controlase peor.
J. L. Prez Motos
Por ltimo, tras haber obtenido las velocidades de ambos motores, se llevan estas a
los motores. Hay que tener en cuenta que para que el robot gire adecuadamente los
signos de giro debern ser distintos en ambos motores.
motor(velm - girom, velm + girom);
CAPTULO 9.
J. L. Prez Motos
TELEMETRA
Tras terminar la aplicacin Android que permite controlar el robot de forma remota,
se pens en realizar una aplicacin que permitiera recoger datos en tiempo real del robot
mientras se encuentra siguiendo la lnea. De esta forma se podra comprobar el
funcionamiento tanto de los sensores como de los motores.
Figura 9-1: Diagrama del funcionamiento de la telemetra del robot. A la izquierda se representa
el sketch del robot. A la derecha se representa la aplicacin Android
El sketch que emplea el robot es el mismo que el que empleaba el robot para seguir
la lnea, pero se han aadido las siguientes lneas de cdigo para enviar los datos al
dispositivo Android, sin olvidar que hay que codificar los datos antes de enviarlos:
J. L. Prez Motos
Serial.write(byte(constrain(abs(motorA),0,vMax)-128));
if (motorA >= 0){
Serial.write(byte(1));
}
else{
Serial.write(byte(2));
}
Serial.write(byte(constrain(abs(motorB),0,vMax)-128));
if (motorB >= 0){
Serial.write(byte(1));
}
else{
Serial.write(byte(2));
}
Serial.write(byte(posicion));
De esta forma se envan al dispositivo Android cinco valores: los PWM de los
motores, los signos que tienen estos PWM y la posicin relativa del robot con respecto a
la lnea.
Para la representacin grfica de los resultados se pens en utilizar una interfaz
similar a la que se emplea en la Frmula1.
Figura 9-2: Telemetra de Bruno Senna (Williams-Renault) en el Gran Premio de la India 2012
J. L. Prez Motos
Para realizar esta aplicacin se emple gran parte del cdigo de la otra aplicacin
(ANEXO A.14). Para que los datos se representen de forma continua en la pantalla del
dispositivo se van a emplear vectores de longitud igual al ancho de la pantalla. Despus,
en cada iteracin se guardar el valor de Xi en Xi-1. En primer lugar se crean las
variables donde se van a guardar los valores.
pwmA = new int[width];
pwmB = new int[width];
posicion = new int[width];
Despus se mapean los resultados para que queden las diferentes grficas de una
forma ordenada. De esta forma, el resultado final es el siguiente:
J. L. Prez Motos
10.1.1. SALARIO
Ingenieros
Meses
Sueldo/mes
1.705,00
Total
Total
10.230,00
10.230,00
Porcentaje
Contingencias Generales
28,30%
8,90%
Accidentes
0,99%
Total
38,19%
3.906,84
Importe
Salario
10.230,00
Cargas sociales
3.906,84
Total
14.136,84
Tabla 10.3: Coste de mano de obra
J. L. Prez Motos
Unidades
19,00
19,00
15,13
15,13
Ruedas
Unidades
34,13
Total
Precio unitario Total
6,17
6,17
7,20
7,20
Motores
Unidades
13,37
Total
Precio unitario Total
15,97
31,94
5,08
5,08
Controlador motores
L6205N
Sensores infrarrojos
Array de sensores infrarrojos QTRC-8RC
Comunicacin
Mdulo bluetooth JY-MCU
Alimentacin
Unidades
37,02
Total
Precio unitario Total
Unidades
14,06
14,06
Total
Precio unitario Total
Unidades
14,40
14,40
14,40
Total
Precio unitario Total
Unidades
14,06
14,05
14,05
14,05
Total
Precio unitario Total
Pilas 9V recargable
7,08
14,16
Cargador
20,20
20,20
Componentes electrnicos
Unidades
34,36
Total
Precio unitario Total
0,04
0,08
0,10
0,10
0,03
0,03
0,02
0,04
Diodo 1N4148
0,01
0,02
Resistencia 100k
Resistencia 120
0,01
0,02
0,01
0,01
Leds
0,02
0,04
0,04
0,04
Soporte
PCB
Unidades
0,38
Total
Precio unitario Total
0,0044
100,00
Total
Total
0,44
0,44
162,21
Pgina 181 de 231
J. L. Prez Motos
Importe
75,00
Total
75,00
Tabla 10.5: Gastos varios
Importe
Porcentaje
14.136,84
162,21
75,00
10%
1.413,68
10%
16,22
10%
7,50
Total
Importe
1.437,40
J. L. Prez Motos
Importe
14.136,84
Coste de materiales
162,21
Gastos varios
Gastos generales
Subtotal
1.437,40
15.811,45
I.V.A. (21%)
Subtotal
75,00
3.320,40
19.131,86
Tabla 10.7: Importe total del proyecto
J. L. Prez Motos
11.1.1. TAMAO
El primer punto fuerte del robot es su tamao. Se ha conseguido que en 58x76mm
integrar todo un sistema capaz de seguir lneas y de ser controlado a distancia mediante
un dispositivo Android. Cuando se inici el diseo del robot se puso como uno de los
objetivos a conseguir el hacerlo ms pequeo que el Pololu 3Pi. Este abarca una
superficie de 70cm2, mientras que nuestro robot abarca 44cm2, es decir, es un 37% ms
pequeo. Este logro ha sido posible gracias al estudio pormenorizado de cada uno de los
componentes que forman el robot y al aprovechamiento mximo del espacio disponible.
J. L. Prez Motos
11.1.2. PESO
El segundo punto fuerte es su peso. Todo el conjunto pesa apenas 135g, frente a los
243g que pesa el Pololu 3Pi, incluidas las pilas. El hecho de que la mayora de piezas
sean de plstico ha facilitado lograr este objetivo que tambin se fij al inicio del diseo
del robot.
11.1.3. VELOCIDAD
El tercer punto fuerte es su velocidad. Haciendo pruebas en circuitos sin apenas
curvas se han alcanzado velocidades de hasta 72cm/s, por lo que supera velocidad del
Pocketbot 2 que se haba puesto como objetivo, 70cm/s.
11.1.4. COMUNICACIN
El ltimo punto fuerte del robot es el de la comunicacin. Hasta la fecha pocos
robots de estas caractersticas incluyen algn tipo de conexin inalmbrica. Adems, el
hecho de poder recoger datos y de controlarlo a distancia es un punto muy a tener en
cuenta para proyectos similares que se realicen en el futuro.
J. L. Prez Motos
11.2.2. COSTE
Otro de los objetivos marcados al inicio del proyecto fue que el robot costara menos
de los 100 que cuesta el Pololu 3Pi. Este no incluye ni programador ni pilas, por lo que
quitando esa parte del presupuesto nuestro robot costara producirlo 11228.
J. L. Prez Motos
Microcontrolador
Ruedas
Motores
Controlador motores
Sensores infrarrojos
Comunicacin
Componentes electrnicos
Soporte
Figura 11-4: Representacin de los costes segn componentes quitando los componentes que no
incluye el Pololu 3Pi
En el grfico se puede ver que prcticamente un tercio del valor del robot es el
coste asociado a los motores, por lo que podra ser interesante buscar otras opciones que
ofrezcan las mismas caractersticas pero por un precio menor.
Tambin se podra ahorrar algo de dinero en el controlador de los motores. Existen
otras opciones, como los L293N, que por la mitad de dinero ofrecen las mismas
caractersticas que el L6205N empleado en este robot.
J. L. Prez Motos
pruebas, como por ejemplo las pruebas realizadas para calibrar los parmetros PID,
requieran un tiempo excesivo.
Para solventar este problema Arduino posee una librera llamada SoftwareSerial[9].
Por defecto la comunicacin serie en un Arduino Pro Mini se realiza por los pines
digitales 0 y 1. Esta librera permite que la comunicacin serie se realice a travs de
otros pines. De esta forma es posible tener mltiples puertos series por software y no
hara falta desconectar dispositivos.
J. L. Prez Motos
de Carrera apoyndose en la robtica y que este proyecto sirva para futuros proyectos.
J. L. Prez Motos
BIBLIOGRAFA
RECURSOS BIBLIOGRFICOS
[1]
[4]
Iriarte Pastor, Aitor; Zuazu Ayesa, Carlos. Proyecto Arduino UPNA. Proyecto
[7]
Media. 2011.
[8]
Pamplona, 2010.
[9]
[10]
RECURSOS ELECTRNICOS
[11]
http://aess.upc.es/aessbot/documentacion/normativa_aessbot2012_rastreadores_esp.pdf
[12]
http://www.pololu.com/file/0J137/Pololu3piRobotGuiaUsuario.pdf
[13]
http://www.bricogeek.com/shop/robotica/106-seguidor-de-lineas-pololu-3pi.html
[14]
Asociacin
de
Robtica
J. L. Prez Motos
Domtica
de
Espaa.
Proyecto
n00b0t:
http://foro.webdearde.com/viewtopic.php?f=6&t=3404&sid=d927e9812f6e45440f4b7b
c2e682743a
[15]
[16]
[17]
[18]
[19]
[20]
[21]
Arduino: http://arduino.cc/
[22]
[23]
[24]
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERA
TURE/DATASHEET/CD00002345.pdf
[25]
8x.pdf
[26]
[27]
http://www.hobbycomponents.com/index.php?route=product/product&product_id=116
[28]
Comandos AT:
http://elecfreaks.com/store/download/datasheet/Bluetooth/HC0305%20serail%20module%20AT%20commamd%20set%20201104%20revised.pdf
[29]
Aplicacin BlueTerm:
https://play.google.com/store/apps/details?id=es.pymasde.blueterm&hl=es_419
[30]
Eagle: http://www.cadsoftusa.com/
[31]
DesignSpark: http://www.designspark.com/
[32]
http://www.bricogeek.com/shop/295-conversor-serie-usb-ftdi232.html
[33]
http://wechoosethemoon.es/2011/07/15/arduino-matlab-adquisicion-de-datos/
[34]
[35]
Basic4Android: http://www.basic4ppc.com/
Pgina 191 de 231
[36]
Amarino: http://www.amarino-toolkit.net/
[37]
[38]
Processing: http://processing.org/
[39]
J. L. Prez Motos
http://developer.android.com/reference/android/hardware/SensorManager.html
[40]
http://developer.android.com/guide/topics/connectivity/bluetooth.html
[41]
[42]
http://developer.android.com/reference/android/hardware/SensorEvent.html
[43]
[44]
[45]
http://www.lab.dit.upm.es/~lprg/material/apuntes/io/streams.htm
[46]
J. L. Prez Motos
ANEXO A: CDIGOS
DIG17
DIG18
DIG16
DIG15
DIG14
DIG9
DIG19
irS[0]
###
###
irS[1]
###
###
irS[2]
###
###
irS[3]
###
###
irS[4]
###
###
irS[5]
###
###
*/
#define NUM_SENSORS
#define TIMEOUT
#define LEDON
6
2500
9
//Configuracin de pines
QTRSensorsRC qtrrc((unsigned char[]) {14, 15, 16, 17, 18, 19},
NUM_SENSORS, TIMEOUT, LEDON);
//configuracin de pines y de tiempo para la
J. L. Prez Motos
int i;
/*
===============
=
SETUP
=
===============
*/
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
//se espera de un segundo para comenzar la calibracin
delay(1000);
//se enciende el LED 13 para indicar que se estn calibrando los sensores
digitalWrite(13, HIGH);
//obtencin de los valores mnimos y mximos de cada sensor
tiempo = millis();
while (millis() - tiempo < 4000)
{
qtrrc.read(irS);
minmax(irS);
}
//se apaga el LED 13 para indicar que se ha terminado la calibracin de los sensores
digitalWrite(13, LOW);
//se obtienen por pantalla los valores mximos y mnimos para cada sensor
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(irMax[i]);
Serial.print(' ');
}
Serial.println(' ');
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(irMin[i]);
Serial.print(' ');
}
Serial.println(' ');
}
/*
===============
=
LOOP
=
===============
*/
void loop()
{
//lectura de los sensores y almacenamiento de sus valores
qtrrc.read(irS);
//se mapea cada valor segn su mximo y su mnimo entre 0 y 9 para ver si sigue la
lnea
for (i = 0; i < NUM_SENSORS; i++)
{
irM[i] = (map(irS[i], irMin[i], irMax[i], 0, 9));
}
//filtro por si hay valores menores o mayores que los medidos durante la calibracin
for (i = 0; i < NUM_SENSORS; i++)
J. L. Prez Motos
{
if (irM[i]
{
irM[i] =
}
if (irM[i]
{
irM[i] =
}
< 0)
0;
> 9)
9;
}
/*se obtiene por pantalla el valor mapeado de cada sensor, para sabes si se detecta
bien o no la lnea.
*/
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(irM[i]);
Serial.print(' ');
}
Serial.println(' ');
delay(100);
}
/*
===============
= FUNCIONES =
===============
*/
void minmax(unsigned int val[NUM_SENSORS])
mnimo de los sensores
{
for (i = 0; i < NUM_SENSORS; i++)
{
if (val[i] > irMax[i])
{
irMax[i] = val[i];
}
if (val[i] < irMin[i])
{
irMin[i] = val[i];
}
}
}
void loop(){
if (conf){
// Parpadeo para verificar su funcionamiento
digitalWrite(13, HIGH);
// Enciende el LED
delay(espera);
// Espera
digitalWrite(13, LOW);
// Apaga el LED
delay(espera);
// Espera
}
J. L. Prez Motos
else{
digitalWrite(13, HIGH); // Empiezael tiempo de espera para reconectar
Serial.println("Configuracion del modulo bluetooth");
Serial.println("Conecte el TX del modulo BT al RX del arduino y el RX del modulo BT
al TX del arduino");
delay(15000);
// Espera de 15 segundos (se puede cambiar)
digitalWrite(13, LOW); // Tiempo de espera agotado para reconectar
Serial.print("AT");
delay(espera);
J. L. Prez Motos
{
digitalWrite(13,HIGH);
delay(200);
digitalWrite(13,LOW);
delay(200);
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,LOW);
delay(100);
Serial.println("LED intermitente");
break;
}
}
}
}
DIG17
DIG18
DIG16
DIG15
DIG14
DIG9
DIG19
irS[0]
###
###
irS[1]
###
###
irS[2]
###
###
irS[3]
###
###
irS[4]
###
###
irS[5]
###
###
*/
#define NUM_SENSORS
#define TIMEOUT
#define LEDON
6
2500
19
//Configuracin de pines
QTRSensorsRC qtrrc((unsigned char[]) {12, 14, 11, 15, 18, 17},
NUM_SENSORS, TIMEOUT, LEDON);
//configuracin de pines y de tiempo para la
//lectura de los sensores
//Configuracin de los sensores IR
unsigned int irS[NUM_SENSORS];
sensores
long irMax[] = {1, 1, 1, 1, 1, 1};
long irMin[] =
{5000, 5000, 5000, 5000, 5000, 5000};
long irM[] = {0, 0, 0, 0, 0, 0};
long tiempo;
int i;
/*
===============
=
SETUP
=
===============
*/
void setup()
{
Serial.begin(9600);
J. L. Prez Motos
pinMode(13, OUTPUT);
//se espera de un segundo para comenzar la calibracin
delay(1000);
//se enciende el LED 13 para indicar que se estn calibrando los sensores
digitalWrite(13, HIGH);
//obtencin de los valores mnimos y mximos de cada sensor
tiempo = millis();
while (millis() - tiempo < 4000)
{
qtrrc.read(irS);
minmax(irS);
}
//se apaga el LED 13 para indicar que se ha terminado la calibracin de los sensores
digitalWrite(13, LOW);
//se obtienen por pantalla los valores mximos y mnimos para cada sensor
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(irMax[i]);
Serial.print(' ');
}
Serial.println(' ');
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(irMin[i]);
Serial.print(' ');
}
Serial.println(' ');
}
/*
===============
=
LOOP
=
===============
*/
void loop()
{
//lectura de los sensores y almacenamiento de sus valores
qtrrc.read(irS);
//se mapea cada valor segn su mximo y su mnimo entre 0 y 9 para ver si sigue la
lnea
for (i = 0; i < NUM_SENSORS; i++)
{
irM[i] = (map(irS[i], irMin[i], irMax[i], 0, 9));
}
//filtro por si hay valores menores o mayores que los medidos durante la calibracin
for (i = 0; i < NUM_SENSORS; i++)
{
if (irM[i] < 0)
{
irM[i] = 0;
}
if (irM[i] > 9)
{
irM[i] = 9;
}
}
/*se obtiene por pantalla el valor mapeado de cada sensor, para sabes si se detecta
bien o no la lnea.
*/
for (i = 0; i < NUM_SENSORS; i++)
{
Serial.print(irM[i]);
Serial.print(' ');
}
Serial.println(' ');
delay(100);
J. L. Prez Motos
}
/*
===============
= FUNCIONES =
===============
*/
void minmax(unsigned int val[NUM_SENSORS])
mnimo de los sensores
{
for (i = 0; i < NUM_SENSORS; i++)
{
if (val[i] > irMax[i])
{
irMax[i] = val[i];
}
if (val[i] < irMin[i])
{
irMin[i] = val[i];
}
}
}
DIG08
DIG07
DIG05
DIG03
DIG06
DIG09
**
**
LEDi
==== OUTB1
|
MB ===|
|
==== OUTB2
LEDi
LEDd
DIG10
DIG16
**
**
LEDd
OUTA1 ====
|
|=== MA
|
OUTA2 ====
*/
int
int
int
int
int
int
int
int
enableA = 8;
enableB = 7;
in1A = 5;
in2A = 3;
in1B = 6;
in2B = 9;
LEDi = 10;
LEDd = 16;
//pin
//pin
//pin
//pin
//pin
//pin
//pin
//pin
A
A
B
B
int i;
/*
===============
J. L. Prez Motos
=
SETUP
=
===============
*/
void setup(){
Serial.begin(57600);
//pinMode
pinMode(in1A, OUTPUT);
pinMode(in2A, OUTPUT);
pinMode(in1B, OUTPUT);
pinMode(in2B, OUTPUT);
pinMode(enableA, OUTPUT);
pinMode(enableB, OUTPUT);
pinMode(LEDi, OUTPUT);
pinMode(LEDd, OUTPUT);
//se detienen ambos motores
motor(0,0);
//se ponen a cero todas las salidas
digitalWrite(in1A, LOW);
digitalWrite(in1B, LOW);
digitalWrite(in2A, LOW);
digitalWrite(in2B, LOW);
//se activan ambos puentes
digitalWrite(enableA, HIGH);
digitalWrite(enableB, HIGH);
//se apagan los dos LEDs
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
//espera de un segundo para poder posicionar el robot en el suelo
delay(1000);
//se hace una pequea secuencia con los LEDs para indicar que ha iniciado el programa
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
delay(500);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
delay(500);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
delay(500);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
delay(500);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
delay(500);
}
void loop(){
//se lleva la velocidad a los motores
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, HIGH);
motor(200,200);
delay(2000);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, HIGH);
motor(-200,-200);
delay(2000);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
motor(100,200);
delay(1000);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
motor(200,100);
delay(1000);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
motor(-100,100);
delay(1000);
digitalWrite(LEDi, LOW);
J. L. Prez Motos
digitalWrite(LEDd, HIGH);
motor(100,-100);
delay(1000);
}
/*
********************************************************
*
Funcin para mover los motores segn el PWM
*
********************************************************
*/
void motor(int out1, int out2){
if (out1 >= 0){
analogWrite(in1A, constrain(abs(out1), 0, vMax));
analogWrite(in2A, 0);
}
else{
analogWrite(in1A, 0);
analogWrite(in2A, constrain(abs(out1), 0, vMax));
}
if (out2 >= 0){
analogWrite(in1B, constrain(abs(out2), 0, vMax));
analogWrite(in2B, 0);
}
else{
analogWrite(in1B, 0);
analogWrite(in2B, constrain(abs(out2), 0, vMax));
}
}
DIG17
DIG18
DIG15
DIG11
DIG14
DIG12
DIG19
irS[0]
###
###
irS[1]
###
###
irS[2]
###
###
irS[3]
###
###
irS[4]
###
###
irS[5]
###
###
*/
#define NUM_SENSORS
#define TIMEOUT
sensor
#define LEDON
6
2500
19
//Configuracin de pines
QTRSensorsRC qtrrc((unsigned char[]) {12, 14, 11, 15, 18, 17},
NUM_SENSORS, TIMEOUT, LEDON);
//configuracin de pines y de tiempo
para la lectura de los sensores
//Configuracin de los sensores IR
unsigned int irS[NUM_SENSORS];
de los sensores
J. L. Prez Motos
int dt = 10;
long tiempo = 0;
int i;
/*
===============
=
SETUP
=
===============
*/
void setup(){
Serial.begin(57600);
//obligado por el BT
delay(1000);
}
/*
===============
=
LOOP
=
===============
*/
void loop(){
//lectura de los sensores y almacenamiento de sus valores
qtrrc.read(irS);
//mapeamos cada valor segn su mximo y su mnimo entre 0 y 9 para ver si sigue la
lnea
for (i = 0; i < NUM_SENSORS; i++){
irM[i] = (map(irS[i], irMin[i], irMax[i], 0, 9));
}
//filtro por si hay valores menores o mayores que los medidos durante la calibracin
for (i = 0; i < NUM_SENSORS; i++){
if (irM[i] < 0){
irM[i] = 0;
}
if (irM[i] > 9){
irM[i] = 9;
}
}
//para obtener resultados
for (i = 0; i < NUM_SENSORS; i++){
Serial.print(irM[i]);
Serial.print(' ');
}
Serial.println(' ');
//se incluye un retraso para que matlab pueda procesar los datos
delay(dt);
}
J. L. Prez Motos
J. L. Prez Motos
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
Serial.println("LED izquierdo");
break;
}
//Si se recibe una 'v' se enciende el LED derecho y se muestrar en Blueterm LED
derecho
case 'v':{
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
Serial.println("LED derecho");
break;
}
//Si se recibe una 'd' se encienden los dos LEDs y se muestrar en Blueterm LEDs
encendidos
case 'd':{
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, HIGH);
Serial.println("LEDs encendidos");
break;
}
//Si se recibe una 'v' se enciende el LED derecho y se muestrar en Blueterm LED
derecho
case 'i':{
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
delay(100);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
delay(100);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
delay(100);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
delay(100);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
delay(100);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
delay(100);
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, LOW);
delay(100);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, HIGH);
delay(100);
Serial.println("LEDs intermitentes");
}
}
}
}
DIG17
DIG18
DIG15
DIG11
DIG14
DIG12
DIG19
enableA
enableB
in1A
in2A
in1B
in2B
DIG08
DIG07
DIG05
DIG03
DIG06
DIG09
LEDi
LEDd
DIG10
DIG16
**
J. L. Prez Motos
**
LEDi
irS[0]
###
###
**
LEDd
irS[1]
###
###
irS[2]
###
###
irS[3]
###
###
==== OUTB1
|
MB ===|
|
==== OUTB2
irS[4]
###
###
irS[5]
###
###
OUTA1 ====
|
|=== MA
|
OUTA2 ====
6
2500
19
//Asignacin de pines
QTRSensorsRC qtrrc((unsigned char[]) {12, 14, 11, 15, 18, 17},
NUM_SENSORS, TIMEOUT, LEDON);
//configuracin de pines y de tiempo para la
lectura de los sensores
int enableA = 8;
//pin del enable del puente A
int enableB = 7;
//pin del enable del puente B
int in1A = 5;
//pin de la entrada 1 del puente A
int in2A = 3;
//pin de la entrada 2 del puente A
int in1B = 6;
//pin de la entrada 1 del puente B
int in2B = 9;
//pin de la entrada 2 del puente B
int LEDi = 10;
//pin del LED izquierdo
int LEDd = 16;
//pin del LED derecho
//Variables de los sensores IR
unsigned int
sensores
long irP[] =
long irMax[]
{1, 1, 1, 1,
long irMin[]
{5000, 5000,
long irM[] =
irS[NUM_SENSORS];
//vector de pesos
//vector para almacenar valores mximos
//vector para almacenar valores mnimos
//vector donde se guardan los valores mapeados
//constante de proporcionalidad
//constante de derivacin
//constante de integracin
float integ = 0;
//parte integral
float deriv = 0;
//parte derivada
long errora = 0;
//variable donde
float toterror = 0;
//variable donde
error
/*
float kp = 7;
float kd = 0;
float ki = 15;
*/
//Variables para el clculo de la posicin
int seg = 25;
del PID
del PID
se guarda el error anterior
se guarda la suma total del
J. L. Prez Motos
//variable
//variable
//variable
//variable
//velocidad
//velocidad
//velocidad
//velocidad
//velocidad
//constante
//Variables de tiempo
int dt = 20;
que pasarlo a segundos
unsigned long tiempo;
//LEDs
int brillo = 0;
int i;
/*
===============
=
SETUP
=
===============
*/
void setup(){
Serial.begin(57600);
//obligado por el BT
//pinMode
pinMode(in1A, OUTPUT);
pinMode(in2A, OUTPUT);
pinMode(in1B, OUTPUT);
pinMode(in2B, OUTPUT);
pinMode(enableA, OUTPUT);
pinMode(enableB, OUTPUT);
pinMode(LEDi, OUTPUT);
pinMode(LEDd, OUTPUT);
//se detienen ambos motores
motor(0,0);
//se ponen a cero todas las salidas
digitalWrite(in1A, LOW);
digitalWrite(in1B, LOW);
digitalWrite(in2A, LOW);
digitalWrite(in2B, LOW);
//se activan ambos puentes
digitalWrite(enableA, HIGH);
digitalWrite(enableB, HIGH);
//se apagan los dos LEDs
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
//espera de un segundo para poder posicionar el siguelineas en el suelo
delay(1000);
calibracion();
delay(1000);
}
/*
===============
=
LOOP
=
===============
*/
void loop(){
J. L. Prez Motos
J. L. Prez Motos
*/
void calculo_posicion(){
posicion = 0;
cont = 0;
for (i = 0; i < NUM_SENSORS; i++)
{
posicion = posicion + irM[i] * irP[i];
cont = cont + irM[i];
}
posicion = posicion / cont;
}
/*
********************************************************
*
*
Funcin para calibrar los sensores
********************************************************
*/
void calibracion(){
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, HIGH);
//obtencin de los valores mnimos y mximos de cada sensor
motor(50, -50);
tiempo = millis();
while (millis() - tiempo < 2000){
qtrrc.read(irS);
minmax(irS);
}
motor(0, 0);
//terminada la calibracin se coloca el siguelneas sobre la lnea
motor(-25, 25);
while (posicion > seg || posicion < seg)
{
qtrrc.read(irS);
for (i = 0; i < NUM_SENSORS; i++)
{
irM[i] = map(irS[i], irMin[i], irMax[i], 0, 9);
}
for (i = 0; i < NUM_SENSORS; i++)
{
filtro(irM[i], 0, 9);
}
calculo_posicion();
//LEDs
if (brillo == 1){
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, HIGH);
brillo = 0;
}
else{
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
brillo = 1;
}
}
motor(0, 0);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
}
/*
********************************************************
* Funcin para asegurarnos que no se pasan los valores *
********************************************************
*/
void filtro (int input, int inputmin, int inputmax){
if (input < inputmin){
input = inputmin;
}
if (input > inputmax){
input = inputmax;
}
}
/*
********************************************************
J. L. Prez Motos
*
Funcin para calcular los mximos y
*
*
mnimos de cada sensor
*
********************************************************
*/
void minmax(unsigned int val[NUM_SENSORS]){
for (i = 0; i < NUM_SENSORS; i++){
if (val[i] > irMax[i]){
irMax[i] = val[i];
}
if (val[i] < irMin[i]){
irMin[i] = val[i];
}
}
}
/*
********************************************************
*
Funcin para mover los motores segn el PWM
*
********************************************************
*/
void motor(int out1, int out2){
if (out1 >= 0){
analogWrite(in1A, constrain(abs(out1), 0, vMax));
analogWrite(in2A, 0);
}
else{
analogWrite(in1A, 0);
analogWrite(in2A, constrain(abs(out1), 0, vMax));
}
if (out2 >= 0){
analogWrite(in1B, constrain(abs(out2), 0, vMax));
analogWrite(in2B, 0);
}
else{
analogWrite(in1B, 0);
analogWrite(in2B, constrain(abs(out2), 0, vMax));
}
}
/*
********************************************************
*
Funcin por si el robot se ha salido del trazado
*
********************************************************
*/
void no_linea(){
switch(out){
case 'I':
//caso en el que la ltima vez que se vi lnea
esta estaba a la izquierda
error = -seg;
//se fuerza a girar a la izquierda
motorA = vMax;
motorB = -vMax;
break;
case 'D':
//caso en el que la ltima vez que se vi lnea
esta estaba a la derecha
error = seg;
//se fuerza a girar a la derecha
motorA = -vMax;
motorB = vMax;
break;
case 'C':
//caso en el que la ltima vez que se vi lnea
esta estaba en el centro
error = 0;
//se fuerza a ir marcha atrs
motorA = -vMax;
motorB = -vMax;
break;
default:
error = 0;
break;
}
}
/*
********************************************************
*
PID
*
********************************************************
----------------------
J. L. Prez Motos
Control PID
---------------------Los signos con los que afectan el control PD a cada motor son distintos ya que para vari
ar la posicin del siguelineas
lo que se pretende es qe este gire
*/
void pid(){
integ = integ + error * dt / 1000;
deriv = (error - errora) * 1000 / dt;
//el 1000 es el factor para pasar de ms a
segundos
motorA = vel + error * kp + integ * ki + deriv * kd;
motorB = vel - error * kp - integ * ki - deriv * kd;
errora = error;
la parte derivativativa
}
/*
********************************************************
*
Funcin para mostrar los resultados por pantalla
*
********************************************************
*/
void resultados(){
/*for (i = 0; i < NUM_SENSORS; i++){
Serial.print(irM[i]);
Serial.print(' ');
}*/
//Serial.print(posicion);
//Serial.print(' ');
//Serial.println(seg);
Serial.print(error);
Serial.print(' ');
Serial.print(0);
Serial.print(' ');
Serial.print(constrain(motorA,-vMax,vMax));
Serial.print(' ');
Serial.println(constrain(motorB,-vMax,vMax));
//Serial.println(bif);
/*Serial.write(byte(constrain(abs(motorA),0,vMax)-128));
if (motorA >= 0){
Serial.write(byte(1));
}
else{
Serial.write(byte(2));
}
Serial.write(byte(constrain(abs(motorB),0,vMax)-128));
if (motorB >= 0){
Serial.write(byte(1));
}
else{
Serial.write(byte(2));
}
Serial.write(byte(posicion));
switch (bif){
case 'I':
Serial.write(byte(1));
break;
case 'C':
Serial.write(byte(2));
break;
case 'D':
Serial.write(byte(3));
break;
}*/
/*Serial.write(byte(seg));
for (i = 1; i < NUM_SENSORS; i++){
Serial.write(byte(irM[i]));
}*/
}
/*
********************************************************
*
Funcin para cuando el robot siga el trazado
*
********************************************************
J. L. Prez Motos
*/
void si_linea(){
//Marca de bifurcaciones
//if ((((irM[0] && irM[2]) > 0) && (irM[1] == 0)) || (((irM[5] && irM[3]) > 0) &&
(irM[4] == 0)) || ((irM[0] && irM[2] && irM[3] && irM[5] > 0) && ((irM[1] == 0) &&
(irM[4] == 0))))
if ((((irM[0] > irM[1]) && (irM[2] > irM[1])) || ((irM[5] > irM[4]) && (irM[3] >
irM[4]))) && (vena < 3))
//if ((((irM[0] && irM[2]) > 0) && (irM[1] == 0)) || (((irM[5] && irM[3]) > 0) &&
(irM[4] == 0)))
{
si_marca();
}
else if ((((irM[0] > irM[1]) && (irM[2] > irM[1])) || ((irM[5] > irM[4]) && (irM[3] >
irM[4])))){ //evitar que lade cuando ve una marca de bifurcacin
irM[0] = 0;
irM[1] = 0;
irM[4] = 0;
irM[5] = 0;
calculo_posicion();
}
else{
calculo_posicion();
}
//Actualizar las marcas de bifurcacin
if ((vena < 4) && (ven < 3)){
bif = bifa;
}
//Bifurcaciones
if ((ven > 3) && (bif == 'I') && (vena > 3)){
seg = 0;
//obligamos a que gire a la izquierda
vel = vell;
//se frena el coche
}
else if ((ven > 3) && (bif == 'D') && (vena > 3)){
seg = 50;
//obligamos a que gire a la derecha
vel = vell;
//se frena el coches
}
//seguir recto
else{
seg = 25;
//valor por defecto
vel = velr;
//velocidad normal
}
//Clculo del error
error = seg - posicion;
//PID
pid();
/*
Se va guardando la ltima posicin en la que se vio lnea. Si se vio a la izquierda de
la parte central querr decir que el
error es negativo y si por el contrario se vio a la derecha querr decir que el error
es positivo.
*/
if (error < 0){
out = 'I';
}
else if (error > 0){
out = 'D';
}
else{
out = 'C';
}
vena = ven;
}
/*
********************************************************
*
*
Funcin para detectar marcas de bifurcacin
********************************************************
irS[0]
###
###
|||||
|||||
irS[1]
###
###
irS[2]
###
###
irS[3]
###
###
|||||||||||||
|||||||||||||
irS[4]
###
###
irS[5]
###
###
//Marca a la izquierda
|||||||||||||
|||||||||||||
J. L. Prez Motos
|||||
|||||
//Marca a la derecha
*/
void si_marca(){
if ((irM[0] > irM[1]) && (irM[2] > irM[1])){
bifa = 'I';
posicion = seg;
}
else if ((irM[5] > irM[4]) && (irM[3] > irM[4])){
bifa = 'D';
posicion = seg;
}
else{
bifa = 'C';
posicion = seg;
}
}
ANEXO
A.11:
OBTENCIN
DE
LOS
PARMETROS
DEL
CONTROLADOR PID
clear;
clc;
%borrar previos
delete(instrfind({'Port'},{'COM6'}));
%crear objeto serie
s = serial('COM6','BaudRate',57600,'Terminator','CR/LF');
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');
%abrir puerto
fopen(s);
% parmetros de medidas
tmax = 15; % tiempo de captura en s
rate = 50; % resultado experimental
% preparar la figura
f = figure('Name','Captura');
a = axes('XLim',[0 tmax],'YLim',[-1.2 1.2]);
l1 = line(nan,nan,'Color','r','LineWidth',2);
l2 = line(nan,nan,'Color','b','LineWidth',1);
l3 = line(nan,nan,'Color','y','LineWidth',2);
l4 = line(nan,nan,'Color','g','LineWidth',2);
xlabel('Tiempo (s)')
ylabel('Error')
title('Captura del error en tiempo real con Arduino')
grid on
hold on
% inicializar
v1 = zeros(1,tmax*rate);
v2 = zeros(1,tmax*rate);
v3 = zeros(1,tmax*rate);
v4 = zeros(1,tmax*rate);
i = 1;
t = 0;
% ejecutar bucle cronometrado
tic
while t<tmax
t = toc;
% leer del puerto serie
puerto = fscanf(s,'%f %f %f %f')';
v1(i)=puerto(1)/25;
J. L. Prez Motos
v2(i)=puerto(2)/25;
v3(i)=puerto(3);
v4(i)=puerto(4);
% dibujar en la figura
x = linspace(0,i/rate,i);
set(l1,'YData',v1(1:i),'XData',x);
set(l2,'YData',v2(1:i),'XData',x);
set(l3,'YData',v3(1:i),'XData',x);
set(l4,'YData',v4(1:i),'XData',x);
drawnow
% seguir
i = i+1;
end
%% Cerrar el puerto
fclose(s);
delete(s);
clear s;
DIG08
DIG07
DIG05
DIG03
DIG06
DIG09
LEDi
LEDd
DIG10
DIG16
**
**
LEDi
irS[0]
###
###
**
**
LEDd
irS[1]
###
###
irS[2]
###
###
irS[3]
###
###
____ OUTB1
|
MB ===|
|
____ OUTB2
irS[4]
###
###
irS[5]
###
###
OUTA1 ___
|
|=== MA
|
OUTA2 ___
*/
//Configuracin de pines
int
int
int
int
int
int
int
int
enableA = 8;
enableB = 7;
in1A = 5;
in2A = 3;
in1B = 6;
in2B = 9;
LEDi = 10;
LEDd = 16;
//pin
//pin
//pin
//pin
//pin
//pin
//pin
//pin
A
A
B
B
int i;
giro = 0;
vel = 0;
girom = 0;
velm = 0;
J. L. Prez Motos
/*
===============
=
SETUP
=
===============
*/
void setup(){
Serial.begin(57600);
//obligado por el BT
//pinMode
pinMode(in1A, OUTPUT);
pinMode(in2A, OUTPUT);
pinMode(in1B, OUTPUT);
pinMode(in2B, OUTPUT);
pinMode(enableA, OUTPUT);
pinMode(enableB, OUTPUT);
pinMode(LEDi, OUTPUT);
pinMode(LEDd, OUTPUT);
//se detienen ambos motores
motor(0,0);
//se ponen a cero todas las salidas
digitalWrite(in1A, LOW);
digitalWrite(in1B, LOW);
digitalWrite(in2A, LOW);
digitalWrite(in2B, LOW);
//se activan ambos puentes
digitalWrite(enableA, HIGH);
digitalWrite(enableB, HIGH);
//se apagan los dos LEDs
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
//espera de un segundo para poder posicionar el siguelineas en el suelo
delay(1000);
}
/*
===============
=
LOOP
=
===============
*/
void loop(){
delay(20);
digitalWrite(LEDi, LOW);
digitalWrite(LEDd, LOW);
//motor(0,0);
//Mientras el puerto serie del modulo bluetooth esta disponible
while (Serial.available()>0){
//Guardamos en la variable dato el valor leido por el modulo bluetooth
digitalWrite(LEDi, HIGH);
digitalWrite(LEDd, HIGH);
giro = Serial.read() - 10; //el -10 es cosa de java. Fallaba el paso de numeros
negativos
vel = Serial.read() - 10;
//filtros
filtro(vel, -10, 10);
filtro(giro, -10, 10);
//mapeados
if (vel >= 0){ //hay que cambiar el sentido a vel
velm = map(vel, 0, 10, 0, -255);
}
else{
velm = map(vel, -10, 0, 255, 0);
}
if (giro >= 0){
girom = map(giro, 0, 10, 0, 50);
}
else{
girom = map(giro, -10, 0, -50, 0);
}
//motor
J. L. Prez Motos
processing.core.*;
android.bluetooth.BluetoothAdapter;
android.bluetooth.BluetoothDevice;
android.bluetooth.BluetoothSocket;
android.content.BroadcastReceiver;
android.content.Context;
android.content.Intent;
java.util.ArrayList;
java.util.UUID;
java.io.IOException;
java.io.InputStream;
java.io.OutputStream;
java.lang.reflect.Method;
import
import
import
import
import
import
android.hardware.Sensor;
android.hardware.SensorEvent;
android.hardware.SensorManager;
android.hardware.SensorEventListener;
android.os.Bundle;
android.view.WindowManager;
J. L. Prez Motos
J. L. Prez Motos
J. L. Prez Motos
pwmB.recorteY = width/60;
pwmB.digitos = 3;
pwmB.decimales = -1;
pwmB.etiqueta = "Motor izquierdo";
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void draw() {
//para
ir pasando de un estado a otro
switch(estado){
case 0:
listaDispositivos("BUSCANDO DISPOSITIVOS", color(255, 0, 0));
break;
case 1:
listaDispositivos("DISPOSITIVOS DISPONIBLES", color(51, 181, 229));
break;
case 2:
conectaDispositivo();
break;
case 3:
//dibujar el fondo
background(0);
strokeWeight(1);
fill(31,91,76);
stroke(92,214,166);
ellipse(width/2,height/2,(float)(0.98*height),(float) (0.98*height));
noFill();
for (i = 1; i*50 < l/2; i++){
ellipse(width/2,height/2,100*i,100*i);
}
muestraDatos();
//mostrar los resultados por pantalla
break;
case 4:
muestraError();
break;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void onCreate(Bundle bundle) {
//funcin para evitar
que se apague la pantalla
super.onCreate(bundle);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void onStart(){
//funcin que se ejecuta al iniciarse la aplicacin
super.onStart();
//incluirlo siempre al princpio de onStart
bttelefono = BluetoothAdapter.getDefaultAdapter();
//detectar como est el bluetooth
if (bttelefono != null){
//si el
telfono no dispone de bluetooth devolver null
if (!bttelefono.isEnabLED()){
//si el
bluetooth no est activado, se activa. Permisos
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//de
bluetooth
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
else{
empieza();
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void onStop(){
//funcin para finalizar la aplicacin
if(socket != null){
//si
todava no se ha cortado la comunicacin se intenta
J. L. Prez Motos
try{
//cerrar el medio de comunicacin
socket.close();
}
catch(IOException ex){
println(ex);
}
}
super.onStop();
//incluirlo siempre al final del onStop
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void onActivityResult (int requestCode, int resultCode, Intent data){
//se obtiene el
resultado de una operacin
if(resultCode == RESULT_OK){
//con resultCode se obtiene si la operacin
empieza();
//ha sido exitosa o no
}
else{
estado = 4;
error = "No se ha activado el bluetooth";
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void mouseReleased(){
//funcin que se llama cada vez que se toca la
pantalla
switch(estado){
case 0:
break;
case 1:
compruebaEleccion();
break;
case 3:
onResume();
break;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void empieza(){
dispositivos = new ArrayList<BluetoothDevice>();
for (BluetoothDevice dispositivo : bttelefono.getBondedDevices()){
dispositivos.add(dispositivo);
//aade los diferentes dispositivos a la matriz
de dispositivos disponibles
}
estado = 1;
//pasar a la pantalla de
elegir dispositivos -> listaDispositivos
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void listaDispositivos(String texto, int c){
//funcin para mostrar en pantalla los
dispositivos
background(0);
textFont(androidFont);
fill(c);
textSize(height/15);
text(texto,width/2, 30);
if(dispositivos != null){
for(int indice = 0; indice < dispositivos.size(); indice++){
BluetoothDevice dispositivo = (BluetoothDevice) dispositivos.get(indice);
fill(0,255,255);
int posicion = height/6 * (1 + indice);
if(dispositivo.getName() != null){
textSize(height/18);
text(dispositivo.getName(),width/2, posicion); //nombre del dispositivo
}
fill(92, 214, 166);
textSize(height/20);
J. L. Prez Motos
valor[1]=vel;
valor[0]=giro;
//dibujar el circulo
strokeWeight(2);
stroke(2,52,77);
fill(0,255/* - 180 / 15 * sqrt(ax*ax+ay*ay)*/,255/* - 180 / 15 * sqrt(ax*ax+ay*ay)*/,10 +
sqrt(ax*ax+ay*ay)*245/15);
ellipse(constrain(map(ax, -10, 10, width/2-l/2+width/40, width/2+l/2-width/40), width/2l/2+width/20, width/2+l/2-width/20),
constrain(map(ay, -10, 10, height/2-l/2+width/40, height/2+l/2-width/40),
height/2-l/2+width/20, height/2+l/2-width/20),
width/20, width/20);
//enviar datos al robot desde el telfono*/
try{
ons.write(valor,0,valor.length); //(variable,bites vacos,longitud)
=
=
=
=
J. L. Prez Motos
//evitar que se enven datos que no se
//(variable,desde donde,longitud)
ardu[0] + 128;
ardu[1];
ardu[2] + 128;
ardu[3];
//pwmA.dibuja();
//pwmB.dibuja();
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void onResume() {
//funcin que sirve para volver a retomar una actividad,
en este caso el acelermetro
super.onResume();
//incluir siempre al principio del
onResume
//se define el SensorManager (te permite acceder al sensor)
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
//se define un SensorEventListener (recibe la informacin del sensor cuando este vara. Lega
desde el SensorManager)
accSensorEventListener = new MySensorEventListener();
//se coge el sensor tipo acelermetro
acc_sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//se guarda el SensorEventListener junto con su sensor y su Sensor Manager. Ajustar el delay
segn las necesidades
mSensorManager.registerListener(accSensorEventListener, acc_sensor,
SensorManager.SENSOR_DELAY_GAME);
} //tipos de delay en orden ascendente: SENSOR_DELAY_FASTEST; SENSOR_DELAY_GAME;
SENSOR_DELAY_NORMAL; SENSOR_DELAY_UI
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void onPause() {
//desvincular el SensorEventListener antes de salir
mSensorManager.unregisterListener(accSensorEventListener);
super.onPause();
//incluir siempre al final del onPause
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void muestraError() {
//funcin para mostrar errores. Se
mostrar el error en el centro de la pantalla
//con fondo rojo
background(255, 0, 0);
fill(255, 255, 0);
textFont(androidFont);
textAlign(CENTER);
translate(width / 2, height / 2);
textSize(16);
text(error, 0, 0);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
//class del sensor
class MySensorEventListener implements SensorEventListener {
public void onSensorChanged(SensorEvent event) {
J. L. Prez Motos
J. L. Prez Motos
processing.core.*;
android.bluetooth.BluetoothAdapter;
android.bluetooth.BluetoothDevice;
android.bluetooth.BluetoothSocket;
android.content.BroadcastReceiver;
android.content.Context;
android.content.Intent;
java.util.ArrayList;
java.util.UUID;
java.io.IOException;
java.io.InputStream;
java.io.OutputStream;
java.lang.reflect.Method;
android.os.Bundle;
android.view.WindowManager;
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
//un BroadcastReceiver sirve
BroadcastReceiver receptor = new BroadcastReceiver(){
para recibir eventos
public void onReceive(Context context, Intent intent){
String accion = intent.getAction();
//recibe el
evento que se enva a la aplicacin
if (BluetoothDevice.ACTION_FOUND.equals(accion)){
//la accin es que ha encontrado
un dispositivo bluetooth
BluetoothDevice dispositivo =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
println(dispositivo.getName() + " " + dispositivo.getAddress());
dispositivos.add(dispositivo);
}
J. L. Prez Motos
else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(accion)){
est buscando disopositivos
estado = 0;
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(accion)){
terminado de buscar
estado = 1;
}
//el telfono
//el telfono ha
}
};
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void setup() {
size(displayWidth, displayHeight, JAVA2D);
//se obtienen las medidas de la
pantalla y se define que solo habrn
//objetos en 2D
frameRate(25);
//refresco de pantalla
//para que la pantalla est girada
orientation(LANDSCAPE);
//si queremos que la posicin de la pantalla sea vertical:
//orientation(PORTRAIT);
//fuentes
fontList = PFont.list();
androidFont = createFont(fontList[0], 32, true);
textFont(androidFont);
stroke(255);
//definicin del tamao de la matriz a rellenar
pwmA = new int[width];
pwmB = new int[width];
posicion = new int[width];
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void draw() {
//para
ir pasando de un estado a otro
switch(estado){
case 0:
listaDispositivos("BUSCANDO DISPOSITIVOS", color(255, 0, 0));
break;
case 1:
listaDispositivos("DISPOSITIVOS DISPONIBLES", color(51, 181, 229));
break;
case 2:
conectaDispositivo();
break;
case 3:
//dibujar el fondo
background(0);
strokeWeight(1);
fill(31,91,76);
stroke(92,214,166);
rectMode(CORNERS);
rect(0,(float) (0.01*height),width,(float) (0.33*height));
rect(0,(float) (0.34*height),width,(float) (0.66*height));
rect(0,(float) (0.67*height),width,(float) (0.99*height));
textSize(height/33);
textAlign(CENTER, CENTER);
fill(253,254,31);
stroke(253,254,31);
text("Motor izquierdo",width/2,(float) (height*0.03));
text("Motor derecho",width/2,(float) (height*0.36));
text("Lnea",width/2,(float) (height*0.69));
textSize(height/44);
textAlign(LEFT, CENTER);
text("255",(float) (0.01*width),(float) (0.03*height));
text("0",(float) (0.01*width),(float) (0.15*height));
J. L. Prez Motos
J. L. Prez Motos
if(resultCode == RESULT_OK){
//con resultCode se obtiene si la operacin
empieza();
//ha sido exitosa o no
}
else{
estado = 4;
error = "No se ha activado el bluetooth";
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void mouseReleased(){
//funcin que se llama cada vez que se toca la
pantalla
switch(estado){
case 0:
break;
case 1:
compruebaEleccion();
break;
case 3:
onResume();
break;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void empieza(){
dispositivos = new ArrayList<BluetoothDevice>();
for (BluetoothDevice dispositivo : bttelefono.getBondedDevices()){
dispositivos.add(dispositivo);
//aade los diferentes dispositivos a la matriz
de dispositivos disponibles
}
estado = 1;
//pasar a la pantalla de
elegir dispositivos -> listaDispositivos
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void listaDispositivos(String texto, int c){
//funcin para mostrar en pantalla los
dispositivos
background(0);
textFont(androidFont);
textAlign(CENTER,CENTER);
fill(c);
textSize(height/15);
text(texto,width/2, 30);
if(dispositivos != null){
for(int indice = 0; indice < dispositivos.size(); indice++){
BluetoothDevice dispositivo = (BluetoothDevice) dispositivos.get(indice);
fill(0,255,255);
int posicion = height/6 * (1 + indice);
if(dispositivo.getName() != null){
textSize(height/18);
text(dispositivo.getName(),width/2, posicion); //nombre del dispositivo
}
fill(92, 214, 166);
textSize(height/20);
text(dispositivo.getAddress(),width/2, posicion + height/16);
//direccin mac
del dispositivo
fill(255);
line(width/4, posicion + height/12, width*3/4, posicion + height/12);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void compruebaEleccion(){
int elegido = (mouseY - 50) / 55;
if(elegido < dispositivos.size()){
dispositivo = (BluetoothDevice) dispositivos.get(elegido);
println(dispositivo.getName());
estado = 2;
//ir a conectaDispositivo
J. L. Prez Motos
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void conectaDispositivo(){
//sirve para conectar el telfono con el dipositivo.
Cuidado con el UUID. Los nmeros
try{
//ah puestos son para el
bluetooth, pero se han tenido que cambiar los primeros (puerto serie)
socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString("00001101-00001000-8000-00805F9B34FB"));
Method m = dispositivo.getClass().getMethod("createRfcommSocket", new Class[] {
int.class });
socket = (BluetoothSocket) m.invoke(dispositivo, 1);
socket.connect();
ins = socket.getInputStream(); //por aqu se recibirn datos del robot en el mvil
ons = socket.getOutputStream(); //por aqu se enviarn datos del mvil al robot
estado = 3;
//ir a muestraDatos
}
catch(Exception ex){
estado = 4;
error = ex.toString();
println(error);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void muestraDatos(){
//funcin donde se realizarn las principales
operaciones y se mostrarn por
//pantalla los resultados
try{
telfono
while(ins.available() > 0){
ins.read(ardu,0,ardu.length);
}
}
catch(Exception ex){
estado = 4;
error = ex.toString();
println(error);
}
for (i=1;i<width;i++){
pwmA[i-1]=pwmA[i];
pwmB[i-1]=pwmB[i];
posicion[i-1]=posicion[i];
}
//Aadir valores
if (ardu[1]==1){
pwmA[i-1]=ardu[0]+128;
}
else if (ardu[1]==2){
pwmA[i-1]=-1*(ardu[0]+128);
}
if (ardu[3]==1){
pwmB[i-1]=ardu[2]+128;
}
else if (ardu[3]==2){
pwmB[i-1]=-1*(ardu[2]+128);
}
posicion[i-1]=ardu[4];
for (i=1;i<width;i++){
point(i,map(pwmA[i],-255,255,(float)(0.33*height),(float)(0.01*height)));
line(i,map(pwmA[i],-255,255,(float)(0.33*height),(float)(0.01*height)),i,map(pwmA[i1],-255,255,(float)(0.33*height),(float)(0.01*height)));
point(i,map(pwmB[i],-255,255,(float)(0.66*height),(float)(0.34*height)));
line(i,map(pwmB[i],-255,255,(float)(0.66*height),(float)(0.34*height)),i,map(pwmB[i1],-255,255,(float)(0.66*height),(float)(0.34*height)));
point(i,map(posicion[i],0,50,(float)(0.99*height),(float)(0.67*height)));
J. L. Prez Motos
line(i,map(posicion[i],0,50,(float)(0.99*height),(float)(0.67*height)),i,map(posicion[i1],0,50,(float)(0.99*height),(float)(0.67*height)));
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public void muestraError()
//funcin para mostrar errores. Se
mostrar el error en el centro de la pantalla
{
//con fondo rojo
background(255, 0, 0);
fill(255, 255, 0);
textFont(androidFont);
textAlign(CENTER);
translate(width / 2, height / 2);
textSize(16);
text(error, 0, 0);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
public int sketchWidth() { return displayWidth; }
public int sketchHeight() { return displayHeight; }
public String sketchRenderer() { return JAVA2D; }
}
J. L. Prez Motos
ANEXO B: PLANOS
76
58
de Navarra
Nafarroako
Unibertsitate Publikoa
E.T.S.I.I.T.
INGENIERO
INDUSTRIAL
PROYECTO:
DEPARTAMENTO:
DEPARTAMENTO DE
INGENIERIA ELECTRICA
Y ELECTRONICA
REALIZADO:
18/2/2013
ESCALA:
2:1
de Navarra
Nafarroako
Unibertsitate Publikoa
E.T.S.I.I.T.
INGENIERO
INDUSTRIAL
PROYECTO:
DEPARTAMENTO:
DEPARTAMENTO DE
INGENIERIA ELECTRICA
Y ELECTRONICA
REALIZADO:
18/2/2013
ESCALA: