PROYECTO DE GRADO Presentado ante la ilustre UNIVERSIDAD DE LOS ANDES como requisito final para obtener el Título de INGENIERO DE SISTEMAS DISEÑO E IMPLEMENTACIÓN DE UNA INTERFAZ (SOFTWARE, HARDWARE) ENTRE UN SIMULADOR Y UN BRAZO ROBÓTICO, USANDO UN MICROCONTROLADOR. Por Br. Yuliany Quintero Tutor: Dr. Iñaki Aguirre Noviembre 2008 ©2008 Universidad de Los Andes Mérida, Venezuela Diseño e Implementación de una Interfaz (Software, Hardware) entre un simulador y un brazo robótico, usando un microcontrolador. Br. Yuliany Quintero Proyecto de Grado — Control y Automatización, 91 páginas Resumen: En este trabajo se presenta la información relacionada con el diseño e implementación de una interfaz (software, hardware). La tarjeta de interfaz permite conectar un brazo robótico con un simulador usando un microcontrolador. La información requerida por el microcontrolador para ejercer el control en los actuadores del brazo robótico, es trasmitida por el computador (simulador) por vía puerto serial. Cuando se desea diseñar una interfaz de este tipo se deben tomar en cuenta varios factores, tales como: elementos motores o actuadores, sensores disponibles, amplificadores de potencia, método para la asignación de tareas, programación, etc., estos aspectos son considerados cuidadosamente para lograr el fin perseguido. Palabras clave: sistema de comunicación, brazo robótico, actuadores, sensores, microcontrolador, interfaz. Índice Índice…… .............................................................................. iii Índice de Tablas ......................................................................... v Índice de Figuras ........................................................................vi Capítulo 1 Introducción ............................................................... 8 1.1 Antecedentes ................................................................................ 8 1.2 Planteamiento del Problema.............................................................. 9 1.3 Delimitación del Problema ..............................................................10 1.4 Objetivos....................................................................................11 1.4.1 Objetivo General .....................................................................11 1.4.2 Objetivos Específicos ................................................................11 1.5 Metodología ................................................................................11 Capítulo 2 Marco Teórico ............................................................ 13 2.3 Brazo Robótico o Manipulador y su Cinemática .....................................13 2.4 Elementos Motrices o Actuadores ......................................................16 2.4.1 Motores de Corriente Continua (CC) ............................................16 2.4.2 Motor de Lego NXT.................................................................18 2.5 Sensor de Posición.........................................................................19 2.5.1 Encoder Óptico Incremental .......................................................19 2.6 Sistema de Comunicación de Datos ....................................................20 2.6.1 Transmisión y Recepción Serial ...................................................21 2.7 Microcontrolador..........................................................................23 2.7.1 Estructura Básica de un Microcontrolador .......................................24 2.7.2 Familias de Microcontroladores ...................................................27 iii 2.7.3 Microcontroladores de la Microchip ..............................................28 Capítulo 3 Diseño e Implementación............................................... 32 3.1 Simulador – Procesador ..................................................................32 3.2 Procesador – Brazo Robótico ...........................................................37 3.3 Programación del PIC16F877 ...........................................................44 3.4 Construcción del circuito impreso para la Interfaz ..................................57 3.5 Resultados ..................................................................................59 Capítulo 4 Conclusiones y Recomendaciones ..................................... 64 4.1 Conclusiones ...............................................................................64 4.2 Recomendaciones .........................................................................65 Bibliografía ……………………………………………………………66 Anexo A………………………………………………………………68 Anexo B………………………………………………………………79 Anexo C……………… ............................................................. 86 iv Índice de Tablas Tabla 1: Características del Motor Lego NXT. .................................................18 Tabla 2: Microcontroladores más comunes. .....................................................27 Tabla 3: Comportamiento de un Motor LEGO NXT según el L293B. .....................41 Tabla 4: Recursos utilizados por el PIC16F877. ................................................45 Tabla 5: Relación pulsos vs grados, sentido horario articulación 1. .........................47 Tabla 6: Relación pulsos vs grados, sentido antihorario articulación 1. ....................47 Tabla 7: Relación pulsos vs grados, sentido horario articulación 3. .........................50 Tabla 8: Relación pulsos vs grados, sentido antihorario articulación 3. ....................50 Tabla 9: Relación pulsos vs grados, sentido horario articulación 2. .........................53 Tabla 10: Relación pulsos vs grados, sentido antihorario articulación 2. ...................53 Tabla 11. Resultados de la Articulación 1 (Horario). ..........................................60 Tabla 12. Resultados de la Articulación 2 (Antihorario). .....................................61 Tabla 13. Resultados para la Articulación 3 (Antihorario). ...................................61 v Índice de Figuras Figura 1: Diagrama de acoplamiento............................................................... 9 Figura 2: Esquema de funcionamiento ............................................................. 9 Figura 3: Brazo Robótico. ..........................................................................13 Figura 4: Motor CC con juego de engranajes reductores. ....................................17 Figura 5: Variación de la Velocidad de un Motor CC controlado por PWM. .............17 Figura 6: Motor Lego NXT.........................................................................18 Figura 7: Encoder Óptico Incremental. ..........................................................20 Figura 8: Conector DB9. ...........................................................................23 Figura 9: Estructura de un microcontrolador. ..................................................23 Figura 10: Arquitecturas de un Microcontrolador..............................................27 Figura 11: Estructura interna de un PIC. ........................................................29 Figura 12: Plataforma de Desarrollo Integrada MPLAB. ......................................30 Figura 13: Plataforma de Desarrollo PCW. .....................................................31 Figura 14: Herramienta Computacional (Arismendi, 2008). .................................33 Figura 15: Panel de Pasos del Simulador. ........................................................33 Figura 16: Diagrama de Flujo 1. ...................................................................34 Figura 17: Diagrama de Flujo 2. ...................................................................35 Figura 18: PIC 16F877. .............................................................................36 Figura 19: MAX232. ................................................................................36 Figura 20: Esquema electrónico Simulador - Procesador. ....................................37 Figura 21: Identificación de las articulaciones. ..................................................37 Figura 22: Articulaciones 1 y 3 con los motores LEGO NXT. ...............................38 Figura 23: Articulación 3 con los dos motores LEGO NXT. .................................38 Figura 24: Encoder óptico incorporado en el motor LEGO NXT. ..........................39 Figura 25: Conector del motor LEGO NXT. ...................................................40 Figura 26: Conector RJ11 sin pestaña. ...........................................................40 Figura 27: Driver L293B. ...........................................................................41 Figura 28: Esquema electrónico Procesador - Brazo Robótico. ..............................42 Figura 29: Esquema electrónico de la Interfaz. .................................................43 Figura 30: Sistema de control para las articulaciones. .........................................44 Figura 31: Velocidad del 60% para la articulación 1. ..........................................46 Figura 32: Gráficas correspondiente a las tablas 5 y 6. ........................................49 Figura 33: Gráficas grados vs pulsos de las tablas 7 y 8. .......................................51 Figura 34: Variaciones de la velocidad. ...........................................................52 Figura 35: Gráficas grados vs pulsos de las tablas 9 y 10.......................................54 Figura 36: Montaje de la interfaz para realizar mediciones en los motores. ...............55 Figura 37: Software y Hardware para la programación del PIC. .............................56 Figura 38: Esquema electrónico en Protues. ....................................................57 Figura 39: Circuito impreso de la Interfaz. ......................................................58 Figura 40: Circuito impreso de la Interfaz en 3D. ..............................................59 Figura 41: Prueba 1. .................................................................................62 Figura 42: Prueba 2. .................................................................................63 vii Capítulo 1 Introducción 1.1 Antecedentes Cuando se tiene un robot, para que su funcionamiento sea el adecuado, se tienen que fusionar sistemas mecánicos y electrónicos, es decir, se integran componentes de Hardware como sensores, actuadores y microcomputadoras en el proceso mecánico, además del procesamiento de la información Software. En el caso del Software, esta integración se basa principalmente en funciones de control por retroalimentación, donde se tiene conocimiento del proceso y del correspondiente tratamiento de la información (mediciones), dando como resultado algoritmos en tiempo real que deben adaptarse a las propiedades mecánicas del proceso (Bishop, 2002). A esta visión de integración de manera óptima de Software y Hardware, además de una integración entre las diversas disciplinas de ingeniería, así como la integración entre el diseño y la construcción, se le conoce como mecatrónica (University, 2008). En la Universidad de los Andes actualmente se vienen realizando estudios de investigación en el área de Robótica. En particular, es importante mencionar el trabajo realizado por (Arismendi, 2008), quien desarrolló una herramienta computacional para la simulación y programación de un manipulador robótico de tres grados de libertad, así como la tesis de maestría que realizó (Andueza, 2008), donde diseñó un manipulador robótico con tres grados de libertad con fines educativos. Ambos trabajos bajo la supervisión del Dr. Iñaki Aguirre. 9 1.2 Planteamiento del Problema Siguiendo la línea de investigación mencionada anteriormente, se propone unir los dos trabajos anteriores (Arismendi, 2008) y (Andueza, 2008). Para ello, se desarrollará una interfaz (de software y hardware) la cual permitirá acoplarlos, véase Figura 1. Interfaz Simulador (Arismendi, 2008) Software Interfaz Brazo Robótico (Andueza, 2008) Hardware Figura 1: Diagrama de acoplamiento La interfaz que se diseñará e implementará seguirá el esquema de funcionamiento mostrado en la Figura 2. Figura 2: Esquema de funcionamiento Este esquema es similar al empleado en la actualidad durante el proceso de diseño de prototipos para Digital Signal Processors (DSP). Este esquema nos permitirá dividir el problema planteado en dos perspectivas: 10 • Interfaz Simulador – Microcontrolador Desde el punto de vista de software se programará un módulo en el simulador para enviar información (datos) al microcontrolador y, a su vez, monitorear las variables del proceso. Desde el punto de vista de hardware, se diseñarán los circuitos electrónicos que permitan el acondicionamiento de señal, desde el computador (usando comunicación serial) al microcontrolador y viceversa. • Interfaz Microcontrolador – Sistema Electromecánico Desde el punto de vista de software se programarán tres módulos dentro del microcontrolador, el primero que permita enviar y recibir información del simulador, el segundo procesar las señales de los sensores y obtener información para, en tercer lugar generar las acciones de control de los actuadores. Desde el punto de vista de hardware, se manipularán los actuadores y sensores del brazo robótico, así como los circuitos electrónicos auxiliares para generar potencia a los actuadores, ya que el microcontrolador no genera la potencia necesaria, (de hecho, ambas formas de alimentación deben aislarse para evitar sobrecargas que puedan dañar el microcontrolador). 1.3 Delimitación del Problema Este trabajo está dirigido al diseño e implementación de una tarjeta electrónica basada en un microcontrolador, que será utilizada como interfaz entre el Simulador (Arismendi, 2008) y el Brazo Robótico de (Andueza, 2008), permitiendo con esto, seguir la línea de investigación en el área de Robótica que viene realizando el Dr. Iñaki Aguirre. Además, estos trabajos con fines educativos servirán como herramientas en la enseñanza y aprendizaje de algunos cursos de Ingeniería de Sistemas de la Universidad de Los Andes. 11 1.4 Objetivos 1.4.1 Objetivo General Diseñar e implementar una interfaz entre un simulador y un brazo robótico, usando un microcontrolador. 1.4.2 Objetivos Específicos • Determinar un sistema de comunicación entre el brazo robótico y el simulador. • Construir una tarjeta de interfaz, tanto para recibir información del simulador como del brazo robótico. • Construir un circuito electrónico para controlar los actuadores que se utilizarán en las articulaciones del brazo robótico. • Manipular las señales emitidas por los sensores, para poder controlar la posición de cada eslabón del brazo robótico. • Analizar el código del simulador y su estructura de dato, para el posicionamiento del brazo robótico. • Crear un nuevo módulo de programación en el simulador que permita enviar y recibir información referente al posicionamiento del brazo robótico. 1.5 Metodología Para la realización de este trabajo se va a requerir: • Recopilar información para el desarrollo del proyecto; como la interfaz a utilizar, los actuadores y sensores que serían convenientes para el brazo robótico, y la selección del microprocesador. 12 • Analizar una interfaz tanto de software como de hardware que permita comunicar el simulador con el brazo robótico. • Acondicionar tanto las señales emitidas por los sensores, como las señales que van a los actuadores. • Estudiar y analizar el simulador de (Arismendi, 2008), para luego proceder a programar un módulo que permita enviar y recibir información del brazo robótico. Capítulo 2 Marco Teórico 2.3 Brazo Robótico o Manipulador y su Cinemática El brazo robótico o manipulador es el conjunto de elementos mecánicos, formado por una serie de eslabones, unidos mediante articulaciones, que son las que dan la libertad de movimiento al conjunto de piezas, por lo tanto cada articulación constituye un grado de libertad para el brazo (Iñigo Madrigal & Vidal Idiarte, 2002). Véase Figura 3. Figura 3: Brazo Robótico. Los manipuladores se pueden clasificar según el número de articulaciones o movimientos que estos sean capaces de realizar, de esta manera tenemos de: • 3 grados de libertad • 4 grados de libertad • 5 grados de libertad • 6 grados de libertad 14 Entre más articulaciones posea el brazo mayor maniobrabilidad, lo que implica dificultad para su control debido a los requisitos de software para controlarlo, obteniéndose a su vez menor precisión por acumulación de errores. Conocidos los grados de libertad del manipulador es necesario establecer un procedimiento que permita conocer la posición de cada uno de los eslabones en cualquier momento con respecto a un sistema de referencia fijo. La encargada de realizar este estudio es la cinemática del robot. Así, la cinemática (Craig, 2006) se interesa por la descripción analítica del movimiento espacial del robot como una función del tiempo, y en particular por las relaciones entre la posición y la orientación del extremo final del robot con los valores que toman sus coordenadas articulares. Existen dos problemas fundamentales para resolver la cinemática del robot, el primero de ellos se conoce como el problema de cinemática directa, y consiste en determinar cuál es la posición y orientación del extremo final del robot, con respecto a un sistema de coordenadas que se toma como referencia, y el segundo denominado problema de cinemática inversa resuelve la configuración que debe adoptar el robot para una posición y orientación del extremo conocida. Denavit y Hartenberg en 1955, (Craig, 2006) propusieron un método sistemático para descubrir y representar la geometría espacial de los elementos de una cadena cinemática, y en particular de un robot, con respecto a un sistema de referencia fijo. Este método utiliza una matriz de transformación homogénea para descubrir la relación espacial entre dos elementos rígidos adyacentes, reduciéndose el problema cinemático directo a encontrar una matriz de transformación homogénea 4x4 que relacione la localización espacial del robot con respecto al sistema de coordenadas de su base. 15 Según la representación de Denavit-Hartenberg, escogiendo adecuadamente los sistemas de coordenadas asociados para cada eslabón, será posible pasar de uno al siguiente, mediante 4 transformaciones básicas que dependen exclusivamente de las características geométricas del eslabón. Estas transformaciones básicas consisten en una sucesión de rotaciones y traslaciones que permiten relacionar el sistema de referencia del elemento i con el sistema del elemento i-1. Las transformaciones en cuestión son las siguientes: • Rotación alrededor del eje Zi−1 un ángulo . • Traslación a lo largo de Zi−1 una distancia di; vector di(0,0,di). • Traslación a lo largo de Xi una distancia ai; vector ai(0,0,ai). • Rotación alrededor del eje Xi un ángulo . Donde: • es el ángulo que forman los ejes Xi−1 y Xi medido en un plano perpendicular al eje Zi−1, utilizando la regla de la mano derecha. • di es la distancia a lo largo del eje Zi−1 desde el origen del sistema de coordenadas (i-1)- ésimo hasta la intersección del eje Zi−1 con el eje Xi. • ai es la distancia a lo largo del eje Xi que va desde la intersección del eje Zi−1con el eje Xi hasta el origen del sistema i-ésimo. • es el ángulo de separación del eje Zi−1 y el eje Zi, medido en un plano perpendicular al eje Xi, utilizando la regla de la mano derecha. Una vez obtenidos los parámetros de Denavit – Hartenberg se procede a calcular las matrices de transformación homogénea para cada uno de los sistemas coordenados, siguiendo la ecuación que se muestra a continuación: 16 cos 0 0 cos sin cos cos sin 0 sin sin sin cos 0 1 Si bien es cierto que en el caso de la cinemática directa la solución se puede conseguir de manera sistemática, en el caso de la cinemática inversa no se puede realizar así. La solución de la cinemática inversa depende mucho de la configuración del robot, y para muchos casos (posiciones y orientaciones) no existe una solución única o simplemente no existe solución. Una forma de resolver este problema es utilizando el denominado desacople cinemático, que consiste en dividir el problema en posicionamiento y orientación del manipulador; resolviendo cada una de manera independiente y con algún método que resulte más fácil. 2.4 Elementos Motrices o Actuadores Los actuadores generan las fuerzas o pares necesarios para animar la estructura mecánica. Se utilizan tecnologías hidráulicas y neumáticas, para desarrollar potencias importantes, pero en la actualidad se han extendido el empleo de motores eléctricos, y en particular motores de corriente continua servocontrolados, empleándose en algunos casos motores paso a paso y otros actuadores electromecánicos. 2.4.1 Motores de Corriente Continua (CC) Este tipo de motores (Angulo, Romero, & Angulo, 2005) son muy habituales en aplicaciones de baja potencia. En los robots se emplea tanto para el movimiento como para tareas variadas como abrir y cerrar pinzas, poleas, uso de herramientas, etc. Permite una regulación de la velocidad y sentido de giro muy sencillo, sin más que modificar el valor y polaridad de la tensión de alimentación. Normalmente poseen engranajes 17 reductores, bien externos o internos, lo que hará que el movimiento de rotación del eje sea más lento pero con un par de fuerza adecuado. Véase Figura 4. Figura 4: Motor CC con juego de engranajes reductores. Para regular la velocidad de giro de un motor de corriente continua se utiliza la técnica de Pulse Width Modulator (PWM), que consiste en generar trenes de pulsos dentro de un rango dado, por ejemplo entre 0 y 5 V, que son valores muy comunes en el trabajo con circuitos integrados. Véase Figura 5. Figura 5: Variación de la Velocidad de un Motor CC controlado por PWM. 18 2.4.2 Motor de Lego NXT Estos motores son de corriente continua e imán permanente, el control de velocidad de ellos se hace mediante la técnica de Pulse Width Modulator (PWM). También cuentan con protección interna contra sobrecargas (termistores) y contra sobretensiones. Esto implica que no siempre es posible sostener velocidades máximas por tiempo indefinido, (The LEGO Group, 2006). Véase Figura 6. Figura 6: Motor Lego NXT. Las características mecánicas y eléctricas de los motores Lego NXT se resumen en la Tabla 1: Motor Lego NXT (12V) Peso (gr) 80 Velocidad Libre (rpm) 170 Consumo Libre (mA) 60 Consumo Frenado (mA) 2000 Torque (N.cm) 16.7 Potencia Eléctrica (w) 6.96 Potencia Mecánica (w) 3.10 Eficiencia (%) 44,5 Tren de engranajes de reducción. si Tabla 1: Características del Motor Lego NXT. 19 2.5 Sensor de Posición Un sensor no es más que un dispositivo diseñado para recibir información de una magnitud física percibida del exterior transformándola a otra magnitud, normalmente eléctrica, permitiendo cuantificarla y manipularla. En el control del movimiento de las articulaciones de un brazo robótico, al igual que en cualquier sistema de control de posición con realimentación, se requiere el uso de sensores de posición acoplados al eje del motor o actuador que acciona cada articulación. El dispositivo más sencillo y a la vez poco exacto y práctico es el potenciómetro rotatorio; sus mayores desventajas son la falta de continuidad, debido a esto, es muy poco usado. El sensor encoder óptico o conocido como codificador de disco es el más usado para medir la posición angular en las articulaciones de los manipuladores, existe dos tipos el absoluto y el incremental. Tanto los encoders absolutos como los incrementales pueden presentar problemas debido a la gran precisión que es necesaria en el proceso de fabricación de los brazos robóticos. Además son dispositivos especialmente sensibles a golpes y vibraciones, (Alicante, 2001). 2.5.1 Encoder Óptico Incremental Básicamente este sensor de posición requiere un par de emisor/receptor, que se basan en un diodo fotoemisor y en un transistor fotoreceptor, que detectan la presencia o ausencia de luz a través de un disco transparente el cual tiene una serie de ranuras en forma equidistante y radialmente entre sí. Véase Figura 7. 20 Figura 7: Encoder Óptico Incremental. El funcionamiento de este sensor es el siguiente: cuando el sistema empieza a funcionar el diodo fotoemisor empieza a emitir un haz de luz, a medida que el eje donde se ha fijado el disco con ranuras, vaya girando, se producirán una serie de pulsos en el fotoreceptor correspondiente a la luz que atraviesa la ranuras del disco, llevando una cuenta de esos pulsos es posible conocer la posición angular del eje. 2.6 Sistema de Comunicación de Datos La comunicación de datos trata de la transferencia de información entre dos puntos cualesquiera, utilizando dispositivos que permitan dicha transferencia y el tratamiento por computadora de la información. Para comunicar sistemas de tratamiento de información se necesitan dispositivos que permitan la interacción entre ellos. En la actualidad existen diversas formas para realizar la comunicación, entre ellas se tienen la trasmisión de datos en paralelo, en serial, en usb, etc. En la comunicación entre el terminal y un computador, la información trasmitida son códigos asociados a los caracteres del teclado y de la unidad de presentación de la información de dicho terminal. Habitualmente en dicha comunicación se utiliza el código American Standar Code of Information Interchange (ASCII). Normalmente, los siete bits del 21 código van acompañados de un octavo bit utilizado para controlar la paridad del conjunto. El conjunto de los siete bits mas el bit suplementario forma un total de ocho bits (byte), que constituyen realmente la unidad de información transmitida, y suele denominarse caracter. 2.6.1 Transmisión y Recepción Serial En la transmisión y recepción serial, el medio de comunicación consiste en tres hilos; un primer hilo para transmitir el dato, un segundo para la recepción del dato y el otro que actúa como una señal de tierra. Debido a que la transmisión es asincrónica, es posible enviar datos por una línea mientras se reciben datos por otra. Existen dos técnicas importantes para trasmitir y recibir datos binarios. Una técnica es variar la corriente (lazo de corriente de 20mA) y la otra es variar el voltaje (red standar RS-232 de la EIA (Electronics Industry Association)). La técnica de variación de voltaje comunica los datos binarios por inversión de polaridad del voltaje sobre la línea serial. El transmisor envía un voltaje positivo (12 V) para comunicar el bit “0” y un voltaje negativo (-12 V) para comunicar el bit “1”. Los sistemas implementados con esta técnica son más susceptibles al ruido. Las características más importantes de la comunicación serial son la velocidad de transmisión, los bits de datos, los bits de parada, y la paridad. Para que dos puertos se puedan comunicar, es necesario que las características sean iguales, (Instruments, 2006). a. Velocidad de transmisión: Indica el número de bits por segundo que se transfieren, y se mide en baudios (bauds). Las velocidades de transmisión más comunes son de 2400 y 9600. Es posible tener velocidades más altas, pero se 22 reduciría la distancia máxima posible entre los dispositivos. Las altas velocidades se utilizan cuando los dispositivos se encuentran uno junto al otro. b. Bits de datos: Se refiere a la cantidad de bits en la transmisión. Cuando la computadora envía un paquete de información, el tamaño de ese paquete no necesariamente será de 8 bits. Las cantidades más comunes de bits por paquete son 5, 7 y 8 bits. c. Bits de parada: Usado para indicar el fin de la comunicación de un solo paquete. Los valores típicos son 1, 1.5 o 2 bits. Debido a la manera como se transfiere la información a través de las líneas de comunicación y que cada dispositivo tiene su propio reloj, es posible que los dos dispositivos no estén sincronizados. Por lo tanto, los bits de parada no sólo indican el fin de la transmisión sino además dan un margen de tolerancia para esa diferencia de los relojes. d. Paridad: Es una forma sencilla de verificar si hay errores en la transmisión serial. Existen cuatro tipos de paridad: par, impar, marcada y espaciada. La opción de no usar paridad alguna también está disponible. Para paridad par e impar, el puerto serial fijará el bit de paridad (el último bit después de los bits de datos) a un valor para asegurarse que la transmisión tenga un número par o impar de bits en estado alto lógico. La paridad marcada y espaciada en realidad no verifican el estado de los bits de datos; simplemente fija el bit de paridad en estado lógico alto para la marcada, y en estado lógico bajo para la espaciada. Lo más importante de este estándar de comunicaciones es la función específica de cada hilo de entrada y salida de datos porque nos encontramos básicamente con dos tipos de conectores los de 25 pines (DB25) y los de 9 pines (DB9), es probable que se encuentre más la versión de 9 pines. Véase Figura 8. 23 Figura 8: Conector DB9. 2.7 Microcontrolador Un microcontrolador es un circuito integrado o chip que incluye en su interior las tres unidades funcionales de una computadora: Procesador, Memoria y Unidades de E/S, es decir, se trata de un computador completo en un solo circuito integrado (Microcontrolador, 2008). Véase Figura 9. Figura 9: Estructura de un microcontrolador. 24 Los microcontroladores son diseñados para aplicación de control de máquinas, más que para interactuar con humanos, ya que no incluye ningún dispositivo de comunicación que permita interactuar con los humanos, como teclado, monitor, mouse, a diferencia de un computador. 2.7.1 Estructura Básica de un Microcontrolador a. Procesador: es el elemento más importante y determina sus principales características, tanto de software como de hardware. Se encarga de direccionar la memoria de instrucciones, de la decodificación y ejecución de la operación relacionada con la instrucción, así como de buscar los operadores relacionado con la instrucción y almacenar el resultado de la operación en la memoria. Existen dos arquitecturas en los procesadores: la Complex Instruction Set Computer (CISC), está posee un conjunto de instrucciones amplio que permiten realizar operaciones complejas entre operando situados en la memoria. Y la Reduced Instruction Set Computer (RISC) que se centra en tener instrucciones de tamaño fijo, pocas instrucciones y de reducir el acceso a la memoria. b. Memoria: la memoria no es abundante, normalmente, la memoria de instrucciones no excederá los 16 kilobytes de localidades de memoria no volátil Read Only Memory (ROM) y la memoria volátil Random Access Memory (RAM) que se utiliza para almacenar datos y variables ni siquiera llegará a exceder los 5 kilobytes. En el caso de la memoria ROM se utilizan diferentes tecnologías: • ROM de máscara, en este caso no se graba el programa en la memoria sino que el microcontrolador se fabrica con el programa. 25 • One Time Programmable (OTP), es una memoria de sólo lectura programable una sola vez por el usuario. • Erasable Programmable Read OnIy Memory (EPROM), este tipo de tecnología permite borrar y grabar muchas veces la memoria, pero para poder borrarla hay que someterla a rayos ultravioleta durante varios minutos. • Electrical Erasable Programmable Read OnIy Memory (EEPROM), se trata de memorias de sólo lectura, programables y borrables eléctricamente, desde el propio grabador y bajo el control programado de un computador. • FLASH, se trata de una memoria no volátil, de bajo consumo, que se puede escribir y borrar con un circuito electrónico al igual que las EEPROM, pero que suele tener mayor capacidad que estas últimas. c. Periféricos: los microcontroladores disponen de una gran variedad de dispositivos de entrada y salida, algunos de ellos se verán a continuación: • Entrada/Salidas de propósito general, generalmente agrupados en puertos de 8 bits de longitud, permiten leer datos del exterior o simplemente escribir en ellos desde el interior del microcontrolador. • Temporizadores y Contadores, son circuitos que permiten contar pulsos que llegan a su entrada de reloj. Si la fuente de conteo es el oscilador interno del microcontrolador es común que no tengan un pin asociado, y en este caso trabajan como temporizadores. Por otra parte, cuando la fuente de conteo es externa, entonces tienen asociado un pin configurado como entrada, este es el modo contador. • Conversor A/D, como es muy frecuente el trabajo con señales analógicas, éstas deben ser convertidas a digital y es por ello que muchos microcontroladores incorporan este tipo de periférico. Las resoluciones más frecuentes son de 8 y 10 bits. 26 • Puerto Serie, este tipo de periférico está presente en casi todo los microcontroladores, permitiendo la comunicación con otro microcontrolador o con una computadora, normalmente de la forma Universal Asynchronous Receiver Transmitter (UART), si se permite la comunicación síncrona se consigue la forma Universal Synchronous Asynchronous Receiver Transmitter (USART). • Puerto Serie Síncrono, este tipo de periférico se utiliza para comunicar al microcontrolador con otros microcontroladores o con periféricos externos (LCD, memorias, etc.) conectados a él, mediante las interfaces Serial Peripheral Interface (SPI) o Inter-Integrated Circuit (I2C). • Comparadores, son circuitos analógicos basados en amplificadores operacionales que tienen la característica de comparar dos señales analógicas y dar como salida los niveles lógicos ‘0’ o ‘1’ en función del resultado de la comparación. • Modulador de ancho de pulsos, son periféricos capaces de generar señales del tipo Pulse Width Modulator (PWM), muy útiles sobre todo para el control de motores. d. Arquitectura: básicamente existen dos, la Von Neumann y la Harvard, ambas se diferencian en la forma que están conectados la memoria con el procesador y en el bus que cada uno utiliza. En la Von Neumann, existe una sola memoria donde se almacenan las instrucciones y los datos, accediéndose mediante buses de dirección, datos y control. En cambio la arquitectura Harvard tiene dos memorias independientes, una para instrucciones y otra para datos, con sus tres respectivos buses: dirección, datos y control. Véase Figura 10. (Orduña Huertas & Arnau Llombart, 1996). 27 Figura 10: Arquitecturas de un Microcontrolador. 2.7.2 Familias de Microcontroladores Existe una gran diversidad de microcontroladores en el mercado, algunos de estos se pueden citar en la Tabla 2. Tabla 2: Microcontroladores más comunes. Fabricante Atmel AVR Freescale Hitachi, Ltd Holtek Intel 8 bits ATmega8 68HC05 68HC08 68HC11 HCS08 H8 HT8 MCS-48 8048 MCS51 16 bits 32 bits 68HC12 68HCS12 68HCSX12 68HC16 683xx MCS96 MXS296 28 Silabs Microchip NEC ST Texas Instruments Zilog National Semiconductor 8051 8xC251 C8051 10f2xx 12Cxx 12Fxx 16Cxx 16Fxxx 18Cxx 18Fxx 78K ST 62 ST 7 TMS370 MSP430 Z8 Z86E02 COP8 dsPIC30FXX dsPIC33F PIC32 En cuanto a la técnica de fabricación en su totalidad los microcontroladores se fabrican bajo la tecnología Complementary Metal Oxide Semiconductor (CMOS). 2.7.3 Microcontroladores de la Microchip La familia de los Microcontroladores fabricados por la Microchip Tecnology Inc. son conocidos como Peripheral Interface Controller (PIC). Estos Microcontroladores usan un juego de instrucciones tipo RISC, con una arquitectura tipo Harvard, lo que hace difícil comparar el tamaño del código del PIC con el de otros microcontroladores. Los PICs generalmente incorporan características de hardware tales como: • Procesadores de 8 y 16 bits. • Memoria EEPROM, ROM y FLASH disponible desde 256 bytes a 256 kilobytes. 29 • Puertos de entrada y salida, con rangos de 0 Voltios a 5 Voltios. • Temporizadores de 8 y 16 bits. • Periféricos serie síncronos y asíncronos USART, UART. • Conversores análogos de 8 y 10 bits. • Comparadores de tensión. • Módulos de captura y generación de señales PWM. • Osciladores que permiten variar el rango de frecuencia con el que los PICs trabajan, por lo general usa un cristal de cuarzo para poder lograr frecuencias bajas (200khz), medias (4Mhz) y altas (20Mhz). En la Figura 11 se puede observar la estructura de un microcontrolador PIC, en este caso de la familia 16F87X, (Angulo, Romero, & Angulo, 2006). Figura 11: Estructura interna de un PIC. 30 Para la programación de los PICs se utiliza el lenguaje de bajo nivel (de máquina), ya que representan un considerable ahorro de código, lo que es muy importante dada la limitación de la memoria de instrucciones. La Microchip proporciona una Plataforma de Desarrollo Integrada, versión libre bajo Windows llamado MPLAB, que permite escribir los programas para los PICs en lenguaje ensamblador. Véase Figura 12. Figura 12: Plataforma de Desarrollo Integrada MPLAB. Al igual existen Plataformas de Desarrollo Integrada para la programación de los PICs basados en lenguajes de alto nivel como es el caso del compilador de C PCW de la empresa CCS, comercializados por Mircosystems Engineering. El cual permite escribir programas basados en el lenguaje C en vez de ensamblador, con lo cual se logra un menor tiempo de desarrollo y facilidad en la programación. Este entorno de desarrollo genera, al ser compilado, ficheros con extensiones .hex que contiene el código máquina del programa, así como .lst donde se encuentra el ensamblador. Véase Figura 13. 31 Figura 13: Plataforma de Desarrollo PCW. Capítulo 3 Diseño e Implementación Una interfaz de control es un dispositivo de enlace entre un puerto de salida de un computador y los componentes eléctricos o electrónicos de un sistema. Es por esto que se diseñará una interfaz (software, hardware) que permita la interacción entre el simulador (Arismendi, 2008) y el brazo robótico (Andueza, 2008). Para el diseño de la interfaz se seguirá el esquema planteado en la Figura 2 (página 8). El cual permitirá dividirlo en dos módulos: Simulador – Procesador, y Procesador – Brazo Robótico. 3.1 Simulador – Procesador Los Simuladores robóticos son herramientas computacionales capaces, como su nombre lo indican, de simular los movimientos y tareas que realizarán los robots, así como que tenga la opción para su programación. En cuanto al simulador a ser utilizado por la interfaz, será el desarrollado por (Arismendi, 2008), ya que es una herramienta multiplataforma, es decir, puede correr en cualquier sistema operativo (Windows, Linux, MacOS, etc.), su programación está basado en el lenguaje de Java y Java 3D; este simulador utiliza las ecuaciones de la cinemática inversa y directa del brazo robótico propuesto en el trabajo de (Andueza, 2008). Véase Figura 14. 33 Figura 14: Herramienta Computacional (Arismendi, 2008). El simulador contiene un panel llamado Pasos, véase Figura 15, que sirve para la programación de tareas del manipulador; se agregan posiciones que se desea que tome el manipulador y una vez guardadas se puede ejecutar la secuencia de movimientos del mismo. Figura 15: Panel de Pasos del Simulador. 34 Como see observa en la Figuura 15, exxisten dos botones de d selecciónn sin funciionalidad, es decir, quee no fueron programaddos durante el desarrolllo de simulaador, ya quue para la feecha de culm minación deel proyecto, el manipuulador no esstaba totalm mente consttruido. Parte dell trabajo de esta tesis fue f realizar la program mación de essos dos móddulos (botoones) para que q cumpliera sus funciones, siguieendo la líneaa de program mación en Java y Java 3D. Debiddo a que la función dee los botonnes es comuunicar el siimulador coon el maniipulador, see pensó en utilizar un sistema de comunicacción serial, puesto que solo utilizza tres hiloss para trasm mitir inform mación y adeemás la maayoría de loos computaddores (PC) poseen pueertos seriales. En este caso se estabbleció trabajaar con el puuerto COM11. A continnuación se mostraránn los diagrramas de flujo que representaan el compportamientoo de cada unno de los bottones respectivamente:: p el botóón que ejecuuta la secuencia de acciiones de la tabla • Diagramaa de Flujo para de instruccciones en el e robot reall. Véase Figura 16. Figura 16: Diagrama de d Flujo 1. 35 • Diagramaa de Flujo para p el botóón que ejecuuta la secuencia de acciiones de la tabla de instruccioones en el roobot real y repite r el cicllo para un número n deteerminado. Véase V Figura 17. Figura 17: Diagrama de d Flujo 2. Los códigos c corrrespondienttes de dichoos módulos en e Java, están disponibles en los Anexo A A (páágina 68). Ahora enn cuanto al procesador, p se utilizó un u microconntrolador PIIC16F877, véase v Figurra 18, ya quue este dispoositivo es alttamente eficciente en el uso de la memoria m de datos d y proogramas y por p lo tantoo en la veloocidad de ejjecución. Además poseee periféricoos de serie síncrono y asíncronos lo cual perrmite establlecer comunnicación conn el computtador dondde se estará ejecutando e e simuladorr. el 36 Figura 18: PIC 16F877. Se tiene que tomar en cuenta que sus puertos de E/S utilizan la tecnología Transistor- Transistor Logic (TTL) que manejan niveles de voltaje de 0 a 5 V. Debido a que se va a utilizar la norma RS-232 para establecer la comunicación serial entre el simulador y el microcontrolador es necesario usar un dispositivo intermedio que permita regular el voltaje señalado en la norma. Ese dispositivo es el circuito integrado MAX232, véase Figura 19, ya que cambia los niveles TTL a los del RS-232 cuando se hace una trasmisión, y cambia los niveles RS-232 a TTL cuando se tiene una recepción. Figura 19: MAX232. En relación a lo anterior el diseño de la Interfaz correspondiente a la sección Simulador – Procesador es la que se muestra en la Figura 20. 37 Figura 20: Esquema electrónico Simulador - Procesador. 3.2 Procesador – Brazo Robótico En esta sección se comenzará conociendo los componentes electromecánicos del brazo robótico (Andueza, 2008), necesario para seguir con el diseño de la interfaz. Este manipulador posee tres grados de libertad por ende tiene tres articulaciones, véase Figura 21. Figura 21: Identificación de las articulaciones. 38 Las articulaciones 1 y 3 utilizan un motor de LEGO NXT respectivamente, la articulación 2 en cambio utiliza dos motores de LEGO NXT, necesarios para animar la estructura mecánica. Véase la Figura 22 y Figura 23. Figura 22: Articulaciones 1 y 3 con los motores LEGO NXT. Figura 23: Articulación 3 con los dos motores LEGO NXT. 39 Los motores tienen incorporado en su eje un sensor de posición del tipo encoder óptico incremental (véase Figura 24), que se encargan de representar los movimientos de los motores mediante señales eléctricas en forma de trenes de pulsos que varían entre 0 y 5 voltios. Figura 24: Encoder óptico incorporado en el motor LEGO NXT. Estos son los dispositivos eléctricos y electromecánicos que van a ser conectados por parte del manipulador a la interfaz. Para su conexión con la interfaz es necesario construir sus cables, para ello se identificaron los pines del conector del motor LEGO NXT según (The LEGO Group, 2006) son: 1 2 3 4 5 6 Pin de entrada para la señal PWM para el motor. Pin de entrada para la señal PWM para el motor. Pin de entrada para la señal de tierra del sensor. Pin de entrada para el voltaje (5V) del sensor. Pin de salida para la señal emitida por el sensor. Pin de salida para la señal emitida por el sensor. 40 Su conector es similar al telefónico (RJ11) tiene seis hilos pero la pestaña a la derecha, véase Figura 25, así que para su fabricación se utilizó el conector RJ11 con cable de seis hilos plano, pero quitando la pestaña del conector (véase Figura 26), todo esto debido a que los cables originales vienen en tamaños estándar y además son proporcionados por el Kit del LEGO MINDSTORMS NXT. Figura 25: Conector del motor LEGO NXT. Figura 26: Conector RJ11 sin pestaña. Las señales de los pines 1 y 2 del conector del motor van a ser proporcionadas por el microcontrolador, pero cuando se trabajan con microcontroladores, es habitual que las señales que se generan por sus puertos de E/S no tengan intensidad suficiente para hacer mover un motor, por lo que se tienen que utilizar dispositivos intermedios que la amplifiquen, como es el caso del driver L293B. Véase Figura 27. 41 Figura 27: Driver L293B. El L293B es un circuito integrado que contiene cuatro amplificadores capaces de generar 1A de corriente. Cada amplificador dispone de una señal de entrada INn, una salida OUTn y una tercera de control o permiso ENn para cada pareja de amplificadores. Vss será el pin de alimentación del driver y Vc la tensión a suministrar a los motores conectados. Al L293B se le pueden conectar dos motores LEGO NXT. El ENn funciona como activación para los motores y el INn para determinar el sentido de giro. Véase la Tabla 3. ENn INn1 INn2 Giro del Motor H L L Parada Rápida H:Nivel lógico alto H L H Sentido Horario L: Nivel lógico bajo H H L Sentido Antihorario L X X Deshabilitado X: H ó L Tabla 3: Comportamiento de un Motor LEGO NXT según el L293B. Las señales que emite el sensor por los pines 5 y 6 del conector RJ11 también van a ser tratadas y procesadas por el microcontrolador para cada uno de los motores del brazo robótico. 42 Otras de la razones de haber elegido el PIC16F877 es que éste cuenta con módulos para generar señales PWM, las cuales van a ser utilizadas por los motores para regular su velocidad, así como de comparadores de tensión para detectar las emitidas por los sensores. Estos aspectos se tuvieron en cuenta para el diseño de la interfaz en la asignación de los puertos de E/S del PIC que conecta a los motores. En la Figura 28, se muestra el esquema electrónico para esta sección, siguiendo las consideraciones expuestas anteriormente. Figura 28: Esquema electrónico Procesador - Brazo Robótico. 43 Los diodos, están conectados para proteger el circuito contra posibles picos de corriente inversa cuando se pone en marcha los motores. Por lo tanto, el diseño e implementación de la interfaz, es el resultado de la unión de los esquemas electrónicos de las secciones anteriores, tal como se puede observar en la Figura 29. Figura 29: Esquema electrónico de la Interfaz. Para entender el esquema electrónico se recomienda revisar el Anexo B (página 79) donde se encuentran las datasheet de cada uno de los dispositivos utilizados en el diseño. 44 3.3 Programación del PIC16F877 A la hora de seguir el esquema de la Figura 2 (página 9) en el diseño de la Interfaz, se puede pensar en un sistema de control realimentado para cada uno de los motores que actúan en las articulaciones del brazo robótico, véase Figura 30. Figura 30: Sistema de control para las articulaciones. En el computador se interpretan uno por uno los comandos del Simulador, en éste se calcula la cinemática del manipulador, dando como resultado la posición angular deseada de cada uno de los eslabones. Esta información es suministrada al bloque Microcontrolador. Dicho bloque interpreta la información correspondiente a los pulsos que se quieren obtener de los sensores, y así lograr la posición angular a la que se quiere llegar, además de establecer para cuál de los motores se va a generar las señales necesarias para controlar su giro y velocidad y lograr de la posición actual . A su vez recibe la información proveniente de los encoders ópticos (pulsos). Es por esta razón que se programaron tres módulos para el PIC16F877, los cuales son: • Módulo que interpreta las señales emitidas por los encoders ópticos, para que el PIC pueda contar los pulsos enviados por los encoders, debe realizar una 45 detección de flanco de subida (cambio de 0 a 5 voltios en la señal), es decir, que va contando uno por cada flanco de subida que detecta. • Módulo de leer y escribir usando comunicación serial, el PIC recibe información del simulador referente a la posición angular deseada para cada eslabón, debe ser expresada en cantidades de pulsos, ya que los sensores lo que hacen es convertir una magnitud analógica de entrada en una señal digital. A su vez, el PIC envía información al simulador cuando se ha alcanzado (cantidad de pulsos), para así recibir nuevamente información y procesarla. • Módulo de generar las señales para el control de giro y velocidad de los motores, el PIC interpreta la información que proviene del simulador para determinar a cual motor hay que aplicar las señales según la Tabla 3, y así lograr . En cuanto al control de velocidad de los motores, se pueden tener variaciones, que corresponden al tiempo que permanece en alto (5V) la señal PWM en un determinado período fijo. Para dichos módulos se utilizaron los recursos mostrados en la Tabla 4. Recursos Módulo USART Pines C6 configurado para trasmitir información. C7 configurado para recibir información. Módulo PWM C2 configurado para generar señales PWM. Interrupciones B0 configurado para detectar los pulsos enviados Externas Puertos E/S por los encoders ópticos. B2, B3, B4, B5, C3, C4, D2 y D3 configurados para controlar el sentido de giro de los motores. Tabla 4: Recursos utilizados por el PIC16F877. 46 Con la interfaz diseñada en un protoboard y con un software llamado Serial Módem que permite enviar y recibir información a través del puerto serial de la computadora (véase Figura 36, página 55), se realizaron a los motores de cada una de las articulaciones pruebas experimentales para determinar la velocidad y posición angular. Estas pruebas consistieron en enviar una cantidad de pulsos con una cierta velocidad a la Interfaz, permitiendo al modulo sensor programado en el PIC realizar un conteo de los pulsos emitidos por los encoders, lográndose obtener la cantidad de pulsos enviados y así poder observar la posición angular final de los eslabones mediante un transportador, obteniéndose: a) Para la articulación 1 se trabajó con una velocidad constante del 60%, véase Figura 31, ya que es la velocidad mínima requerida para animar el eslabón 1, puesto que para velocidades inferiores se forzaba el motor y no se obtenía movimiento. Por el contrario, al usar valores superiores, por ejemplo 90%, se producían movimientos bruscos provocando variaciones en la posición deseada. Figura 31: Velocidad del 60% para la articulación 1. En cuanto a la posición angular, se tomaron mediciones en el encoder respecto a los dos giros del motor: horario y antihorario. Estas mediciones son para obtener la relación pulsos vs ángulos que se observa en la Tabla 5 para el sentido horario, y la Tabla 6 para el antihorario. 47 Tabla 5: Relación pulsos vs grados, sentido horario articulación 1. Pulsos Grados 20 12 40 22 60 36 80 39 100 50 120 58 140 67 160 73 180 76 200 82 220 90 240 102 260 107 280 113 300 120 320 133 340 137 360 145 380 150 400 160 420 171 440 180 Tabla 6: Relación pulsos vs grados, sentido antihorario articulación 1. Pulsos Grados 0 180 20 170 40 153 60 138 80 130 48 100 126 120 112 140 102 160 95 180 89 200 80 220 74 240 65 260 61 280 56 300 48 320 40 340 35 360 31 380 25 400 18 420 8 440 3 A partir de los datos de las Tablas mencionadas se obtuvieron las gráficas mostradas en la Figura 32, con su respectiva interpolación polinómica. Interpolación polinómica para la Tabla 5: 3.812 3.4784 7.3485 1.4724 0.0005325 0.023459 3.8071 0.59237 6.4997 5.7235 Interpolación polinómica para la Tabla 6: 6.9563 1.4934 4.104 441.81 9.67322 0.001169 0.068619 34.68 49 Figura 32: Gráficas correspondiente a las tablas 5 y 6. b) Para la articulación 3 se tomaron en cuenta los aspectos mencionados anteriormente en relación a determinar la velocidad del 60%, al igual se tomaron mediciones del encoder con el fin de determinar la relación existente entre los ángulos y pulsos para los dos giros del motor, dando como resultado la Tabla 7 y la Tabla 8. 50 Tabla 7: Relación pulsos vs grados, sentido horario articulación 3. Pulsos Grados 0 ‐90 20 ‐65 40 ‐48 60 ‐33 80 ‐23 100 ‐15 120 ‐5 140 2 160 8 180 15 200 25 220 33 240 40 260 50 280 62 300 73 320 80 340 87 Tabla 8: Relación pulsos vs grados, sentido antihorario articulación 3. Pulsos Grados 0 90 20 70 40 47 60 20 80 2 100 ‐8 120 ‐19 140 ‐32 51 160 ‐43 180 ‐60 200 ‐67 220 ‐70 240 ‐75 260 ‐80 280 ‐87 300 ‐90 Las gráficas referentes a las Tablas anteriores se pueden apreciar en la Figura 33. Figura 33: Gráficas grados vs pulsos de las tablas 7 y 8. 52 Para las cuales se obtuvieron las interpolaciones polinómicas respectivamente: Horario: 1.5425 9.1096 2.6572 8.9332 0.00021107 0.0062388 8.0259 6.5768 135.96 Antihorario: 8.3385 4.8696 0.00033694 0.01602 1.36141 1.6928 84.908 c) A diferencia de las articulaciones anteriores, la articulación 2 trabaja con variaciones en la velocidad, véase la Figura 34, debido a que tiene que realizar mayor fuerza para romper la inercia provocada por la adición del peso del eslabón 3 con el 2. Una vez logrado esto, se tiene que decrementar la velocidad progresivamente, ya que la fuerza de gravedad ayudaría a que el eslabón 2 incremente su velocidad. Al igual, se tomaron mediciones en el encoder para los dos giros de los motores, las cuales se pueden observar en las Tablas 9 y 10 respectivamente. Velocidad vs Pulsos 1200 1000 800 600 400 200 0 0 20 40 60 80 100120140160180200220240260280300 Figura 34: Variaciones de la velocidad. 53 Tabla 9: Relación pulsos vs grados, sentido horario articulación 2. Pulsos Grados 0 0 20 3 40 10 60 15 80 21 100 36 120 43 140 55 160 58 180 74 200 83 220 90 240 120 260 138 280 162 300 180 Tabla 10: Relación pulsos vs grados, sentido antihorario articulación 2. Pulsos Grados 0 180 20 174 40 167 60 153 80 143 100 138 120 129 140 127 160 118 54 180 100 200 77 220 55 240 45 260 40 280 8 300 0 En base a las mediciones almacenadas en las Tablas anteriores se pueden apreciar sus gráficas en la Figura 35. Figura 35: Gráficas grados vs pulsos de las tablas 9 y 10. 55 Sus respectivas interpolaciones polinómicas son las siguientes: Interpolación para la Tabla 9: 1.0471 7.5019 0.00018232 2.2004 0.0072672 3.4344 0.20931 5.8923 3.1489 5.8923 1.0463 Interpolación para la Tabla 10: 9.3801 8.1935 0.00069859 0.031438 3.1224 0.69036 6.7277 6.2879 8.812 299.89 Figura 36: Montaje de la interfaz para realizar mediciones en los motores. 56 Cabe destacar que las ecuaciones calculadas para cada una de las articulaciones fueron tomadas en cuenta en la programación de los módulos del simulador referente al envío de los ángulos, ya que la interfaz como se pudo apreciar manipula las señales de los encoders (pulsos). La escritura del programa se realizó en un lenguaje de alto nivel C PCW, para ver la implementación del código refiérase al Anexo C (página 86). Para el grabado en la memoria ROM del PIC del fichero .hex generado por el compilador, se utilizó un software llamado IC-Prog conjuntamente con su hardware de programación JDM Programmer, véase Figura 37. Figura 37: Software y Hardware para la programación del PIC. 57 3.4 Construcción del circuito impreso para la Interfaz Para la construcción del circuito impreso o Printed Circuit Board (PCB), se utilizó el software de diseño electrónico Proteus versión 7.2 con sus tres módulos respectivos: • Intelligent Schematic Input System (ISIS), este módulo permitió realizar el esquema electrónico de la Interfaz diseñada, véase Figura 38. 12v C1 22p C2 22p X1 13 14 1 CRYSTAL R1 10k 5v 16 U2 2 3 4 5 6 7 8 9 10 OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RE0/AN5/RD RC2/CCP1 RE1/AN6/WR RC3/SCK/SCL RE2/AN7/CS RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT RD0/PSP0 RD1/PSP1 RD2/PSP2 RD3/PSP3 RD4/PSP4 RD5/PSP5 RD6/PSP6 RD7/PSP7 33 34 35 36 37 38 39 40 2 7 1 IN1 IN2 EN1 9 10 15 EN2 IN3 IN4 VSS VS OUT1 OUT2 GND 15 16 17 18 23 24 25 26 3 6 OUT3 GND OUT4 +88.8 16 2 7 1 IN1 IN2 EN1 D2 1N4007 1N4007 D3 D4 1N4007 1N4007 D5 D6 1N4007 1N4007 D7 D8 1N4007 1N4007 D9 D10 1N4007 1N4007 D11 D12 1N4007 1N4007 D13 D14 1N4007 1N4007 D15 D16 1N4007 1N4007 11 14 L293D 19 20 21 22 27 28 29 30 D1 U1 +88.8 VSS 8 VS OUT1 OUT2 U3 3 6 +88.8 9 10 15 EN2 IN3 IN4 GND PIC16F877 OUT3 GND OUT4 11 14 L293D +88.8 C5 1 C1+ 11 12 10 9 8 1u 16 VCC T1IN R1OUT T2IN R2OUT U4 3 C1T1OUT R1IN T2OUT R2IN VS+ VS- C2+ GND 14 13 7 8 2 6 15 1u C3 1u 1 6 2 7 3 8 4 9 DCD DSR RXD RTS TXD CTS DTR RI C2- C4 4 P1 C6 ERROR 5 MAX232 COMPIM 1u Figura 38: Esquema electrónico en Proteus. • Virtual System Modelling (VSM), permitió simular el esquema electrónico, ya que la característica más sorprendente e importante de VSM es su capacidad de simular el software que se ejecuta en el microcontrolador y su interacción con cualquier componente electrónico digital o analógico conectado a él. Para realizar este 58 proceso es muy sencillo, se sitúa el PIC y se selecciona el fichero .hex que contiene el programa que deseamos ejecutar en el microcontrolador. • Advanced Routing and Editing Software (ARES), en este módulo de diseño, la PCB está plenamente integrada con el módulo ISIS, ya que una vez diseñado el esquema en ISIS éste genera automáticamente la lista de redes (los pines interconectados entre sí), ARES es capaz de recibir estas redes, para diseñar a partir de ellas nuestra PCB, véase la Figura 39. Figura 39: Circuito impreso de la Interfaz. Este módulo también permite ver el diseño del circuito impreso de la Interfaz en 3D como se puede apreciar en la Figura 40. 59 Figura 40: Circuito impreso de la Interfaz en 3D. Completada esta fase, se procede a realizar el circuito impreso siguiendo una técnica muy conocida que consiste en transferir el esquema diseñado en ARES a una baquelita de cobre por medio del papel transfer. 3.5 Resultados Para la validación de la interfaz se realizaron distintas pruebas, que consistieron en utilizar el simulador para enviar los ángulos requeridos a los eslabones del brazo robótico, obteniéndose resultados satisfactorios tal como se pueden apreciar en las Tablas 11, 12 y 13. 60 Tabla 11. Resultados de la Articulación 1 (Horario). Grados Requeridos 12 22 36 39 50 58 67 73 76 82 90 102 107 113 Grados Obtenidos 12 20 33 40 45 55 65 72 75 80 89 100 106 110 Error en Grados 120 118 2 133 134 1 137 139 2 145 148 3 150 150 0 160 161 1 171 172 1 180 179 1 0 2 3 1 5 3 2 1 1 2 1 2 1 3 61 Tabla 12. Resultados de la Articulación 2 (Antihorario). Grados Requeridos 180 174 167 153 143 138 129 127 118 100 77 55 45 40 Grados Obtenidos 180 173 170 157 147 143 134 132 124 105 77 52 47 40 Error en Grados 8 0 0 1 3 4 4 5 5 5 6 5 0 3 2 0 8 0 0 0 Tabla 13. Resultados para la Articulación 3 (Antihorario). Grados Requeridos -90 -65 -48 -33 -23 -15 -5 2 8 15 25 33 40 50 Grados Obtenidos -90 -65 -47 -34 -23 -15 -4 1 7 17 25 33 41 50 Error en Grados 0 0 1 1 0 0 1 1 1 2 0 0 1 0 62 62 61 1 73 70 3 80 78 2 87 86 1 Como se puede apreciar en las Tablas el margen de error máximo para la Articulación 1, 2 y 3 son: 5, 8 y 1 respectivamente, lo cual garantiza que se está cumpliendo la realimentación, estos errores se puede minimizar mejorando la interpolación polinómica, es decir, aumentando el grado del polinomio. En las Figuras 41 y 42 se pueden apreciar resultados obtenidos de la Interfaz diseñada. Figura 41: Prueba 1. 63 Figura 42: Prueba 2. Capítulo 4 Conclusiones y Recomendaciones 4.1 Conclusiones El logro más importante de este proyecto fue el de construir una tarjeta electrónica que sirve de interfaz entre una herramienta computacional para la simulación de un manipulador de 3 grados de libertad con un brazo robótico. Obteniéndose a partir del diseño e implementación de la misma las siguientes conclusiones: • La interfaz permite realizar un control de posición para los eslabones del manipulador basados en la realimentación de los encoders ópticos incrementales. • Para el control de la posición de los eslabones es necesario la variable de referencia en este caso la posición angular deseada, la cual es enviada a la interfaz a través del simulador usando comunicación serial. • Para lograr la posición de los eslabones es necesaria animar las articulaciones que están dotadas por motores CC, lo cual basta con suministrar señales PWM a los drivers de potencia, ya que los microcontroladores no generan la potencia suficiente. • Cuando se utilizan sensores para obtener un sistema realimentado se tiene que tomar en cuenta la relación con su variable física. • Al establecer un sistema de comunicación entre un microprocesador y terminales de un computador se tienen que acondicionar las señales a trasmitir. 65 • Gracias a la versatilidad y programación de los microcontroladores PIC se pueden utilizar en actividades que requieran del procesamiento de señales digitales y control de diferentes dispositivos electrónicos. 4.2 Recomendaciones • Cuando se desea utilizar la interfaz para mover las articulaciones del brazo no se debe hacer por un tiempo prolongado, ya que esto provoca sobrecalentamiento en los motores, conllevando a que pierdan potencia y no se logre alcanzar el objetivo deseado (posición angular deseada). • Al conectar el computador con la interfaz se debe tomar en cuenta que el puerto serial COM1 debe de estar libre, es decir, no debe estar ocupado por ningún otro periférico, ya que el simulador utiliza este puerto para establecer la comunicación con la interfaz. • Al utilizar la interfaz se debe tener en cuenta que sus respectivos cables de conexión no interfieran en el eslabón 0, ya que interrumpen el movimiento de la articulación 1, arrojando así resultados no deseados. Bibliografía Alicante, D. d.-U. (Noviembre de 2001). Universidad de Alicante. Recuperado el 23 de Octubre de 2008, de http://www.dccia.ua.es/dccia/inf/asignaturas/ROB/optativos/Sensores/internos.html Andueza, L. J. (2008). Diseño de un manipulador robótico con tres grados de libertad para fines educativos. Tesis (Magister Scientiae), Universidad de Los Andes, Facultad de Ingeniería, Postgrado en Control y Automatización, Mérida - Venezuela. Angulo, J., Romero, S., & Angulo, I. (2005). Introducción a la Robótica. Madrid, España: THOMSON. Angulo, J., Romero, S., & Angulo, I. (2006). Microcontroladores PIC: Diseño práctico de aplicaciones 2da parte. Mc Graw Hill. Arismendi, C. (2008). Desarrollo de una herramienta computacional para la simulación y programación de un manipulador robótico de tres grados de libertad. Proyecto de Grado EISULA, Universidad de Los Andes, Escuela de Ingeniería de Sistemas, Mérida - Venezuela. Bishop, R. H. (2002). Mechatronics Handbook. Boca Ratón, EE.UU.: CRC PRESS. Craig, J. J. (2006). Robótica. México: Pearson Preintice Hall. Instruments, N. (06 de Junio de 2006). Recuperado el 25 de Noviembre de 2008, de http://digital.ni.com/public.nsf/allkb/039001258CEF8FB686256E0F005888D1 67 Iñigo Madrigal, R., & Vidal Idiarte, E. (2002). Robots industriales manipuladores. Barcelona España: Edicions UPC. Microcontrolador, W. (2008). Wikipedia - Microcontrolador. Recuperado el 15 de 10 de 2008, de http://es.wikipedia.org/wiki/Microcontrolador Orduña Huertas, J. M., & Arnau Llombart, V. (1996). Arquitectura y programación de microcontroladores. Valencia - España: Universitat. The LEGO Group. (2006). LEGO MINDSTORMS NXT Hardware Developer Kit. University, M. (2008). Acerca de Mechatronics. Recuperado el 27 de 04 de 2008, de http://www.eng.mu.edu/~craigk/ Anexo A private void botonSecRobActionPerformed(java.awt.event.ActionEvent evt) { String accion; String valor; String ind=""; String pulsos; String velo_h; float ang1; Double angulo=0.0; Double angulo_a=0.0; Double vel_h=0.0; model.setAng1Gra(0); model.setAng2Gra(0); model.setAng3Gra(-90); listaPuertos = CommPortIdentifier.getPortIdentifiers(); while( listaPuertos.hasMoreElements() ) { idPuerto = (CommPortIdentifier)listaPuertos.nextElement(); if( idPuerto.getPortType() == CommPortIdentifier.PORT_SERIAL ) { if( idPuerto.getName().equals("COM1") ) { // Si el puerto no está en uso, se intenta abrir try { puertoSerie = ( SerialPort )idPuerto.open("AplEscritura",2000); } catch( PortInUseException e ) {} // Se obtiene un canal de salida try { salida = puertoSerie.getOutputStream(); } catch( IOException e ) {} // Se obtiene un canal de entrada try { entrada = puertoSerie.getInputStream(); } catch( IOException e ) {} puertoSerie.notifyOnDataAvailable(true); // Se fijan los parámetros de comunicación del puerto try { puertoSerie.setSerialPortParams( 9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE ); } catch( UnsupportedCommOperationException e ) {} } } 69 } //Se envian y reciben la informacion for(int i=0;i<modeloTabla.getRowCount();i++){ accion=(modeloTabla.getValueAt(i,1)).toString(); valor=(modeloTabla.getValueAt(i,2)).toString(); System.out.println(accion); System.out.println(valor); try { Thread.sleep( 1000); } catch (InterruptedException e) {e.printStackTrace();} if(accion.endsWith("1")){ ang1= model.getAng1(); if(ang1<Float.valueOf(valor)) { ind="I\r"; angulo=Double.valueOf(valor); angulo=(6.1028*Math.pow(10.0,20.0)*Math.pow(angulo,10.0))-(1.0942*Math.pow(10.0,16.0)*Math.pow(angulo,9.0))+(1.7442*Math.pow(10.0,-13.0)*Math.pow(angulo,8.0))(9.7398*Math.pow(10.0,-11.0)*Math.pow(angulo,7.0))+(2.5922*Math.pow(10.0,8.0)*Math.pow(angulo,6.0))-(3.7368*Math.pow(10.0,6.0)*Math.pow(angulo,5.0))+(0.00029904*Math.pow(angulo,4.0))(0.012579*Math.pow(angulo,3.0))+(0.24146*Math.pow(angulo,2.0))+(0.51239*angulo)+0.0 76864; if(ang1==0) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(6.1028*Math.pow(10.0,20.0)*Math.pow(angulo_a,10.0))-(1.0942*Math.pow(10.0,16.0)*Math.pow(angulo_a,9.0))+(1.7442*Math.pow(10.0,-13.0)*Math.pow(angulo_a,8.0))(9.7398*Math.pow(10.0,-11.0)*Math.pow(angulo_a,7.0))+(2.5922*Math.pow(10.0,8.0)*Math.pow(angulo_a,6.0))-(3.7368*Math.pow(10.0,6.0)*Math.pow(angulo_a,5.0))+(0.00029904*Math.pow(angulo_a,4.0))(0.012579*Math.pow(angulo_a,3.0))+(0.24146*Math.pow(angulo_a,2.0))+(0.51239*angulo_ a)+0.076864; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); } else if(ang1>Float.valueOf(valor)){ ind="O\r"; angulo=Double.valueOf(valor); angulo=(4.7166*Math.pow(10.0,11.0)*Math.pow(angulo,6.0))-(2.7902*Math.pow(10.0,8.0)*Math.pow(angulo,5.0))+(6.0209*Math.pow(10.0,-6.0)*Math.pow(angulo,4.0))(0.00055785*Math.pow(angulo,3.0))+(0.02458*Math.pow(angulo,2.0))(3.4218*angulo)+420.31; if(ang1==180) 70 angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(4.7166*Math.pow(10.0,11.0)*Math.pow(angulo_a,6.0))-(2.7902*Math.pow(10.0,8.0)*Math.pow(angulo_a,5.0))+(6.0209*Math.pow(10.0,-6.0)*Math.pow(angulo_a,4.0))(0.00055785*Math.pow(angulo_a,3.0))+(0.02458*Math.pow(angulo_a,2.0))(3.4218*angulo_a)+420.31; } angulo=(angulo-angulo_a); if(ang1>90) angulo=angulo-50; else angulo=angulo-70; angulo=Math.ceil(angulo); } pulsos=String.valueOf(angulo); System.out.println(pulsos); try { salida.write(pulsos.concat("\r").getBytes() ); } catch( IOException e ) {} try { salida.write(ind.getBytes() ); } catch( IOException e ) {} model.setAng1Gra(Float.valueOf(valor)); } else if(accion.endsWith("2")){ ang1= model.getAng2(); if(ang1<Float.valueOf(valor)) { ind="J\r"; angulo=Double.valueOf(valor); angulo=(1.0471*Math.pow(10.0,15.0)*Math.pow(angulo,9.0))-(7.5019*Math.pow(10.0,13.0)*Math.pow(angulo,8.0))+(2.2004*Math.pow(10.0,-10.0)*Math.pow(angulo,7.0))(3.4344*Math.pow(10.0,-8.0)*Math.pow(angulo,6.0))+(3.1489*Math.pow(10.0,6.0)*Math.pow(angulo,5.0))(0.00018232*Math.pow(angulo,4.0))+(0.0072672*Math.pow(angulo,3.0))(0.20931*Math.pow(angulo,2.0))+(5.8923*angulo)+1.0463; if(ang1==0){ angulo_a=0.0; vel_h=1023.0; } else { angulo_a=Double.valueOf(ang1); angulo_a=(1.0471*Math.pow(10.0,15.0)*Math.pow(angulo_a,9.0))-(7.5019*Math.pow(10.0,13.0)*Math.pow(angulo_a,8.0))+(2.2004*Math.pow(10.0,-10.0)*Math.pow(angulo_a,7.0))(3.4344*Math.pow(10.0,-8.0)*Math.pow(angulo_a,6.0))+(3.1489*Math.pow(10.0,6.0)*Math.pow(angulo_a,5.0))(0.00018232*Math.pow(angulo_a,4.0))+(0.0072672*Math.pow(angulo_a,3.0))(0.20931*Math.pow(angulo_a,2.0))+(5.8923*angulo_a)+1.0463; 71 vel_h=-(4.507*Math.pow(10.0,14.0)*Math.pow(angulo_a,7.0))+(5.3504*Math.pow(10.0,-11.0)*Math.pow(angulo_a,6.0))(2.6429*Math.pow(10.0,-8.0)*Math.pow(angulo_a,5.0))+(7.0484*Math.pow(10.0,6.0)*Math.pow(angulo_a,4.0))(0.0010772*Math.pow(angulo_a,3.0))+(0.089206*Math.pow(angulo_a,2.0))(5.3203*angulo_a)+1028.6; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); vel_h=Math.ceil(vel_h); } else if(ang1>Float.valueOf(valor)){ ind="K\r"; angulo=Double.valueOf(valor); angulo=-(9.3801*Math.pow(10.0,16.0)*Math.pow(angulo,9.0))+(8.1935*Math.pow(10.0,-13.0)*Math.pow(angulo,8.0))(3.1224*Math.pow(10.0,-10.0)*Math.pow(angulo,7.0))+(6.7277*Math.pow(10.0,8.0)*Math.pow(angulo,6.0))-(8.812*Math.pow(10.0,6.0)*Math.pow(angulo,5.0))+(0.00069859*Math.pow(angulo,4.0))(0.031438*Math.pow(angulo,3.0))+(0.69036*Math.pow(angulo,2.0))(6.2879*angulo)+299.89; if(ang1==180) { angulo_a=0.0; vel_h=1023.0; } else { angulo_a=Double.valueOf(ang1); angulo_a=-(9.3801*Math.pow(10.0,16.0)*Math.pow(angulo_a,9.0))+(8.1935*Math.pow(10.0,-13.0)*Math.pow(angulo_a,8.0))(3.1224*Math.pow(10.0,-10.0)*Math.pow(angulo_a,7.0))+(6.7277*Math.pow(10.0,8.0)*Math.pow(angulo_a,6.0))-(8.812*Math.pow(10.0,6.0)*Math.pow(angulo_a,5.0))+(0.00069859*Math.pow(angulo_a,4.0))(0.031438*Math.pow(angulo_a,3.0))+(0.69036*Math.pow(angulo_a,2.0))(6.2879*angulo_a)+299.89; vel_h=(1.5867*Math.pow(10.0,9.0)*Math.pow(angulo_a,5.0))-(1.1693*Math.pow(10.0,6.0)*Math.pow(angulo_a,4.0))+(0.0003026*Math.pow(angulo_a,3.0))(0.031588*Math.pow(angulo_a,2.0))-(0.8949*angulo_a)+1015.6; } angulo=angulo-angulo_a; angulo=Math.ceil(angulo); vel_h=Math.ceil(vel_h); } pulsos=String.valueOf(angulo); System.out.println(pulsos); velo_h=String.valueOf(vel_h); System.out.println(velo_h); try { salida.write(pulsos.concat("\r").getBytes() ); } catch( IOException e ) {} try { salida.write(ind.getBytes() ); 72 } catch( IOException e ) {} try { Thread.sleep( 1000); } catch (InterruptedException e) {e.printStackTrace();} try { salida.write(velo_h.concat("\r").getBytes() ); } catch( IOException e ) {} model.setAng2Gra(Float.valueOf(valor)); } else if(accion.endsWith("3")){ ang1= model.getAng3(); if(ang1<Float.valueOf(valor)) { ind="B\r"; angulo=Double.valueOf(valor); angulo=(9.1096*Math.pow(10.0,11.0)*Math.pow(angulo,6.0))+(1.5425*Math.pow(10.0,-8.0)*Math.pow(angulo,5.0))(8.9332*Math.pow(10.0,-7.0)*Math.pow(angulo,4.0))(0.00021107*Math.pow(angulo,3.0))+(0.0062388*Math.pow(angulo,2.0))+(2.6572*angulo)+ 135.96; if(ang1==-90) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(9.1096*Math.pow(10.0,11.0)*Math.pow(angulo_a,6.0))+(1.5425*Math.pow(10.0,-8.0)*Math.pow(angulo_a,5.0))(8.9332*Math.pow(10.0,-7.0)*Math.pow(angulo_a,4.0))(0.00021107*Math.pow(angulo_a,3.0))+(0.0062388*Math.pow(angulo_a,2.0))+(2.6572*angu lo_a)+135.96; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); } else if(ang1>Float.valueOf(valor)){ ind="N\r"; angulo=Double.valueOf(valor); angulo=(-8.3385*Math.pow(10.0,14.0)*Math.pow(angulo,8.0))+(4.8696*Math.pow(10.0,12.0)*Math.pow(angulo,7.0))+(1.3614*Math.pow(10.0,-9.0)*Math.pow(angulo,6.0))(8.0259*Math.pow(10.0,-8.0)*Math.pow(angulo,5.0))-(6.5768*Math.pow(10.0,6.0)*Math.pow(angulo,4.0))+(0.00033694*Math.pow(angulo,3.0))+(0.01602*Math.pow(angu lo,2.0))-(1.6928*angulo)+84.908; if(ang1==90) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(-8.3385*Math.pow(10.0,14.0)*Math.pow(angulo_a,8.0))+(4.8696*Math.pow(10.0,12.0)*Math.pow(angulo_a,7.0))+(1.3614*Math.pow(10.0,-9.0)*Math.pow(angulo_a,6.0))(8.0259*Math.pow(10.0,-8.0)*Math.pow(angulo_a,5.0))-(6.5768*Math.pow(10.0,- 73 6.0)*Math.pow(angulo_a,4.0))+(0.00033694*Math.pow(angulo_a,3.0))+(0.01602*Math.pow( angulo_a,2.0))-(1.6928*angulo_a)+84.908; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); } pulsos=String.valueOf(angulo); System.out.println(pulsos); try { salida.write(pulsos.concat("\r").getBytes() ); } catch( IOException e ) {} try { salida.write(ind.getBytes() ); } catch( IOException e ) {} model.setAng3Gra(Float.valueOf(valor)); } while(siga.equals("n")){ try { while (entrada.available() > 0) { int nbyte = entrada.read(readBuffer); siga = new String (readBuffer) ; System.out.println(new String(readBuffer)); } }catch (IOException e) {} } siga="n"; } puertoSerie.close(); //Cierra el puerto COM1 } private void botonCicloRobActionPerformed(java.awt.event.ActionEvent evt) { String accion; String valor; String ind=""; String pulsos; String velo_h; float ang1; Double angulo=0.0; Double angulo_a=0.0; Double vel_h=0.0; model.setAng1Gra(0); model.setAng2Gra(0); model.setAng3Gra(-90); //Se envian y reciben la informacion if(!esUltPosIni("Mover 1")) modeloTabla.addRow(new Object[]{modeloTabla.getRowCount()+1,"Mover 1", 0, getPunto()}); 74 if(!esUltPosIni("Mover 2")) modeloTabla.addRow(new Object[]{modeloTabla.getRowCount()+1,"Mover 2", 0, getPunto()}); if(!esUltPosIni("Mover 3")) modeloTabla.addRow(new Object[]{modeloTabla.getRowCount()+1,"Mover 3", -90, getPunto()}); listaPuertos = CommPortIdentifier.getPortIdentifiers(); while( listaPuertos.hasMoreElements() ) { idPuerto = (CommPortIdentifier)listaPuertos.nextElement(); if( idPuerto.getPortType() == CommPortIdentifier.PORT_SERIAL ) { if( idPuerto.getName().equals("COM1") ) { // Si el puerto no está en uso, se intenta abrir try { puertoSerie = ( SerialPort )idPuerto.open("AplEscritura",2000); } catch( PortInUseException e ) {} // Se obtiene un canal de salida try { salida = puertoSerie.getOutputStream(); } catch( IOException e ) {} // Se obtiene un canal de entrada try { entrada = puertoSerie.getInputStream(); } catch( IOException e ) {} puertoSerie.notifyOnDataAvailable(true); // Se fijan los parámetros de comunicación del puerto try { puertoSerie.setSerialPortParams( 9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE ); } catch( UnsupportedCommOperationException e ) {} } } } int repetir; String ciclos=JOptionPane.showInputDialog("Introduzca el número de ciclos"); if(ciclos!=null) repetir = Integer.parseInt(ciclos); else repetir=0; while(repetir>0){ repetir--; //Se envian y reciben la informacion for(int i=0;i<modeloTabla.getRowCount();i++){ accion=(modeloTabla.getValueAt(i,1)).toString(); valor=(modeloTabla.getValueAt(i,2)).toString(); System.out.println(accion); System.out.println(valor); try { 75 Thread.sleep( 1000); } catch (InterruptedException e) {e.printStackTrace();} if(accion.endsWith("1")){ ang1= model.getAng1(); if(ang1<Float.valueOf(valor)) { ind="I\r"; angulo=Double.valueOf(valor); angulo=(6.1028*Math.pow(10.0,20.0)*Math.pow(angulo,10.0))-(1.0942*Math.pow(10.0,16.0)*Math.pow(angulo,9.0))+(1.7442*Math.pow(10.0,-13.0)*Math.pow(angulo,8.0))(9.7398*Math.pow(10.0,-11.0)*Math.pow(angulo,7.0))+(2.5922*Math.pow(10.0,8.0)*Math.pow(angulo,6.0))-(3.7368*Math.pow(10.0,6.0)*Math.pow(angulo,5.0))+(0.00029904*Math.pow(angulo,4.0))(0.012579*Math.pow(angulo,3.0))+(0.24146*Math.pow(angulo,2.0))+(0.51239*angulo)+0.0 76864; if(ang1==0) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(6.1028*Math.pow(10.0,20.0)*Math.pow(angulo_a,10.0))-(1.0942*Math.pow(10.0,16.0)*Math.pow(angulo_a,9.0))+(1.7442*Math.pow(10.0,-13.0)*Math.pow(angulo_a,8.0))(9.7398*Math.pow(10.0,-11.0)*Math.pow(angulo_a,7.0))+(2.5922*Math.pow(10.0,8.0)*Math.pow(angulo_a,6.0))-(3.7368*Math.pow(10.0,6.0)*Math.pow(angulo_a,5.0))+(0.00029904*Math.pow(angulo_a,4.0))(0.012579*Math.pow(angulo_a,3.0))+(0.24146*Math.pow(angulo_a,2.0))+(0.51239*angulo_ a)+0.076864; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); } else if(ang1>Float.valueOf(valor)){ ind="O\r"; angulo=Double.valueOf(valor); angulo=(4.7166*Math.pow(10.0,11.0)*Math.pow(angulo,6.0))-(2.7902*Math.pow(10.0,8.0)*Math.pow(angulo,5.0))+(6.0209*Math.pow(10.0,-6.0)*Math.pow(angulo,4.0))(0.00055785*Math.pow(angulo,3.0))+(0.02458*Math.pow(angulo,2.0))(3.4218*angulo)+420.31; if(ang1==180) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(4.7166*Math.pow(10.0,11.0)*Math.pow(angulo_a,6.0))-(2.7902*Math.pow(10.0,8.0)*Math.pow(angulo_a,5.0))+(6.0209*Math.pow(10.0,-6.0)*Math.pow(angulo_a,4.0))(0.00055785*Math.pow(angulo_a,3.0))+(0.02458*Math.pow(angulo_a,2.0))(3.4218*angulo_a)+420.31; } angulo=(angulo-angulo_a); if(ang1>90) 76 angulo=angulo-50; else angulo=angulo-70; angulo=Math.ceil(angulo); } pulsos=String.valueOf(angulo); System.out.println(pulsos); try { salida.write(pulsos.concat("\r").getBytes() ); } catch( IOException e ) {} try { salida.write(ind.getBytes() ); } catch( IOException e ) {} model.setAng1Gra(Float.valueOf(valor)); } else if(accion.endsWith("2")){ ang1= model.getAng2(); if(ang1<Float.valueOf(valor)) { ind="J\r"; angulo=Double.valueOf(valor); angulo=(1.0471*Math.pow(10.0,15.0)*Math.pow(angulo,9.0))-(7.5019*Math.pow(10.0,13.0)*Math.pow(angulo,8.0))+(2.2004*Math.pow(10.0,-10.0)*Math.pow(angulo,7.0))(3.4344*Math.pow(10.0,-8.0)*Math.pow(angulo,6.0))+(3.1489*Math.pow(10.0,6.0)*Math.pow(angulo,5.0))(0.00018232*Math.pow(angulo,4.0))+(0.0072672*Math.pow(angulo,3.0))(0.20931*Math.pow(angulo,2.0))+(5.8923*angulo)+1.0463; if(ang1==0){ angulo_a=0.0; vel_h=1023.0; } else { angulo_a=Double.valueOf(ang1); angulo_a=(1.0471*Math.pow(10.0,15.0)*Math.pow(angulo_a,9.0))-(7.5019*Math.pow(10.0,13.0)*Math.pow(angulo_a,8.0))+(2.2004*Math.pow(10.0,-10.0)*Math.pow(angulo_a,7.0))(3.4344*Math.pow(10.0,-8.0)*Math.pow(angulo_a,6.0))+(3.1489*Math.pow(10.0,6.0)*Math.pow(angulo_a,5.0))(0.00018232*Math.pow(angulo_a,4.0))+(0.0072672*Math.pow(angulo_a,3.0))(0.20931*Math.pow(angulo_a,2.0))+(5.8923*angulo_a)+1.0463; vel_h=-(4.507*Math.pow(10.0,14.0)*Math.pow(angulo_a,7.0))+(5.3504*Math.pow(10.0,-11.0)*Math.pow(angulo_a,6.0))(2.6429*Math.pow(10.0,-8.0)*Math.pow(angulo_a,5.0))+(7.0484*Math.pow(10.0,6.0)*Math.pow(angulo_a,4.0))(0.0010772*Math.pow(angulo_a,3.0))+(0.089206*Math.pow(angulo_a,2.0))(5.3203*angulo_a)+1028.6; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); vel_h=Math.ceil(vel_h); } 77 else if(ang1>Float.valueOf(valor)){ ind="K\r"; angulo=Double.valueOf(valor); angulo=-(9.3801*Math.pow(10.0,16.0)*Math.pow(angulo,9.0))+(8.1935*Math.pow(10.0,-13.0)*Math.pow(angulo,8.0))(3.1224*Math.pow(10.0,-10.0)*Math.pow(angulo,7.0))+(6.7277*Math.pow(10.0,8.0)*Math.pow(angulo,6.0))-(8.812*Math.pow(10.0,6.0)*Math.pow(angulo,5.0))+(0.00069859*Math.pow(angulo,4.0))(0.031438*Math.pow(angulo,3.0))+(0.69036*Math.pow(angulo,2.0))(6.2879*angulo)+299.89; if(ang1==180) { angulo_a=0.0; vel_h=1023.0; } else { angulo_a=Double.valueOf(ang1); angulo_a=-(9.3801*Math.pow(10.0,16.0)*Math.pow(angulo_a,9.0))+(8.1935*Math.pow(10.0,-13.0)*Math.pow(angulo_a,8.0))(3.1224*Math.pow(10.0,-10.0)*Math.pow(angulo_a,7.0))+(6.7277*Math.pow(10.0,8.0)*Math.pow(angulo_a,6.0))-(8.812*Math.pow(10.0,6.0)*Math.pow(angulo_a,5.0))+(0.00069859*Math.pow(angulo_a,4.0))(0.031438*Math.pow(angulo_a,3.0))+(0.69036*Math.pow(angulo_a,2.0))(6.2879*angulo_a)+299.89; vel_h=(1.5867*Math.pow(10.0,9.0)*Math.pow(angulo_a,5.0))-(1.1693*Math.pow(10.0,6.0)*Math.pow(angulo_a,4.0))+(0.0003026*Math.pow(angulo_a,3.0))(0.031588*Math.pow(angulo_a,2.0))-(0.8949*angulo_a)+1015.6; } angulo=angulo-angulo_a; angulo=Math.ceil(angulo); vel_h=Math.ceil(vel_h); } pulsos=String.valueOf(angulo); System.out.println(pulsos); velo_h=String.valueOf(vel_h); System.out.println(velo_h); try { salida.write(pulsos.concat("\r").getBytes() ); } catch( IOException e ) {} try { salida.write(ind.getBytes() ); } catch( IOException e ) {} try { Thread.sleep( 1000); } catch (InterruptedException {e.printStackTrace();} try { salida.write(velo_h.concat("\r").getBytes() ); } catch( IOException e ) {} model.setAng2Gra(Float.valueOf(valor)); } e) 78 else if(accion.endsWith("3")){ ang1= model.getAng3(); if(ang1<Float.valueOf(valor)) { ind="B\r"; angulo=Double.valueOf(valor); angulo=(9.1096*Math.pow(10.0,11.0)*Math.pow(angulo,6.0))+(1.5425*Math.pow(10.0,-8.0)*Math.pow(angulo,5.0))(8.9332*Math.pow(10.0,-7.0)*Math.pow(angulo,4.0))(0.00021107*Math.pow(angulo,3.0))+(0.0062388*Math.pow(angulo,2.0))+(2.6572*angulo)+ 135.96; if(ang1==-90) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(9.1096*Math.pow(10.0,11.0)*Math.pow(angulo_a,6.0))+(1.5425*Math.pow(10.0,-8.0)*Math.pow(angulo_a,5.0))(8.9332*Math.pow(10.0,-7.0)*Math.pow(angulo_a,4.0))(0.00021107*Math.pow(angulo_a,3.0))+(0.0062388*Math.pow(angulo_a,2.0))+(2.6572*angu lo_a)+135.96; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); } else if(ang1>Float.valueOf(valor)){ ind="N\r"; angulo=Double.valueOf(valor); angulo=(-8.3385*Math.pow(10.0,14.0)*Math.pow(angulo,8.0))+(4.8696*Math.pow(10.0,12.0)*Math.pow(angulo,7.0))+(1.3614*Math.pow(10.0,-9.0)*Math.pow(angulo,6.0))(8.0259*Math.pow(10.0,-8.0)*Math.pow(angulo,5.0))-(6.5768*Math.pow(10.0,6.0)*Math.pow(angulo,4.0))+(0.00033694*Math.pow(angulo,3.0))+(0.01602*Math.pow(angu lo,2.0))-(1.6928*angulo)+84.908; if(ang1==90) angulo_a=0.0; else { angulo_a=Double.valueOf(ang1); angulo_a=(-8.3385*Math.pow(10.0,14.0)*Math.pow(angulo_a,8.0))+(4.8696*Math.pow(10.0,12.0)*Math.pow(angulo_a,7.0))+(1.3614*Math.pow(10.0,-9.0)*Math.pow(angulo_a,6.0))(8.0259*Math.pow(10.0,-8.0)*Math.pow(angulo_a,5.0))-(6.5768*Math.pow(10.0,6.0)*Math.pow(angulo_a,4.0))+(0.00033694*Math.pow(angulo_a,3.0))+(0.01602*Math.pow( angulo_a,2.0))-(1.6928*angulo_a)+84.908; } angulo=(angulo-angulo_a); angulo=Math.ceil(angulo); } pulsos=String.valueOf(angulo); System.out.println(pulsos); try { salida.write(pulsos.concat("\r").getBytes() ); } catch( IOException e ) {} 79 try { salida.write(ind.getBytes() ); } catch( IOException e ) {} model.setAng3Gra(Float.valueOf(valor)); } while(siga.equals("n")){ try { while (entrada.available() > 0) { int nbyte = entrada.read(readBuffer); siga = new String (readBuffer) ; System.out.println(new String(readBuffer)); } }catch (IOException e) {} } siga="n"; } } puertoSerie.close(); } //Cierra el puerto COM1 Anexo B • Datasheet para el dispositivo electrónico MAX232 81 82 • Datasheet para el dispositivo electrónico PIC16F877 83 84 85 • Datasheet para el driver L293B Anexo C Código del PIC #include <16F877.h> #include <stdlib.h> #fuses XT, NOLVP, NOWDT, PUT, BROWNOUT, NOPROTECT #use delay(clock=4000000) #use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7) char letra1[6], letra; long int velocidad_h=1023, valor=0, s=0, contador=0; void get_string(char* s, int max) { //Funcion para obtener un String del serial int len; char c; --max; len=0; do { c=getc(); if(c==8) { // Backspace if(len>0) { len--; } } else if ((c>=' ')&&(c<='~')) if(len<max) { s[len++]=c; } } while(c!=13); s[len]=0; } #int_ext void pulsos() { //Interrupcion para el contador 87 contador++; } //Articulacion 1 void horario1() { output_high(PIN_C5); output_high(PIN_A1); output_low(PIN_A2); } void anti_horario1() { output_high(PIN_C5); output_low(PIN_A1); output_high(PIN_A2); } void parar1() { output_low(PIN_C5); output_low(PIN_A1); output_low(PIN_A2); set_pwm1_duty(0); } //Articulacion 2 void horario2() { output_high(PIN_D3); output_high(PIN_B7); output_high(PIN_B5); output_low(PIN_B6); output_low(PIN_B4); } void anti_horario2() { output_high(PIN_D3); output_low(PIN_B7); output_low(PIN_B5); output_high(PIN_B6); output_high(PIN_B4); 88 } void parar2() { output_low(PIN_D3); output_low(PIN_B7); output_low(PIN_B5); output_low(PIN_B6); output_low(PIN_B4); set_pwm1_duty(0); } //Articulacion 3 void horario3() { output_high(PIN_D2); output_high(PIN_A3); output_low(PIN_A5); } void anti_horario3() { output_high(PIN_D2); output_low(PIN_A3); output_high(PIN_A5); } void parar3() { output_low(PIN_D2); output_low(PIN_A3); output_low(PIN_A5); set_pwm1_duty(0); } void main() { enable_interrupts(global); //Interrupcion Global enable_interrupts(int_ext); ext_int_edge(L_to_H); setup_timer_2(T2_DIV_BY_16, 255, 1); //Pre=1 Periodo=255 Pos=1 setup_ccp1(CCP_PWM); //Configuracion PWM 89 output_low(pin_C2); puts("Programa principal"); output_high(PIN_A0); delay_ms(150); output_low(PIN_A0); output_low(PIN_B7); output_low(PIN_B6); output_low(PIN_B5); output_low(PIN_B4); output_low(PIN_A1); output_low(PIN_A2); output_low(PIN_A3); output_low(PIN_A5); output_low(PIN_D2); //Articulacion 3 Sensor activar output_low(PIN_D3); //Articulacion 2 Senson activar output_low(PIN_C5); //Articulacion 1 Sensor activar while(true){ get_string(letra1,6); //Obtener un String del puerto serial letra=letra1[0]; switch(letra) { case 'I': horario1(); set_pwm1_duty(800); while(contador<=valor){} parar1(); printf("contador %Lu\n",contador); contador=0; putc('s'); break; case 'O': anti_horario1(); set_pwm1_duty(800); while(contador<=valor){} parar1(); printf("contador %Lu\n",contador); contador=0; putc('s'); break; case 'J': printf("Velocidad\n"); 90 get_string(letra1,6); velocidad_h=atol(letra1); printf("Velocidad_i %Lu\n",velocidad_h); horario2(); while(contador<=valor){ set_pwm1_duty(velocidad_h); velocidad_h=velocidad_h-8; printf("Velocidad %Lu\n",velocidad_h); } parar2(); printf("contador %Lu\n",contador); contador=0; putc('s'); break; case 'K': printf("Velocidad\n"); get_string(letra1,6); velocidad_h=atol(letra1); printf("Velocidad_i %Lu\n",velocidad_h); anti_horario2(); while(contador<=valor){ set_pwm1_duty(velocidad_h); velocidad_h=velocidad_h-7; printf("contador %Lu\n",velocidad_h); } parar2(); printf("contador %Lu\n",contador); contador=0; putc('s'); break; case 'B': horario3(); set_pwm1_duty(600); while(contador<=valor){} parar3(); printf("contador %Lu\n",contador); contador=0; putc('s'); break; case 'N': anti_horario3(); set_pwm1_duty(500); while(contador<=valor){} parar3(); printf("contador %Lu\n",contador); contador=0; putc('s'); 91 break; } valor=atol(letra1); } }