Conexión RobotStudio y Arduino TCP/IP
Conexión RobotStudio y Arduino TCP/IP
i
Trabajo Fin de Máster
Máster Universitario en Ingeniería Electrónica, Robótica y Automática
Autor:
Mauricio Hinojosa Rea
Tutores:
Dr. Luis Fernando Castaño Castaño
Dr. David Muñoz de la Peña Sequedo
iii
Trabajo Fin de Máster: Conexión de RobotStudio y Arduino mediante TCP/IP para la recolección y envío de
datos de posicionamiento de cinta transportadora.
El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros:
Presidente:
Vocales:
Secretario:
Sevilla, 2019
v
A Flor Alba y Jazmín.
vii
Agradecimientos
Quiero agradecer a mis padres, mis hermanas y a la vida misma por permitirme pasar un año lleno de aprendizaje
y enseñanzas, tanto en la escuela de la vida como en la Escuela de Ingenieros de Sevilla. Estar aquí, me ha
permitido abrir la mente y los ojos de manera infinita, inconmesurable y real. Gracias a mis padres, Lijia y
Freddy, por mantener su fe en mí, darme la vida y guiarme por el camino que me llevó hasta aquí y que de
seguro me llevará a las estrellas. Michelle y Micaela, por vosotras daría mi existencia.
Doy gracias a David Muñoz y Fernando Castaño, mis tutores; ya que con su propuesta de TFM me mostré a mi
mismo hasta donde puedo llegar de forma intelectual. Gracias por sus enseñanzas y tiempo invertido en este
trabajo. Por ayudarme y por su gran trabajo en lo cotidiano.
ix
Resumen
Este proyecto, nace de la necesidad de comunicar dos equipos utililizados en el laboratorio del departamento de
Ingeniería de Sistemas y Automática de la Escula Técnica Superior de Ingeniería de Sevilla.
Uno de los equipos es un brazo robótico del tipo IRB120 del fabricante ABB, y el otro equipo es una cinta
transportadora automatizada de fabricación propia en el departamento que ocupa parte de la zona de trabajo del
brazo robótico. La cinta transportadora está gobernada por un microcontrolador (Arduino) que permite
posicionar de forma precisa (en coordenadas X e Y) piezas que debe manipular el Robot.
El problema se presenta cuando, por medio de las entradas y salidas que posee la controladora real IRC5
(controladora asociada al robot IRB120) no permite la recogida de datos por medio de interrupciones, que es
justo lo que se requiere para procesar la información que gestiona el Arduino de la cinta (posición X e Y de la
pieza).
Este trabajo tiene la finalidad de inspeccionar, de forma remota, el acceso a datos y manipulación de funciones
de RobotStudio; así como el envío y recolección de datos desde la fuente remota; siendo en este caso Arduino.
Y con la visión, a posteriori, de servir como base de software para el montaje e inclusión del robot real con la
cinta tansportadora. Arduino es una tecnología probada y además; cuenta con un shield Etherner que permite la
manipulación y creación de servidores y clientes ethernet, por lo que es posible colgar un servidor en una red,
clave esencial para este trabajo. RobotStudio tiene la capacidad de emular códigos, tantas veces como se
requiera, para la manipulación y movimiento del robot emulado (segunda clave esencial para el desarrollo de
este trabajo).
El trabajo desarrollado en este documento muestra la creación de un servidor ethernet por medio de protocolos
TCP/IP con Arduino, que también sirve de gestor de sensores y datos de posicionamiento X e Y para, según
petición de RobotStudio, se proceda a realizar 3 funciones en la cinta asociada a Arduino: leer (permite a
RobotStudio conocer los datos de posición de la pieza), absoluto (permite a Arduino mover la cinta según se
disponga en RobotStudio) e incremental (las mismas funciones que para absoluto, en un ciclo de repetición
conocida y enviada desde RobotStudio).
1. Montaje de un servidor en Arduino que conecte el cliente de RobotStudio a esta red, mediante TCP/IP.
2. Desarrollo un protocolo de comunicaciones sencillo entre los equipos.
3. Obtención de los datos de las coordenadas X e Y de la pieza en la cinta y enviarla a RobotStudio desde
Arduino.
xi
Abstract
This project is born from the need to communicate two equipment used in the laboratory of the Department of
Systems Engineering and Automatic of the E.S.I in the Sevilla University.
One of the equipment is a robotic arm of the type IRB120 of the manufacturer ABB, and the other equipment is
an automated conveyor belt of own manufacture in the department that occupies part of the work area of the
robotic arm. The conveyor belt is governed by a microcontroller (Arduino) that allows precise positioning (in X
and Y coordinates) parts to be handled by the Robot.
The problem arises when, through the inputs and outputs of the actual CONTROLLER IRC5 (controller
associated with the robot IRB120) it does not allow the collection of data by means of interruptions, which is
just what is required to process the information that is manages the Arduino of the tape (X and Y position of the
part).
This work is intended to remotely inspect data access and manipulate RobotStudio functions; as well as sending
and collecting data from the remote source; being in this case Arduino. And with the vision is serve as a software
base for the assembly and inclusion of the real robot with the tancarrier tape. Arduino is a proven technology
and it has an Etherner shield that allows the manipulation and creation of ethernet servers and clients, so it is
possible to hang a server on a network, essential key to this work. RobotStudio can emulate codes, as many
times as required, for the manipulation and movement of the emulated robot (second essential key for the
development of this work).
The work developed in this document shows the creation of an ethernet server by means of TCP/IP protocols
with Arduino, which also serves as a sensor manager and X and Y positioning data to, at RobotStudio's request,
perform 3 functions on the Arduino-associated tape: read (allows RobotStudio to know the part's position data),
absolute (allows Arduino to move the tape as available in RobotStudio) and incremental (same functions that
for absolute, in a repetition cycle known and sent from RobotStudio).
1. Mounting a server in Arduino that connects the RobotStudio client to this network, using TCP/IP.
2. Develop a simple communication protocol between Arduino and RobotStudio.
3. Obtain the X and Y coordinate data of the piece on the belt and send it to RobotStudio from Arduino.
xiii
Índice
Agradecimientos ix
Resumen xi
Abstract xiii
Índice xv
Índice de Tablas xvii
Índice de Figuras xix
Notación xxiii
1 Introducción y Objetivos 1
1.1 Posicionado de piezas 1
1.2 Robot ARB120 1
1.3 Arduino TCP/IP 2
1.4 Aplicación 2
1.5 Definición de Funciones y Errores 3
2 Descripción del Hardware 5
2.1 Arduino Mega 2560 5
2.1.1 Alimentación 6
2.1.2 Memoria 6
2.1.3 Entradas y Salidas 6
2.1.4 Comunicación 7
2.2 Hardware Ethernet en Arduino 7
2.3 Motor de Corriente Continua y Driver L298N para motores DC 8
2.3.1 Conexionado para alimentación del módulo L298N 8
2.4 Encoder Rotativo Incremental 9
2.4.1 Especificaciones técnicas encoder incremental 9
2.4.2 Cables de Conexiones de encoder incremental 9
2.5 Calibrador Digital 9
2.6 Banda transportadora con elementos integrados 10
2.7 IRC5C Compact Controller 10
2.7.1 RemoteService 11
3 Estación de RobotStudio 13
3.1 Creación de la herramienta 13
3.1.1 Montaje de la herramienta en RobotStudio 13
3.1.2 Añadir la herramienta al robot 13
3.2 Crontrol en RAPID 14
3.2.1 Creación de variables 14
3.2.2 Funcion “Main” 14
3.2.3 “Abrir comunicación” 15
3.2.4 Función “Leer” 15
3.2.5 Funcion “Absoluto” 15
3.2.6 Funcion “Relativo” 16
xv
3.2.7 Función “Estado” 17
3.2.8 Función “Cerrar Comunicación” 17
3.2.9 Función “Movimiento Robot” 17
3.3 Flexpendant 18
3.3.1 Manejo básico 18
4 Desarrollo de la programación en Arduino 21
4.1 Matriz de pulsadores 21
4.2 Control con Puente L298D 23
4.3 Puente H, encoder incremental y matriz de pulsadores 24
4.4 Creación de un servidor IP con un puerto determinado. 26
4.5 Funciones dependientes de la información enviadas desde RobotStudio 28
4.6 Version final del programa desarrollado en Arduino 32
5 Desarrollo de la programación en RobotStudio 45
5.1 Conexión a un servidor IP Montado en arduino. 45
5.2 Funciones enviadas desde RobotStudio. 46
5.3 Version final del programa desarrollado en Arduino 49
5.4 Tramas de datos enviadas y recibidas desde y hacia RobotStudio 53
5.5 Tramas de errores enviadas y recibidas desde y hacia RobotStudio 54
6 Simulación 56
6.1 Muestra de datos e impresión por serial desde Arduino 57
7 Resultados 58
7.1 Función Local en Arduino 58
7.1.1 Motor Adelante (Cinta avanza) 58
7.1.2 Motor Atrás (Cinta retrocede) 59
7.1.3 Motor Paro (Cinta se detiene) 60
7.2 Función Remoto en Arduino desde RobotStudio 61
7.2.1 Función Leer 61
7.2.2 Función Absoluto 62
7.2.3 Función Relativo 65
7.3 Errores 67
7.3.1 Error 01 67
7.3.2 Error 02 68
7.3.3 Error 03 68
7.3.4 Error 04 69
7.4 Ejemplo de varias funciones y movimiento relativo del robot IRB120 69
8 Conclusiones 72
9 Bibliografía 73
10 Anexo 74
10.1 Anexo A: Arduino 74
10.2 Anexo B: RobotStudio 74
10.3 Anexo B: Esquematico 75
10.4 Anexo B: Esquematico 75
10.5 Anexo C: Especificaciones IRB120 76
10.6 Anexo D: Vínculos RobotStudio 77
ÍNDICE DE TABLAS
xvii
ÍNDICE DE FIGURAS
xix
Figura 36: Montaje Arduino-Ethernet 32
Figura 37: Conexión final, esquema cableado de Arduino y banda transportadora 33
Figura 38: Trama de datos envíada desde RobotStudio para la Función Leer 53
Figura 39: Trama de datos envíada desde RobotStudio para la Función Absoluto 53
Figura 40: Trama de datos envíada desde RobotStudio para la Función Relativo 54
Figura 41: Trama de datos envíada desde Arduino para la Función Leer 54
Figura 42: Trama de datos envíada desde Arduino para la Función Absoluto 54
Figura 43: Trama de datos envíada desde Arduino para la Función Relativo 54
Figura 44: Trama de errores envíada desde Arduino 54
Figura 45: Botonera simulaciones RobotStudio 56
Figura 46: Opciones reproducción RobotStudio 56
Figura 47: Opciones restablecer RobotStudio 56
Figura 48: Ventana guardar estado actual RobotStudio 57
Figura 49: Monitor Serie en Arduino 57
Figura 50: Esquema general de los componentes electrónicos 58
Figura 51: Salida serial para función: Motor Adelante 59
Figura 52: Salida en la cinta para función: Motor Adelante 59
Figura 53: Salida serial para función: Motor Atrás 60
Figura 54: Salida en la cinta para función: Motor Adelante 60
Figura 55: Salida serial para función: Motor Paro 60
Figura 56: Salida en la cinta para función: Motor Paro 61
Figura 57: Función Leer en RobotStudio 61
Figura 58: Función Leer en Arduino 62
Figura 59: Variables recibidas en RobotStudio 62
Figura 60: Función Absoluto en RobotStudio 63
Figura 61: Función Absoluto en Arduino 63
Figura 62: Función Absoluta ejecutándose. 64
Figura 63: Cinta detenida luego de ejecutarse el comando Absoluto. 64
Figura 64: Variables recibidas en RobotStudio 64
Figura 65: Función Absoluto en RobotStudio 65
Figura 66: Función Absoluto en Arduino 65
Figura 67: Función Relativa ejecutándose. 66
Figura 68: Cinta detenida luego de ejecutarse el comando Relativo. 66
Figura 69: Variables recibidas en RobotStudio 67
Figura 70: Salida del Serial de Arduino para Error 01 67
Figura 71: Origen del fallo desde RobotStudio para Error 01 67
Figura 72: Salida RobotStudio para Error 01 67
Figura 73: Salida del Serial de Arduino para Error 02 68
Figura 74: Salida RobotStudio para Error 02 68
Figura 75: Salida del Serial de Arduino para Error 03 68
Figura 76: Salida RobotStudio para Error 03 69
Figura 77: Salida del Serial de Arduino para Error 04 69
Figura 78: Salida RobotStudio para Error 04 69
Figura 79: Valor enviado desde RobotStudio para Error 04 69
Figura 80: Funciones enviadas para ejemplo ilustrativo 70
Figura 81: Seriel para ejemplo ilustrativo 70
Figura 82: Estado en reposo del robot 71
Figura 83: Robot después de recibir información de la función relativo 4, 3 71
Figura 84: Robot después de recibir información de la función absoluto 10 72
xxi
Notación
CA Corriente Alterna
CC Corriente Continua
cm Centímetros
g Gramos
KB Kilo Byte
Km Kilómetros
mm Milímetros
V Voltios
TCPIP Grupo de protocolos de red que respaldan a Internet y que hacen posible la
transferencia de datos entre redes de ordenadores.
xxiii
1 INTRODUCCIÓN Y OBJETIVOS
1.1 Posicionado de piezas
E
n las prácticas de laboratorio que se hacían por parte de los alumnos en los equipos docentes de Robótica
del Departamento de Ingeniería de Sistemas y Automática de la Escuela Técnica Superior de Ingeniería
de Sevilla se limitaba la capacidad de uso de dichos complementos robóticos al posicionar las piezas
dentro del rango de trabajo de un robot de manera manual, irrumpiendo la zona en donde el robot desempeña
sus tareas, lo que desencadenaba una variación muy grande en la precisión de la posición de la pieza a recoger
y las faltas a la seguridad industrial que podrían suceder al momento de la manipulación manual del sistema. El
proceso consistía en colocar la pieza manualmente y reprogramar el movimiento del robot hasta que se tenga un
margen de precisión aceptable.
Ahora, con el sistema de posicionamiento y comunicaciones realizado en este trabajo, se ayudará al estudiante
en las labores de obtención de las piezas, evitando la invasión de la zona de trabajo por el operario; también se
hará un servidor de ethernet desde Arduino para envíar la información de las coordenadas a las que se colocará
la pieza, para luego ser recogida por el robot:
• Posicionado de piezas en medidas de ejes X e Y que el operario solicite para interactúar con el robot.
• Crear el servidor en Arduino y conectarlo con el cliente creado en RobotStudio para el intercambio de
funciones y datos de coordenadas.
• Montar el servidor en Arduino y conoectar el cliente de RobotStudio a esta red, mediante TCP/IP.
• Desarrollar un protocolo de comunicaciones sencillo para la comunicación.
• Obtener los datos de las coordenas X e Y de la pieza en la cinta y enviarla a RobotStudio desde Arduino.
1
1.3 Arduino TCP/IP
El modelo TCP/IP posee un conjunto de guías generales de diseño e implementación de protocolos de red
específicos para consentir que un equipo logre comunicarse en una red local o internet. TCP/IP provee
conectividad de extremo a extremo definiendo como los datos incumbirían ser formateados, direccionados,
transmitidos, enrutados y recibidos por el destinatario [3].
La calidad del modelo TCP/IP está basada en el modelo usado para acceder a Internet o a redes internas (Intranet)
de cualquier tipo de computadoras. Arduino va a permitir conectarse a Internet o a una red interna mediante
TCP/IP y poder realizar múltiples operaciones o usarse como pasarela para conectar a Internet dispositivos que
no tienen esa capacidad. La implementación de la pila de protocolos de TCP/IP en Arduino se hace mediante un
shield o HW adicional que nos da la capa de acceso a red (ethernet o WiFi), capa de internet (IP) y capa de
transporte. La capa de aplicación deberemos implementarla dentro de Arduino ya sea directamente o mediante
una librería [3]. En esta comunicación por estándar se envían hasta 1024 bytes, tanto en RX como TX
1.4 Aplicación
Este trabajo se enfoca en formalizar un posicionador de piezas, que incorporará, por un lado, la cinta
transportadora que dispone de un motor de corriente continua, un encoder incremental, un calibrador digital
ubicado a lo ancho del arreglo y un sensor del tipo fotoeléctrico. Por otra parte, la electrónica de este sistema,
que establecerá las órdenes dictadas a la cinta transportadora usando un microcontrolador Arduino y una placa
ethernet, éste a su vez facilitará las tareas para realizar la interfaz hombre/máquina, la lectura de respuesta de los
elementos presentes en el proyecto, y también servirá para la comunicación del sistema (cinta-Arduino) con el
robot. El control del posicionador de piezas en la zona de trabajo de dos robots se muestra en la Figura 4 [4].
2
Figura 4: Croquis de los posicionadores y zonas de trabajo [3]
Añadido a esto, el sistema a desarrollar facilita la opción de funcionar cuando el microcontrolador Arduino haya
caído, quemado o retirado del sistema, teniendo en cuenta que sí el Arduino no esta presente se podrá hacer un
cambio a local para su uso en general y se podrá actúar de modo manual, provocando que la cinta transportadora
avance, se detenga o retroceda mediante la acción de botones [3].
3
4
2 DESCRIPCIÓN DEL HARDWARE
E
stimando el alcanze del proyecto, se establecen tres etapas, el control con Arduino (y que a la vez sea el
servidor de la red Ethernet), el switch LAN o red interna de los laboratorios, y RobotStudio o El IRB120
que servirán para recoger la pieza (y que servirán como cliente). Por lo tanto, es necesario establecer un
descriptivo general de el hardware, que permitirá entender el proceso de comunicaciones y de accionamiento
del robot y de la cinta asociada al Arduino.
La table de especificaciones muestra los pines, funciones especiales, comunicaciones, interrupciones y otras
caracteristicas físicas y de hardware de este dispositivo.
Tabla 1: Especificaciones Técnicas de Arduino Mega 2560
5
2.1.1 Alimentación
Arduino Mega 2560 tiene la posibilidad de ser alimentado mediante la conexión USB que puede ser
proporcionada por una computadora por poner un ejemplo o una fuente de alimentación externa. La fuente de
poder se selecciona automáticamente [3].
A continuación, se detallan los pines de alimentación de la tarjeta:
• VIN: Entrada de voltaje de la placa cuando se realiza una alimentación externa.
• 5V: Este pin produce una tensión de 5 V regulados.
• 3V3: Fuente de voltaje con una tensión de 3.3V la misma que es generada por el regulador con el que
cuenta la placa, el consumo máximo de corriente es de 50 mA.
• GND: Pines que posee la placa para tener conexión a tierra.
• IOREF: Pin de la placa encargado de proporcionar la referencia de tensión con la que trabaja el
microcontrolador.
2.1.2 Memoria
El ATmega2560 tiene 256KB de memoria flash para almacenar código, tiene 8 KB de memoria SRAM y 4KB
de EEPROM. Para el gestor de arranque son utilizados 8KB de memoria [4].
2.1.4 Comunicación
El ATmega2560 tiene cuatro UART de hardware para comunicación TTL (5V). Un ATmega16U2 en la placa
canaliza uno de estos a través de USB y suministra un puerto virtual para el software en la computadora (las
máquinas Windows requerirán un archivo .inf, pero las máquinas OSX y Linux reconocen la placa de forma
automática). El software Arduino (IDE) incluye un monitor serie que posibilita el envío de datos de texto simples
desde y hacia la placa de Arduino. Los LED RX y TX de la placa parpadearán cuando los datos se transmitan a
través del ATmega8U2 / ATmega16U2 chip y la conexión USB al ordenador (pero no para comunicación serial
en los pines 0 y 1) [3].
7
Figura 6: Shield Ethernet compatible con Arduino Mega [2]
9
Figura 10: Calibrador digital y pines de señales a utilizar [3]
Los procesos de solución para obtener los datos se encuentran en el trabajo anterior; bastará con añadir la librería
y habilitar el puerto de comunicación por interrupción.
10
Figura 12: IRC5C [5]
2.7.1 RemoteService
La finalidad de la caja de RemoteServicees actúar como puente entre el controlador del robot y un servidor
remoto. La conexión entre la caja de Services y el servidor remoto se realiza a travésde la tecnología inalámbrica
GPRS e Internet. A través del puerto de la consola y el puerto Ethernet se almacena, interpreta y filtra la
información proveniente del robot para obtener una valiosa información de servicio en la aplicación
RemoteService (Figura 13) [6].
11
12
3 ESTACIÓN DE ROBOTSTUDIO
E
n este capítulo se va describir el proceso de creación de la estación virtual de RobotStudio, software de
ABB el cual se puede obtener de su página web principal. La versión descargable está bastante limitada
en funciones y para activar todas las funciones hay que tener una licencia, como la que posee la US [7].
La creación de la herramienta tiene que estar dotada de cierta inteligencia y se la desarrollará en la misma
plataforma. La versión de RobotStudio es la 6.08.
13
3.2 Crontrol en RAPID
En este apartado se hará mensión al control creado en RAPID para el envío y recepción de datos por la red; así
como de mavimientos básicos asociados a las coordenadas obtenidas por Arduino. Hay que mensionar que el
programa no crea un servidor interno, ya que al estar RobotStudio montado en el landhost de la computadora es
imposible tratar de crear un servidor que pueda soportar clientes externos y que pasen al la IP del landhost
([Link]). Mas, el proceso inverso: crear un servidor externo y conectar RobotStudio a este (servidor remoto)
es posible. El lenguaje de programación se llama RAPID.
Para el control de la cinta, se han creado 3 funciones que son: leer, absoluto y relativo. Estás 3 funciones serán
explicadas en más detalle en siguientes subsecciones.
14
3.2.3 “Abrir comunicación”
Esta es la función que permite al robot crear un socket del tipo TCP/IP, y luego conectarlo a una dirección IP
([Link]), que en este caso sería la dirección asignada al Arduino, de antemano conocida, con un puerto
dedicado a esta comunicación (4012). Como se muestra, no es necesario es pecificarle una dirección IP propia
al robot ya que él no esta creando el servidor (Figura 19).
15
Figura 21: Función Absoluto + valor Y para Arduino
16
3.2.7 Función “Estado”
Aquí se interpreta el ack que es convertido en las funciones anteriores a un valor num con nombre estad, recibido
desde Arduino (los primeros 8 caracteres ASCII) y permite conocer el estado en el que se encuentran la cinta y
Arduino. 11, 12 y 13 corresponden a los estados realizados correctamente. 1, 2, 3 y 4 corresponden a errores
producidos en el microcontrolador y el sistema (Figura 23).
17
Figura 25: Función Movimiento Robot
3.3 Flexpendant
Parte notable de RobotStudio, es la simulación de uno de verdad y se conecta internamente al robot; y se puede
utilizar tanto para visualizar código como para controlar directamente las articulaciones y realizar operaciones
mediante código RAPID (Figura 26).
18
En la controladora virtual tambien contamos de estos modos. Para tener acceso a ellos debemos ir a la pestaña
de Controlador y seleccionar el icono de Panel de control. Luego podremos seleccionar el modo que se desee
[7].
De vuelta al menu de la Flexpendant logramos ejecutar movimientos, hacienda uso de la opción Jogging. Al
abrirse aparece una ventana donde tenemos dirección a las opciones de movimiento [7].
19
Se puede visualizar difrentes opciones. Las más relevantes en este y anteriores proyectos han sido la de Tool y
WorkObject. Con la primera podemos decir que herramienta tenemos puesta en el robot y con la segunda
respecto a que sistemas de coordenadas, o WorkObject como se nombra en RobotStudio. Si clicásemos sobre
ellos nos aparecerían las diferestes herramientas y WorkObjets, deben haber sido creados previamente, se verá
en apartados siguientes [7].
Al seleccionar Motion Mode, podemos elegir el tipo de movimiento que vamos a hacer. En el ejemplo de la
ventana estaríamos controlando los ejes 1, 2 y 3 y es por ello que en el apartado position nos aparecen los grados
a los que están los ejes del robot. Otra opción sería mover al robot de forma lineal. En este caso Position nos da
las coordenadas en la que se encuentra el TCP de la herramienta en coordenadas cartesianas y respecto al
WorkObject elegido ademas de sus correspondiente cuaterniones [7].
Motion Mode también nos da la opción de hacer movimientos de reorientación sobre el TCP que hayamos
definido [7].
Un paso que debemos dar antes de modificar la posición manualmente es habilitar la opción Enable. La
controladora real tiene un botón en la parte trasera que nos permite habilitar el movimiento si la pulsamos
(además recordar que debemos haber seleccionado Manual en el panel de control) y si liberamos el botón deja
al robot muerto, sin poder hacer movimientos [7]. Haciendo uso del joystick podemos mover el robotcomo se
desee tomando en cuenta sus limitaciones. Podemos de igual manera elegir la velocidad con el botón de
velocidad [7].
20
4 DESARROLLO DE LA PROGRAMACIÓN EN
ARDUINO
U
na vez teminada la Sección de RobotStudio, es necesario programar las acciones de Arduino 2560, y ya
que se tienen varias partes y varios sensores, se han hecho programas que prueban cada una de las fases
de dasarrollo del proyecto del lado de Arduino. Estas partes son: El teclado matricial, el encoder
incremental, la Shield de Ethernet, la pantalla LCD, control de motores, lectura de la señal obtenida en el
calibrador digital, y que, varios de estos puntos fueron resueltos en trabajos anteriores.
21
#include <Keypad.h>
char keys[rowsCount][columsCount] = {
{ '1','2','3', 'A' },
{ '4','5','6', 'B' },
{ '7','8','9', 'C' },
{ '#','0','*', 'D' }
};
void setup() {
[Link](9600);
}
void loop() {
char key = [Link]();
if (key) {
[Link](key);
}
}
22
4.2 Control con Puente L298D
El módulo controlador de motores L298N H-bridge permite controlar la velocidad y la dirección de dos motores
de corriente continua o un motor paso a paso de una forma muy sencilla, gracias a los 2 los dos H-bridge que
posee.
El rango de tensiones en el que trabaja este módulo va desde 3V hasta 35V, y una intensidad de hasta 2A. A la
hora de alimentarlo hay que tener en cuenta que la electrónica del módulo consume unos 3V, así que los motores
reciben 3V menos que la tensión con la que alimentemos el módulo (Figura 34).
// check to see if it's time to blink the LED; that is, if the
difference
// between the current time and last time you blinked the LED is
bigger than
// the interval at which you want to blink the LED.
digitalWrite(enaMotor, HIGH);
digitalWrite(motorizq, HIGH);
digitalWrite(motorder, LOW);
delay(5000);
digitalWrite(enaMotor, HIGH);
digitalWrite(motorizq, LOW);
digitalWrite(motorder, HIGH);
delay(5000);
}
23
4.3 Puente H, encoder incremental y matriz de pulsadores
Se decidió trabajar con la matriz de pulsadores, ya que ocupan menos espacio y no hay que usar resistencias. La
librería dedicada se encarga de obtener los pulsadores y eliminar falsos positivos. A demás se quiso manipular
con el teclado la dirección y parada del motor conecado al Puente H. El programa descrito a continuación pone
en acción en un sentido con el carácter A, con B en sentido contrario y con el caracter 3 para detener el motor.
Con los mismos puertos descritos en las Figuras 33 Y 24, respectivamente.
#include <Keypad.h>
char keys[rowsCount][columsCount] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '#', '0', '*', 'D' }
};
void setup() {
[Link] (9600);
//pines para encoder
pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
pinMode(3, INPUT_PULLUP); // internalเป็ น pullup input pin 3
//Setting up interrupt
pinMode(enaMotor, OUTPUT);
pinMode(motorizq, OUTPUT);
pinMode(motorder, OUTPUT);
}
24
double vuelta = 0;
void loop() {
// Send the value of counter
// if ( counter != temp ) {
char key = [Link]();
if(key == 'A'){
vuelta=mapfloat(counter,0,1200,0,1);
[Link] (vuelta);
motordelante();}
if(key == '3'){
vuelta=mapfloat(counter,0,1200,0,1);
[Link] (vuelta);
motorparo();}
if(key == 'B'){
vuelta=mapfloat(counter,0,1200,0,1);
[Link] (vuelta);
motoratras();}
}
}
void ai1() {
// ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if (digitalRead(2) == LOW) {
counter--;
} else {
counter++;
}
}
void motordelante() {
digitalWrite(enaMotor, HIGH);
digitalWrite(motorizq, HIGH);
digitalWrite(motorder, LOW);
}
void motoratras() {
digitalWrite(enaMotor, HIGH);
digitalWrite(motorizq, LOW);
digitalWrite(motorder, HIGH);
}
void motorparo() {
digitalWrite(enaMotor, LOW);
digitalWrite(motorizq, LOW);
digitalWrite(motorder, LOW);
}
25
4.4 Creación de un servidor IP con un puerto determinado.
En esta sección se probó creando un servidor en la dirección [Link]:4012 desde Arduino para que con
RobotStudio se pudieran comunicar. Se crea el socket, luego se espera a que haya un servidor, se lee una
instrucción y se procede a devolver dos valores. El programa es relativamente sencillo y cumplió con la función
de ser el pilar más fundamental en el que sostendría este trabajo a largo plazo. Cada línea esta comentada con la
acción que se realiza. Desde este punto, se puede notar que había ya que hacer cierto protocolo de
comunicaciones sencillo para que ambos se pudieran entender, esto se puede ver desde la línea 76, función:
corregircadena. El cliente se crea en RobotStudio y se indicá más adelante en la sección de RobotStudio.
#include <SPI.h>
#include <Ethernet.h>
unsigned char bufCAN[15];
unsigned int len2 = 0;
byte MAC[]=
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //direccion Mac generica (puede
ser cualquier otra mac
// esta mac tiene que ser
diferente de la mac de todos los dispositivos en
//la red
};
byte IP[]=
{
192,168,1,200 //Ip asiganda a la placa (aqui se
creará el socket)
};
EthernetServer server(4012);
void setup()
{
[Link](MAC, IP);
[Link]();
[Link](9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port
only
}
[Link]("Ethernet WebServer Example");
}
char c;
void loop()
{
int sensorValue = analogRead(A0);
float voltage = sensorValue * (500.0 / 1023.0);
comunicartcpip(voltage);
delay(10);
}
void paracomunicacion(){
EthernetClient client = [Link]();
[Link](); //cierra el socket
}
#include <SPI.h>
#include <Ethernet.h>
//_______ VARIABLES DE TCP_IP
char bufCom[40]; //buffer de comunicaciones
unsigned int len2 = 0; //longitud de los caracteres a obtener de
robotstudio
byte MAC[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //direccion Mac generica (puede
ser cualquier otra mac
// esta mac tiene que ser diferente de la mac de todos los
dispositivos en
//la red
};
byte IP[] =
{
192, 168, 1, 200 //Ip asiganda a la placa (aqui se
creará el socket)
};
//________________________________
EthernetServer server(4012);
//________________________________
EthernetServer server(4012);
void setup() {
[Link](MAC, IP);
[Link]();
[Link](9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port
only
}
[Link]("Ethernet WebServer Example");
pinMode(13, OUTPUT);
delay(10);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (500.0 / 1023.0);
comunicartcpip();
delay(11);
}
int len = 0;
void comunicartcpip() {
}
//[Link]();
if ([Link]()) {
funcioncinta(bufCom);
String a = corregircadena(estado);
String b = corregircadena(posx);
String c = corregircadena(posy);
String d = a + b + c;
while (estado == 0) {
; 29
}
[Link](d);
[Link](d);
//[Link]();
if ([Link]()) {
funcioncinta(bufCom);
String a = corregircadena(estado);
String b = corregircadena(posx);
String c = corregircadena(posy);
String d = a + b + c;
while (estado == 0) {
;
}
[Link](d);
[Link](d);
[Link]();
}
// [Link](); //cierra el socket
}
delay(5000);
[Link](cadena);
estado = 12;
break;
case 'r' : //funcion movimiento relativo
estado = 0;
cadena = "";
//[Link](funcion);
for (int j = 1; j < len; j++) {
cadena = cadena + bufCm[j];
}
30
delay(5000);
[Link](cadena);
estado = 13;
break;
default:
estado = 1; //ningun caso coincide
[Link]("El caracter enviado desde RobotStudio no
coincide con ninguna funcion");
[Link]("Enviar: l (leer) a (absoluto) o r (relativo)
");
break;
}
bufCm[0] = 'x';
}
32
Figura 37: Conexión final, esquema cableado de Arduino y banda transportadora
byte IP[] =
{
192, 168, 1, 200 //Ip asiganda a la placa (aqui se
creará el socket)
};
//-----------------------------------------------------
// A= local
// B=remoto
// C=motor delante (local)
// D=motor atras (local)
// *=motro paro (local)
// 3=sensor
//
//
//
const byte rowsCount = 4;
const byte columsCount = 4;
char keys[rowsCount][columsCount] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '#', '0', '*', 'D' }
};
//------------------------------------------------------
//------------------------------------------------------
34
void setup() {
//pines para encoder
pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
pinMode(3, INPUT_PULLUP); // internalเป็ น pullup input pin 3
//interrupciones para encoder
//A rising pulse from encodenren activated ai0(). AttachInterrupt 0
is DigitalPin nr 2 on moust Arduino.
attachInterrupt(0, ai0, RISING);
//B rising pulse from encodenren activated ai1(). AttachInterrupt 1
is DigitalPin nr 3 on moust Arduino.
attachInterrupt(1, ai1, RISING);
//------------------------------------------------------
void loop() {
key = [Link](); //para decidir si local o remoto 'A' para
local
local:;
if (key == 'A') { //local
local2:;
motorparo();
cinta = 1;
[Link]("local");
char key2 = '*'; //key2 variable asociada al movimiento de la
cinta
35
while (key2 != 'B') { //mientras no se cambie a remoto
key2 = [Link](); //obtiene la direccion del movimiento
de la cinta
if (key2 == 'B') { //sale del ciclo si == 'B'
key = 'B';
goto remoto;//goto para salir del ciclo while
}
if (key2 == 'C') { //movimiento para adelante
posx = mapfloat(counter, 0, 1200, 0, 1);
[Link] (posx);
motordelante();
}
motoratras();
}
if (key2 == '*') {
posx = mapfloat(counter, 0, 1200, 0, 1);
[Link] (posx);
motorparo();
}
}
key2 = '*';
motorparo();
}
remoto:;
if (key == 'B') { ////para decidir si local o remoto 'B' para
remoto
motorparo();
cinta = 2;
[Link]("remoto");
char key2 = '*'; // Key2 variable asociada al movimiento de la
cinta
while (key2 != 'A') {
key2 = [Link](); //obtiene la direccion del movimiento
de la cinta
if (key2 == 'A') { //sale del ciclo si == 'B'
key = 'A';
error = 2;
comunicartcpip();
if (error == 2) {
error = 0;
goto local2;//goto para salir del ciclo while
}
}
posx = mapfloat(counter, 0, 1200, 0, 1);
comunicartcpip();
if (error == 2) {
error = 0;
}
key2 = '*';
}
// comunicartcpip();
delay(11);
36
}
}
key2 = '*';
}
// comunicartcpip();
delay(11);
}
int len = 0;
void comunicartcpip() {
//[Link]();
if ([Link]()) {
if ([Link]() == 'A') {
error = 2;
[Link]("se cambio de remoto a local se estaba rec");
}
funcioncinta(bufCom); //determina la funcion a realizar enviada
desde RobotStudio
String d = cadenaenviar();
while (estado == 0) {
;
}
[Link](d);
[Link](d);
[Link]();
}
// [Link](); //cierra el socket
}
37
void funcioncinta(char bufCm[40]) { //se verifica que funcion debe
tener la cinta dependiendo de lo que
//el cliente solicite
String cadenadistancia;
String pasos;
if (bufCm[0] == 'a') {
estado = 0;
cadenadistancia = "";
//[Link](funcion);
for (int i = 1; i < len; i++) {
38
goto finproceso;
}
if (valorposicionx + posx < 0) { //si el valor es negativo
entonces esta fuera de rango
error = 4; //codigo de error
motorparo();
goto finproceso;
}
while (posx - posxaux >= 0) {
tiempoactual = millis();
float posxnew;
posx = mapfloat(counter, 0, 1200, 0, 1);
if (tiempoactual == tiempoespera - 10000) {
posxnew = posx;//se asigna el valor de posx a posxnew en el
tiempo 0
}
if (tiempoactual >= tiempoespera) {
if (posxnew == posx) {//si no hay cambios en la posicion en
x
error = 3; //se asigna el codigo de error para enviar
motorparo();
break;
}
}
delay(1);
}
}
motorparo();
delay(1);
estado = 12;
}
39
for (int k = j + 1; k < len; k++) {
pasos = pasos + bufCm[k];
}
int cont = 0;
int pasosfloat = [Link]();
while (cont < pasosfloat) {
posx = mapfloat(counter, 0, 1200, 0, 1); //posx
float valorposicionx = [Link](); //transforma
el dato del movimiento en un flotante para mover la cinta
posxaux = valorposicionx + posx; //para comparar valores
long tiempoespera = millis() + 10000; //TIEMPO DE ESPERA
long tiempoactual = millis(); //TIEMPO QUE TRANSCURRIRA
}
delay(1);
}
}
if (valorposicionx < 0) {
motoratras();
if ([Link]() == 'A') {
error = 2;
motorparo();
goto finproceso;
}
40
if (valorposicionx + posx < 0) { //si el valor es negativo
entonces esta fuera de rango
error = 4; //codigo de error
motorparo();
goto finproceso;
}
while (posx - posxaux >= 0) {
tiempoactual = millis();
float posxnew;
posx = mapfloat(counter, 0, 1200, 0, 1);
if (tiempoactual == tiempoespera - 10000) {
posxnew = posx;
}
if (tiempoactual >= tiempoespera) {
if (posxnew == posx) {
error = 3;
motorparo();
goto finproceso;
}
}
delay(1);
}
}
motorparo();
if(error==3)goto finproceso;
[Link](error);
cont++;
delay(1000);
}
estado = 13;
}
if (estado != 11 && estado != 12 && estado != 13) {
estado = 1;
[Link]("El caracter enviado desde RobotStudio no coincide
con ninguna funcion");
[Link]("Enviar: l (leer) a (absoluto) o r (relativo) ");
}
finproceso:;
bufCm[0] = '+'; //reiniciar funcion en el buffer
if (error == 2) {
estado = 2;
[Link]("Se cambio de remoto a local 2");
}
if (error == 3) {
estado = 3;
[Link]("Encoder no funciona 3");
}
if (error == 4) {
estado = 4;
[Link]("Valor absoluto negativo demasiado grande 4");
}
}
41
String cadenaenviar() { //funcion para ingresar todos los datos:
estado de la cinta
// posx y pos y para ser enviados por tcpip
String a = corregircadena(estado); //estado
String c = corregircadena(posx); //posy
String b = corregircadena(posy); //pos x
String d = a + b + c; //estado, posy, pos x
return d;
}
String corregircadena(float x) { //corrigue y añade 0 al número para
enviar al cliente
String result;
if (x >= 0) { //para x>0
if (x >= 0 && x < 10) { //se añaden 0s a la cadena para enviar
result = "0000" + String(x, 2);
}
else {
if (x >= 10 && x < 100) {
result = "000" + String(x, 2);
}
else {
if (x >= 100 && x < 1000) {
result = "00" + String(x, 2);
}
else {
if (x >= 1000 && x < 10000) {
result = "0" + String(x, 2);
}
}
}
}
}
if (x < 0) { //para x<0
x = x * -1;
if (x >= 0 && x < 10) {
result = "-000" + String(x, 2); //se añaden 0 y el signo a la
cadena
}
else {
if (x >= 10 && x < 100) {
result = "-00" + String(x, 2);
}
else {
if (x >= 100 && x < 1000) {
result = "-0" + String(x, 2);
}
else {
if (x >= 1000 && x < 10000) {
result = '-' + String(x, 2);
}
}
}
}
}
return result;
}
42
void motordelante() { //motor avanza
digitalWrite(enaMotor, HIGH);
digitalWrite(motorizq, HIGH);
digitalWrite(motorder, LOW);
[Link]("Motor avanza");
}
void motoratras() { //motor retrocede
digitalWrite(enaMotor, HIGH);
digitalWrite(motorizq, LOW);
digitalWrite(motorder, HIGH);
[Link]("Motor retrocede");
}
void motorparo() { //motor para
digitalWrite(enaMotor, LOW);
digitalWrite(motorizq, LOW);
digitalWrite(motorder, LOW);
[Link]("Paro motor");
}
}
}
43
44
5 DESARROLLO DE LA PROGRAMACIÓN EN
ROBOTSTUDIO
E
stablecidas las pruebas del capitulo anterior y su respectivo desarrollo, se fueron probando y creando los
codigos de RobotStudio que permitieron comprobar la comunicación y el envío de datos; así como la de
las funciones y la corrección de errores. Todo esto permitió realizar versiones de prueba de código en
RAPID para sostener al cliente ethernet y también de ser el encargado de mandar las funciones solicitadas a la
cinta (Arduino).
MODULE Module1
VAR socketdev my_socket;
VAR rawbytes data;
VAR rawbytes raw_data;
VAR byte nuevo:=0;
VAR num n;
VAR string n2;
var num float;
var num float2;
VAR byte data_buffer;
VAR bool ok:=true;
VAR num i:=1;
VAR rawbytes receive_string;
VAR string string1;
PROC main()
!Añada aquí su código
!SocketCreate server;
SocketCreate my_socket; !crea el socket
SocketConnect my_socket, "[Link]", 4012; !lo enlace a la
direccion y al puerto correspondiente al arduino
WHILE ok=TRUE DO
SocketSend my_socket,\Str:="a23"; !escribe en la red y lo envia a
arduino (donde será leido)
WaitTime 0.5; !espera un tiempo
SocketReceive my_socket \RawData :=
receive_string,\Time:=WAIT_MAX;
!UnpackRawBytes data,1,nuevo,\ASCII:=15;
!!UnpackRawBytes data,2,nuevo,\ASCII:=1;
!UnpackRawBytes data,3,nuevo1,\ASCII:=1;
! UnpackRawBytes data,4,nuevo2,\ASCII:=1;
45
SocketClose my_socket; !cierra el socket
ENDWHILE
!TPWrite "Instruction SocketClose has been executed";
!UnpackRawBytes data,1,nuevo,\ASCII:=15;
!!UnpackRawBytes data,2,nuevo,\ASCII:=1;
!UnpackRawBytes data,3,nuevo1,\ASCII:=1;
! UnpackRawBytes data,4,nuevo2,\ASCII:=1;
ENDPROC
ENDMODULE
MODULE Module1
VAR socketdev my_socket;
VAR num n;
VAR string posx;
VAR string posy;
VAR num posxint;
VAR num posyint;
VAR num estad;
VAR bool ok;
VAR bool okposx;
VAR bool okposy;
VAR bool okack;
VAR num i:=1;
VAR rawbytes receive_string; !recibe un paquete de datos en string
VAR string ack;
PROC main()
!Añada aquí su código
abrircomunicacion;
leer;
WaitTime 1;
absoluto;
WaitTime 1;
relativo;
! WHILE ok=TRUE DO
! ENDWHILE
!TPWrite "Instruction SocketClose has been executed";
ENDPROC
PROC abrircomunicacion()
ENDPROC
PROC leer()
! ClearRawBytes receive_string;
WaitTime 1;
SocketSend my_socket,\Str:="l230"; !escribe en la red y lo envia a
arduino (donde será leido)
WaitTime 0.1; !espera un tiempo
ENDPROC
PROC cerrarcomunicacion()
ClearRawBytes receive_string;
ENDPROC
PROC estado()
ENDPROC
PROC cerrarcomunicacion()
SocketClose my_socket; !cierra el socket
ENDPROC
ENDMODULE
MODULE Module1
VAR socketdev my_socket;
VAR num n;
VAR string posx;
VAR string posy;
VAR string cadena;
VAR num posxint;
VAR num posyint;
VAR num estad:=0;
VAR bool ok;
VAR bool okposx;
VAR bool okposy;
VAR bool okack;
VAR num i:=1;
VAR rawbytes receive_string;
!recibe un paquete de datos en string
VAR string ack;
CONST robtarget
Target_pieza:=[[436.2339,144,180.9312],[0.70711,0,0,0.70711],[0,-1,-
1,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
CONST robtarget
Target_10:=[[436.2339,144.422,389.7914],[0.70711,0,0,0.70711],[0,-1,-
1,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
CONST robtarget Target_20:=[[-
101.0329,144.422,389.7915],[0.70711,0,0,0.70711],[1,-
1,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
CONST robtarget Target_30:=[[-
101.0329,144.422,173.8547],[0.70711,0,0,0.70711],[1,-
1,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
49
PROC main()
! ENDWHILE
!TPWrite "Instruction SocketClose has been executed";
ENDPROC
PROC abrircomunicacion()
SocketCreate my_socket;
!crea el socket
SocketConnect my_socket,"[Link]",4012;
!lo enlace a la direccion y al puerto correspondiente al
arduino
ENDPROC
PROC leer()
! ClearRawBytes receive_string;
WaitTime 1;
SocketSend my_socket,\Str:="l";
!escribe en la red y lo envia a arduino (donde será leido)
WaitTime 0.1;
!espera un tiempo
SocketReceive
my_socket\RawData:=receive_string,\Time:=WAIT_MAX;
WaitTime 0.01;
!espera un tiempo
UnpackRawBytes receive_string,1,ack\ASCII:=8;
!8 es el espacio en caracteres que forman el número
UnpackRawBytes receive_string,9,posx\ASCII:=8;
UnpackRawBytes receive_string,17,posy\ASCII:=8;
!UnpackRawBytes receive_string, 1, posy \ASCII:=24;
!ok:=StrToVal(ack,float);
okposx:=StrToVal(posx,posxint);
okposy:=StrToVal(posy,posyint);
okack:=StrToVal(ack,estad);
ClearRawBytes receive_string;
estado;
ENDPROC
50
PROC absoluto(num distancia)
!ClearRawBytes receive_string;
WaitTime 1;
cadena:=NumToStr(distancia,1);
!cadena:="a"+cadena;
SocketSend my_socket,\Str:="a"+cadena;
!escribe en la red y lo envia a arduino (donde será leido)
WaitTime 0.1;
!espera un tiempo
SocketReceive
my_socket\RawData:=receive_string,\Time:=WAIT_MAX;
WaitTime 0.01;
!espera un tiempo
UnpackRawBytes receive_string,1,ack\ASCII:=8;
!8 es el espacio en caracteres que forman el número
UnpackRawBytes receive_string,9,posx\ASCII:=8;
UnpackRawBytes receive_string,17,posy\ASCII:=8;
okposx:=StrToVal(posx,posxint);
okposy:=StrToVal(posy,posyint);
okack:=StrToVal(ack,estad);
ClearRawBytes receive_string;
estado;
ENDPROC
SocketReceive
my_socket\RawData:=receive_string,\Time:=WAIT_MAX;
WaitTime 0.01;
!espera un tiempo
UnpackRawBytes receive_string,1,ack\ASCII:=8;
!8 es el espacio en caracteres que forman el número
UnpackRawBytes receive_string,9,posx\ASCII:=8;
UnpackRawBytes receive_string,17,posy\ASCII:=8;
okposx:=StrToVal(posx,posxint);
okposy:=StrToVal(posy,posyint);
okack:=StrToVal(ack,estad);
ClearRawBytes receive_string;
estado;
ENDPROC
51
PROC estado()
IF estad=11 THEN
TPWrite "Instruction leer have been done.
Estado:"\Num:=estad;
movimientorobot;
ENDIF
IF estad=12 THEN
TPWrite "Instruction absoluto have been
[Link]:"\Num:=estad;
movimientorobot;
ENDIF
IF estad=13 THEN
TPWrite "Instruction relativo have been
[Link]:"\Num:=estad;
movimientorobot;
ENDIF
Stop;
ENDIF
IF estad=4 THEN
TPWrite "Valor absoluto negativo demasiado grande.
Erro:"\Num:=estad;
ErrWrite "Arduino error","Valor absoluto negativo demasiado
grande."\RL2:="Enviar un valor menor o positivo.";
Stop;
ENDIF
ENDPROC
PROC cerrarcomunicacion()
SocketClose my_socket;
!cierra el socket
ENDPROC
PROC movimientorobot()
IF estad=11 THEN
Movel offs(Target_pieza,-
posxint*5,posyint*5,0),v500,fine,t_pinza\WObj:=wobj0;
!Movej offs(Target_10,-posxint*2,80-
52
posxint*2,0),v500,z100,t_pinza\WObj:=wobj0;
Movej Target_20,v500,fine,t_pinza\WObj:=wobj0;
Movej Target_30,v500,fine,t_pinza\WObj:=wobj0;
Movej Target_30,v500,fine,t_pinza\WObj:=wobj0;
PROC movimientorobot()
IF estad=11 THEN
Movel offs(Target_pieza,-
posxint*5,posyint*5,0),v500,fine,t_pinza\WObj:=wobj0;
!Movej offs(Target_10,-posxint*2,80-
posxint*2,0),v500,z100,t_pinza\WObj:=wobj0;
Movej Target_20,v500,fine,t_pinza\WObj:=wobj0;
Movej Target_30,v500,fine,t_pinza\WObj:=wobj0;
Movej Target_30,v500,fine,t_pinza\WObj:=wobj0;
Movej Target_20,v500,fine,t_pinza\WObj:=wobj0;
Movej Target_10,v500,fine,t_pinza\WObj:=wobj0;
! Movel offs(Target_pieza,-posxint*2,50-
posxint*2,0),v500,z100,t_pinza\WObj:=wobj0;
ENDIF
ENDPROC
ENDMODULE
Figura 38: Trama de datos envíada desde RobotStudio para la Función Leer
Absoluto:
Figura 39: Trama de datos envíada desde RobotStudio para la Función Absoluto
53
Relativo:
Figura 40: Trama de datos envíada desde RobotStudio para la Función Relativo
Ahora, cada función que se envía tiene una respuesta desde Arduino:
Leer:
Figura 41: Trama de datos envíada desde Arduino para la Función Leer
Absoluto:
Figura 42: Trama de datos envíada desde Arduino para la Función Absoluto
Relativo:
Figura 43: Trama de datos envíada desde Arduino para la Función Relativo
54
55
6 SIMULACIÓN
E
ntrando en RobotStudio en la pestaña de “Simulación” encontramos la siguiente botonera:
Con esta botonera se puede ejecutar el código de RAPID en la estación actúal y en el caso de que se desee grabar
la simulación, se selecciona la opción de reproducir, grabar en visor [7].
56
Figura 48: Ventana guardar estado actual RobotStudio
57
7 RESULTADOS
E
stimadas las necesidades, el alcance y las herramientas necesarias; así como la programación, tanto para
Aruino como para RobotStudio, se procede a mostrar los resultados en pantalla para cada uno de los
programas mencionados; en esta sección se separá por modos de Funcionamiento (Local o Remoto) y
luego por funciones de tareas (Leer, Absoluto y Relativo), esto permitirá entender el funcionamiento y salida por
pantalla de las secciones 5.3 (RobotStudio) y 4.6 (Arduino). Permitirá valorar la efectividad con la que las
funciones realizan su tarea y la relación en ambos programas.
Cada componente electrónico se ilustra en la Figura 50 y permite, en forma general, entender el funcionamiento
de la cinta; el componente más importante y que simula la cinta es la matriz de leds conectado al puente H, esté
permite visualizar de forma práctica la función que se esta procesando por Arduino; para los siguientes apartados
será de vital importancia. Al encenderse, Arduino parte de un estado de reposo, apagando el motor y seteando a
0 las coordenadas X e Y de la cinta.
58
[Link] Salida Serial
Para efectos didácticos, se presenta la explicación de cada línea mostrada en la salida serial de Arduino (Figura
51):
[Link] Cinta
Como se puede apreciar en la Figura 52, el motor se activa en la dirección solicitada. Hasta que no se envie el
comando de detener la cinta (por medio del botón), el motor continuará permanentemente encendido.
59
[Link] Salida Serial
La salida serial muestra los mismos resultados con respecto a la sección [Link], con excepción de la última línea
que corresponde a la función motor atrás (motor retrocede en la salida). Para el resto de los parámetros, lo
mencionado en la sección [Link] son los esencialmente lo mismo.
[Link] Cinta
Como se puede apreciar en la Figura 54, el motor se activa en la dirección solicitada. Hasta que no se envie el
comando de detener la cinta, el motor continuará permanentemente encendido.
60
[Link] Cinta
Como se puede apreciar en la Figura 56, el motor se activa en la dirección solicitada. Hasta que no se envie el
comando de detener la cinta, el motor continuará permanentemente encendido.
[Link] RobotStudio
Como se ha indicado en apartados y capítulos anteriores, basta llamar en la función Main a la función leer;
empezando desde Arduino y poniéndolo en modo Remoto, luego se empieza con la simulación. RobotStudio
realiza todas las operaciones solicitadas y envía la función leer (basta con quitar el signo de comentario colocado
delante de la función dentro de Main, como se muestra en la Figura 57.
61
[Link] Arduino
Ahora bien, en Arduino se presentará la siguiente salida, la cual permite apreciar los valores que se envían hacia
RobotStudio. Como la función no requiere salida hacia los motores; entonces, no se produce cambio alguno,
pero claro; la salida serial muestra lo que esta pasando.
La lectura muestra las siguientes variables: estad, posxint, y posyint. La Figura 59 muestra la salida en pantalla
de RobotStudio, luego de ser recibido desde Arduino, con los valores ya convertidos de ASCII a num.
[Link] RobotStudio
Como se ha indicado previamente, basta llamar en la función Main a la función absoluto; empezando desde
Arduino y poniéndolo en modo Remoto. RobotStudio realiza todas las operaciones solicitadas y envía la función
(basta con quitar el signo de comentario colocado delante de la función dentro de Main, como se muestra en la
62
Figura 60; se requiere aumentar la cantidad en cm que se desea que la cinta avance.
[Link] Arduino
En Arduino se presentará la siguiente salida, la cual deja apreciar los valores que se envían hacia RobotStudio
luego de cumplir con la condición de movimiento en cm recibida. Arduino espera alrededor de 10 segundos a
la espera de que haya un cambio en la coordenada Y (esto para saber si la cinta se esta moviendo gracias al
encoder incorporado); cuando se ha cumplido, se empaqueta la trama de datos correspondiente y se envía a
RobotStudio.
[Link] Cinta
Arduino activará el motor de la cinta, y esperará a los 10 segundos para afirmar que la cinta se ha movido y
empaquetarán los datos para envíarlos a RobotStudio. Durante el proceso y antes de envíar la cadena de
caracteres correspondiente, Arduino revisará que la cantidad Y trasladada (por el motor), ya sea en sentido
horario o antihorario (dependerá del signo con el que se ha enviado la distancia en RobotStudio), se haya
completado correctamente.
La Figura 62, muestra la función absoluta ejecutándose con un valor de 5 cm (envíada desde RobotStudio). La
Figura 63, muestra el proceso detenido luego de completarse correctamente los 5 cm (para lograr los 5 cm hay
63
que dar 5 vueltas en el encoder: cada vuelta corresponde a 1 cm).
La lectura muestra las siguientes variables: estad, posxint, y posyint. La Figura 64 muestra la salida en pantalla
de RobotStudio, luego de ser recibido desde Arduino, con los valores ya convertidos de ASCII a num.
[Link] IRB120
El robot (simulado), tomará los datos y dependiendo de sí se han ejecutado correctamente, y realizará
movimientos simples según puntos de trayectorias propuestos. Si el valor recibido desde Arduino es positivo el
brazo se moverá a la derecha de la pantalla; si es negativo se irá moviendo a la izquierda. Cada función (11, 12
y 13) ejecutadas correctamente provocarán el movimiento del robot. En apartados posteriores se realizará una
comparativa en la localización espacial del brazo del robot al recoger la pieza para apreciar el movimiento
producido.
64
7.2.3 Función Relativo
La función Relativo, envíada desde RobotStudio, permite leer las coordenadas X e Y de la cinta en la posición
actúal de la pieza. Se crean observaciones de las variables asociadas al estado de la cinta, posición X y posición
Y; ambas enviadas desde Arduino. Como se requiere la acción de la cinta, Arduino completará las acciones
necesarias, y luego devolverá la cadena de caracteres correspondiente. Esta función requiere de un par de
números para ser completada por la cinta (la distancia a recorrer por la cinta y el número de veces que se desea
hacer este movimiento).
[Link] RobotStudio
Basta llamar en la función Main a la función relativo; empezando desde Arduino y poniéndolo en modo Remoto.
RobotStudio realiza todas las operaciones solicitadas y envía la función (basta con quitar el signo de comentario
colocado delante de la función dentro de Main, como se muestra en la Figura 65. Se requiere aumentar la
cantidad en cm que se desea que la cinta avance y el numéro de ciclos que se va a repetir este proceso.
[Link] Arduino
En Arduino se presentará la siguiente salida, la cual deja apreciar los valores que se envían hacia RobotStudio
luego de cumplir con la condición de movimiento en cm recibida y el número de ciclos. Arduino espera alrededor
de 10 segundos, en cada ciclo, a la espera de que haya un cambio en la coordenada Y (esto para saber si la cinta
se esta moviendo gracias al encoder incorporado); cuando se ha cumplido, se empaqueta la trama de datos
correspondiente y se envía a RobotStudio.
65
que cumplir 3 ciclos de 4cm cada ciclo; lo que sumado son 12 cm (12.85 para el encoder que es una
aproximación por el mapeo en los valores en Arduino).
[Link] Cinta
Arduino activará el motor de la cinta, y esperará a los 10 segundos, en cada ciclo, para afirmar que la cinta se ha
movido lo que corresponda (entre ciclo y siglo se espera 1 segundo). Se empaquetarán los datos para envíarlos
a RobotStudio. Durante el proceso y antes de envíar la cadena de caracteres correspondiente, Arduino revisará
que la cantidad Y trasladada (por el motor), ya sea en sentido horario o antihorario (dependerá del signo con el
que se ha enviado la distancia en RobotStudio), se haya completado correctamente.
La Figura 67, muestra la función realativa ejecutándose con un valor de 4 cm (envíada desde RobotStudio) con
3 ciclos. La Figura 68, muestra el proceso detenido luego de completarse correctamente los 4 cm (para lograr
los 4 cm hay que dar 4 vueltas en el encoder: cada vuelta corresponde a 1 cm).
La lectura muestra las siguientes variables: estad, posxint, y posyint. La Figura 69 muestra la salida en pantalla
de RobotStudio, luego de ser recibido desde Arduino, con los valores ya convertidos de ASCII a num.
66
Figura 69: Variables recibidas en RobotStudio
[Link] IRB120
Al igual que en el apartado [Link] el robot (simulado), tomará los datos y dependiendo de sí se han ejecutado
correctamente, y realizará movimientos según puntos de trayectorias propuestos. Si el valor recibido desde
Arduino es positivo el brazo se moverá a la derecha de la pantalla; si es negativo se irá moviendo a la izquierda.
Cada función (11, 12 y 13) ejecutadas correctamente provocarán el movimiento del robot. En apartados
posteriores se realizará una comparativa en la localización espacial del brazo del robot al recoger la pieza para
apreciar el movimiento del robot.
7.3 Errores
Como se propuso en el apartado 1.5, también se han considerado errores que pudieran suceder a lo largo del
trabajo con la cinta; cada error tiene un código único que tiene un significado en particular, también se mostrará
por pantalla en el serial de Arduino y como un mensaje de error en RobotStudio. Se pueden producir uno o mas
de estos errores en el mismo ciclo de trabajo.
7.3.1 Error 01
Codigo 1: El caracter enviado desde RobotStudio no coincide con ninguna función; se deberá envíar un caracter
correcto. Esto significa que RobotStudio no esta envíando ninguno de los 3 caracteres conocidos por Arduino;
por lo que inevitablemente provocará este fallo. La Figura 70 muestra la salida en el serial de Arduino y la Figura
71, muestra el caracter enviado desde RobotStudio (también podrá ser visto en Flexpendant) que provoca el
fallo. La Figura 72 muestra el error en la salida de RobotStudio.
67
7.3.2 Error 02
Codigo 2: Se ha cambiado (en Arduino) de Remoto a Local, y por tanto la cinta se detendrá. En este caso el
código de error nos dice que el operario cambió de remoto a local sin esperar que el proceso que se estaba
ejecutando en Arduino termine. La Figura 73 muestra la salida serial en Arduino y la Figura 74 muestra la Salida
en RobotStudio.
7.3.3 Error 03
Codigo 3: Encoder no funciona. Revisar función de la cinta y el sensor encoder. Para este error, se toma en
cuenta los 10 segundos en los que, si el puente H está activo, pero no se lee un incremento en la señal de salida
del encoder que corresponde al eje Y, entonces se crea este error. Esto puede significar: que el motor esta
desconectado o que el encoder lo está; por lo general se toma el caso de que el encoder se haya desconectado,
como más frecuente; por lo tanto, la Figura 75 muestra la salida por serial para este error. La Figura 76 muestra
la salida en RobotStudio.
68
Figura 76: Salida RobotStudio para Error 03
7.3.4 Error 04
Codigo 4: Valor de movimiento negativo (en retroceso para la cinta) es demasiado grande. Modificar el valor a
envíar en RobotStudio. Este error solo se da si la petición de movimiento de RobotStudio es un valor negativo
superior a los cm en los que ya se haya movido la pieza o en su estado inicial. Por lo tanto, se suguieren dos
alternativas: incrementar el avance de la cinta y luego retroceder o cambiar el valor negativo por uno mucho
menor (en términos absolutos). La Figura 77 muestra el Serial y la Figura 78 muestra la salida en RobotStudio.
La Figura 79 muestra el valor enviado.
69
Figura 80: Funciones enviadas para ejemplo ilustrativo
En Arduino se presentan las líneas en la siguiente salida de pantalla del Serial; y corresponde a las funciones
mostradas en la Figura 81. La línea 8 muestra que el comando absoluto 5 se realizó correctamente; la línea 9
muestra que el comando leer se completó; La línea 19 muestra que el comando relativo 4- 3 se completó
también. La líne 22 corresponde con el absoluto -8 y la línea 25 con la de que el comando absoluto 10 se realizó
correctamente. El valor final en la línea 25 correspondiente al valor de 20, que realizando las operaciones
correspondientes a cada movimiento: 5+3*4-8+10 dan como resultado un valor de 19 (que para Arduino serían
20 por el map antes mencionado). Lo que corrobora con éxito que las funciones y los valores enviados se
cumplen a cabalidad y que por lo tanto el sistema cumple con los requisitos establecidos.
70
Figura 82: Estado en reposo del robot
71
Figura 84: Robot después de recibir información de la función absoluto 10
Estos resultados, en forma de video se añaden como Anexos, en modo de demostración y verificación del trabajo
realizado.
8 CONCLUSIONES
T
ras lo conseguido en el tabajo se pueden obtener varias conclusiones.
Pero antes de mencionar estas conclusiones quisiera hacer incapíe en que, para realizar este trabajo, a parte
de los conocimientos previos de mecatrónica que se tiene, es esencial aprender y desarrollar nuevas formas
de ver el mundo y en especial adquirir nuevos conocimientos basados en protocolos como el TCP/IP o el
lenguaje RAPID para RobotStudio, entre otras muchas cosas.
Resulta bastante interesante el desarrollo de este proyecto ya que permite controlar, de forma remota,
la operación en la cinta, sin la necesidad de estar en el lugar.
Otro aspecto importante, es que, antes no se habían hecho proyectos parecidos y tratar de conectar de
alguna forma a RobotStudio o los Robots ABB (en especial el IRB120) de forma remota con Arduino,
es sumamente difícil; por lo que prácticamente este es un trabajo pionero y que permitirá a los
estudiantes e investigadores adquirir mayor destreza en el manejo de RobotStudio y Arduino.
Al estar ya conectado con Arduino, no sería necesario utilizar entradas o salidas físicas del robot para
cumplir una tarea; bastaría con modificar el protocolo y expandir el buffer de comunicaciones para
ingresar toda la información relevante que se le quiera pasar al IRB120 y hacerlo por medio del
protocolo TCP/IP. Lo cuál expande la funcionalidad tanto de RobotStudio, como de Arduino. Las
posibilidades son enormes.
Uno de los puntos a destacar más importantes es que Arduino no goza de una estabilidad en cuanto a
rendimiento y protocolos de comunicación, pero aún así el programa desarrollado es bastante efectivo
72
y eficaz. Se recomienda intentar con otro tipo de alternativas.
Otra conclusión, quizá menos importante, es que no se puede crear un servidor en RobotStudio para
enlazar dispositivos fuera del LocalHost; lo cuál se solucionaría portándolo de RobotStudio a la
controladora real del robot. Sin embargo, si el dispositivo que se quiere conectar como cliente hacia
RobotStudio esta en la misma maquina ([Link]) no hay problema; como se ha visto en otros trabajos
de master y de grado.
Todo esto en lo que concierne al trabajo desarrollado.
9 BIBLIOGRAFÍA
[7 Á. C. Sánchez, Diseño de una estación virtual e implantación en sistema real de un robot IRB120, Sevilla:
] Universidad de Sevilla, 2018.
10 ANEXO
10.1 Anexo A: Arduino
En la carpeta “tcp_ip_1” adjunta en el disco del proyecto se encuentran las carpetas con ficheros “.ino”
correspondientes.
“tcp_ip_1” corresponde al apartado 4.8 del documento.
“tcp_ip_2” corresponde al apartado 4.9 del documento.
“tcp_ip_3” corresponde al apartado 4.10 del documento.
74
nombre “estacion_comunicacion.rspag”; este es el archivo mas importante ya que permite abrir la
estación y todos sus componentes y librerias sin la necesidad de añadir nada mas. La versión final se
abrirá al ejecutar este archivo. Archivo>>Compartir>>Unpack and Work
En la carpeta “robot_estudio” se encuentra la carpeta “Archivos Rapid Para Pruebas”, con los
siguientes archivos:
o “Comunicacion_prueba1.txt”, que deberá ser abierta y copiada en la sección de rapid de la
estación y corresponde a la sección 5.1 de este trabajo
o “[Link]”, que al igual que la anterior deberá ser abierta y pegada en la
sección de Rapid de RobotStudio y corresponde a la sección 5.2 de este trabajo
o “comunicacionprueba_robotstudio.txt” y “[Link]” pueden ser útiles para futuros
trabajos
En la carpeta “robot_estudio” se encuentra la carpeta “StationBackups”, que son estaciones Backups
que RobotStudio va creando a lo largo del trabajo.
75
10.5 Anexo C: Especificaciones IRB120
76
10.6 Anexo D: Vínculos RobotStudio
Curso de RobotStudio en Youtube
[Link]
MdqZU&list=PL7fQXFqChkTe0snNKx67OHyaZxYfdlRBz
Curso de RobotStudio en Youtube
[Link]
Página principal ABB
[Link]
Foro ABB
[Link]
Página desarrolladores ABB
[Link]
77