Desarrollo de dispositivo de bajo coste para la medida de oscilaciones
angulares en ejes
Titulación: Ingeniería Industrial Alumno/a: Juan Bermúdez Rodríguez Director/a/s: Jose Luis Aguirre Martínez
Cartagena, 24 de Agosto de 2016
Índice general
1. Introducción 7
1.1. Concepto de mantenimiento. Mantenimiento predictivo . . . 7
1.1.1. Tipos de mantenimiento . . . 7
1.1.2. Mantenimiento predictivo . . . 8
1.1.3. Ventajas del mantenimiento predictivo . . . 9
1.1.4. Aplicaciones del mantenimiento predictivo por técnica predictiva . . . 9
1.2. Punto de partida y objetivos . . . 14
1.2.1. Antecedentes de la medida angular instantánea de una máquina rotativa . . 14
1.2.2. Objetivos del proyecto . . . 15
1.3. Esquema de memoria. Desarrollo del proyecto . . . 16
2. Uso del lenguaje Arduino y la placa microcontroladora ChipkitMax32 18 2.1. Arduino y ChipKit Max32 . . . 18
2.1.1. ¾Por qué Arduino? . . . 19
2.1.2. ¾Por qué ChipKitMax 32? . . . 20
2.2. Detalles de la placa ChipKit Max32 . . . 20
2.3. Software de Programación . . . 22
2.3.1. Librerías y estructura a bajo nivel . . . 23
2.4. Principios de la programación en MPIDE . . . 26
2.4.1. Programa . . . 26
2.4.2. setup() . . . 27
2.4.3. loop() . . . 27
2.4.4. Funciones . . . 28
2.4.5. Entre llaves . . . 28
2.4.6. ; Punto y coma . . . 29
2.4.7. /*. . . */ Bloque de comentarios . . . 29
2.4.8. // Línea de comentarios . . . 29
2.4.9. Ejemplo de un programa . . . 30
2.5. Problemas del lenguaje de programación . . . 30
2.5.1. Velocidad de lectura y escritura de datos . . . 30
2.5.2. Problema de la estructura tradicional de un programa . . . 31
2.5.3. Timers . . . 33
2.5.4. Uso de interrupciones . . . 33
2.5.5. Programa básico con interrupciones . . . 34
2.5.6. Resultados obtenidos y observaciones . . . 37
2.6. Programa avanzado de MPIDE . . . 37
2.6.1. Cambio del preescalado . . . 37
2.6.2. Input capture o Modo de Captura en el módulo CCP . . . 38
2.6.3. Resumen del programa a desarrollar . . . 38
2.6.4. Programa desarrollado . . . 39
2.6.5. Conclusiones y resultados . . . 41
3. Arduino 43 3.1. Esquema básico . . . 43
3.1.1. Paso de información y esquema para el uso de puertos . . . 45
3.1.2. Paso de información y esquema para el uso del módulo de captura . . . 46
3.2. Herramientas necesarias para la creación del programa . . . 48
3.3. Uso de interrupciones . . . 48
3.4. Lectura de datos . . . 50
3.4.1. Lectura de puertos . . . 50
3.5. Input Capture . . . 53
3.5.1. Ventajas e inconvenientes del Input Capture . . . 54
3.6. Cambio del preescalado de los timers . . . 55
3.7. Cambio en la velocidad de envío de datos a través del puerto serie. . . 57
3.7.1. ¾Qué es el puerto serie? . . . 57
3.7.2. Arduino y el puerto serie . . . 58
3.7.3. Conexión del Arduino con el ordenador . . . 59
3.7.4. Líneas de código para el uso del puerto serie. . . 60
3.8. Resumen de requisitos necesarios por la placa Arduino . . . 61
4. Elección de la placa Arduino 63 4.1. Tipos de Arduino, detalles y diferencias . . . 63
4.1.1. Duemilanove . . . 63
4.1.2. Arduino MEGA . . . 64
4.1.3. Nano . . . 65
4.1.4. Due . . . 66
4.2. Placas elegidas para su comparación . . . 68
4.3. Comparativa del hardware . . . 68
4.3.1. Arduino Due . . . 68
4.3.2. Arduino Mega . . . 70
4.3.3. Conclusión en cuanto a hardware . . . 71
4.4. Uso de interrupciones por timer y de la instrucción input capture . . . 71
4.4.1. Arduino Mega . . . 71
4.4.2. Arduino Due . . . 72
4.4.3. Conclusiones en el uso de interrupciones . . . 74
4.5. Posibilidad del uso de lectura de puertos . . . 74
4.5.1. Puertos Placa Due . . . 74
4.5.2. Puertos Placa Mega . . . 76
4.6. Posibilidad de cambio de preescalado . . . 77
4.7. Posibilidad de cambio en la velocidad de transimision del puerto serie . . . 77
4.8. Conclusión y elección de la placa . . . 78
5. Programa Arduino Mega 79
5.1. Programa Base . . . 79
5.1.1. Programa utilizado como base del proyecto . . . 80
5.1.2. Líneas de código del programa base . . . 81
5.1.3. Código antes del setup . . . 83
5.1.4. ISR del timer5 . . . 84
5.1.5. Setup . . . 85
5.1.6. Loop . . . 85
5.1.7. Conclusión del programa . . . 85
5.2. Uso de los registros de los timer . . . 86
5.2.1. Tipos de timers . . . 86
5.3. Registros timers . . . 87
5.3.1. TCNT . . . 87
5.3.2. TCCR . . . 88
5.3.3. ICR1 . . . 89
5.3.4. TIMSK y TIFR . . . 90
5.4. Cambio de velocidad del puerto serie . . . 90
5.4.1. Nuevo monitor serie . . . 92
5.5. Solución usando las instrucciones PORT . . . 93
5.5.1. Código usando dos puertos para medida de una velocidad . . . 94
5.6. Solución usando el módulo de captura . . . 96
5.6.1. Código usando el módulo de captura para medida de una velocidad . . . . 96
6. Pruebas en un entorno controlado para los dos programas 99 6.1. Introducción . . . 99
6.2. Programas de apoyo . . . 100
6.2.1. Programa para emulación de DISCON 2 . . . 101
6.2.2. Programa para emulación de la señal del encoder . . . 103
6.3. Pruebas para el programa con emulación de DISCON2 . . . 104
6.3.1. Prueba de funcionamiento para los puertos A y C . . . 104
6.3.2. Pruebas de velocidades para puertos A y C . . . 107
6.3.3. Prueba de funcionamiento del programa con puertos F y K . . . 111
6.4. Pruebas de velocidad para los puertos F y K . . . 114
6.4.1. Prueba a velocidad de 10KHz . . . 114
6.4.2. Prueba a velocidad de 100KHz . . . 114
6.4.3. Prueba a velocidad de 1MHz . . . 115
6.5. Programa con las dos señales y todos los puertos . . . 116
6.5.1. Código del programa de dos interrupciones simultaneas . . . 116
6.5.2. Conexión entre placas . . . 118
6.5.3. Prueba de funcionamiento . . . 119
6.5.4. Clonclusión del programa creado . . . 124
6.6. Solución mediante el uso de dos placas Arduino Mega . . . 125
6.6.1. Código, conexiones entre placas y medidas efectuadas. . . 126
6.6.2. Funcionamiento del programa . . . 131
6.7. Puebas para el programa con emulación de las señales del encoder . . . 132
6.7.1. Prueba del programa base para medida de pulsos de onda cuadrada . . . . 133
6.8. Programa elegido y camino a seguir . . . 136
7. Python 138
7.1. Introducción . . . 138
7.2. Python . . . 139
7.2.1. Instalación de librerías . . . 140
7.3. Programa receptor de datos . . . 143
7.3.1. Comunicación serial con las placas . . . 143
7.3.2. Encontrar las placas . . . 145
7.3.3. Guardado de datos en un chero . . . 146
7.3.4. Finalización de la comunicación serial . . . 148
7.3.5. Script completo, pruebas de funcionamiento y modicaciones . . . 148
7.3.6. Modicaciones efectuadas para alcanzar la latencia estable del programa ante un gran número de medias . . . 151
7.4. Programa de procesamiento de datos recibidos . . . 158
7.4.1. Composición de los dos puertos . . . 158
7.4.2. Resta de datos . . . 164
7.4.3. Cálculo de las velocidades instantaneas en cada punto . . . 165
7.4.4. Resumen y esquema del programa de procesamiento de datos . . . 168
7.5. Programa para gracar los datos procesados . . . 169
7.5.1. Código para la gráca de las velocidades instantáneas . . . 170
7.5.2. Acciones realizadas por el programa . . . 171
7.5.3. Resultados mostrados . . . 171
7.6. Creación de carpeta para resultados y manipulación de los archivos creados . . . . 174
7.6.1. Creación de una carpeta y un nombre de manera automática . . . 175
7.6.2. Manipulación de los archivos . . . 176
7.6.3. Ejemplo del script . . . 176
7.6.4. Valores promediados . . . 178
7.7. Prototipo de programa para pruebas de campo . . . 180
8. Pruebas de campo 184 8.1. Introducción y nes buscados . . . 184
8.1.1. Fines buscados . . . 184
8.2. Descripción del hardware disponible . . . 185
8.3. Pruebas realizadas . . . 189
8.3.1. Prueba de funcionamiento . . . 189
8.3.2. Prueba con canal 2 . . . 193
8.3.3. Prueba con una placa Mega diferente . . . 194
8.3.4. Prueba con cambio del Baud Rate . . . 195
8.3.5. Prueba con desdoblamiento de datos . . . 197
8.3.6. Prueba con una placa codicadora de señal diferente . . . 198
8.4. Resumen de los resultados y comentarios . . . 200
9. Conclusiones 203 9.1. Comentarios nales y recomendaciones de mejora . . . 204
9.1.1. Recomendaciones respecto a hardware . . . 204
9.1.2. Recomendaciones respecto a software . . . 205
A. Esquemático Max32 207
B. Esquemático Arduino Mega 212
C. Esquemático Arduino Due 213
D. Documentación Placa Discon 214
D.1. Esquemático . . . 214 D.2. Disposición y cableado de la placa . . . 215
E. Especicaciones Micro-Encoder 217
Capítulo 1
Introducción
1.1. Concepto de mantenimiento. Mantenimiento predictivo
El Mantenimiento industrial en nuestros días necesita de una serie de instrumentos para poder innovarse y abaratar costes. Esos instrumentos se convierten a veces en auténticas políticas del buen hacer para la industria que conminan a la misma a reconsiderar todos sus estamentos.
Es preciso disponer de un sistema de mejora continua para tratar de distanciarse de los com- petidores y así mejorar nuestra posición en el mercado. En cuanto a Mantenimiento se reere, las únicas estrategias válidas hoy en día son las encaminadas tanto a aumentar la disponibilidad y ecacia de los equipos productivos, como a reducir los costes de Mantenimiento, siempre dentro del marco de la seguridad y el medio ambiente.
Un buen mantenimiento predictivo ayuda a garantizar la disponibilidad y ecacia requerida de los equipos e instalaciones, asegurando la duración de su vida útil y minimizando los costes de Mantenimiento, dentro del marco de la seguridad y el medio ambiente.
Es obvio que el mantenimiento no solamente tiene una rama o vertiente, ya que si lo que se busca es la costante mejora esta se puede realizar en diversas áreas, con el n de que todas ellas se complementen ayudando a aumentar la vida útil de las máquinas.
1.1.1. Tipos de mantenimiento
Cada equipo de la planta cuenta con características importantes a la hora de valorar su estrate- gia de mantenimiento óptima. Dicha estrategia estará orientada a obtener la mejor disponibilidad, calidad y seguridad operativa del proceso y deberá considerar los siguientes factores:
Criticidad en el Proceso.
Características Constructivas.
Condiciones Operativas.
Y en función de cada uno de los factores anteriormente expuestos se pondrá en marcha un plan de mantemiento.
Los más importantes aparecen a continuación:
Mantenimiento correctivo.
Mantenimiento predictivo o basado en la condición.
Mantenimiento proactivo o ingeniaría de mantenimiento.
El proyecto que se desarrollará pertenece al segundo tipo, es decir, al mantenimiento predictivo, por lo tanto solamente se abordará este en particular de ahora en adelante.
1.1.2. Mantenimiento predictivo
El Mantenimiento Predictivo consiste en inspeccionar los equipos a intervalos regulares y tomar acción para prevenir las fallas o evitar las consecuencias de las mismas según condición.
Incluye tanto las inspecciones objetivas (con instrumentos) y subjetivas (con los sentidos), como la reparación del defecto (falla potencial). Es un conjunto de técnicas instrumentadas de medida y análisis de variables para caracterizar en términos de fallos potenciales la condición operativa de los equipos productivos. Su misión principal es articular un único sistema de gestión global de planta capaz de integrar operación y mantenimiento bajo la misma óptica y por otra parte optimizar la
abilidad y disponibilidad de equipos al mínimo costo.
En resumen el mantenimiento predictivo consiste en la serie de acciones que se toman y las técnicas que se aplican con el objetivo de detectar posibles fallos y defectos de maquinaria en las etapas incipientes para evitar que estos fallos se maniesten en uno más grande durante su fun- cionamiento, evitando que ocasionen paros de emergencia y tiempos muertos, causando impacto
nanciero negativo.
Se considerará a un mantenimiento como predictivo si cumple las siguientes cualidades:
Desde un punto de vista técnico
La medida no debe ser intrusiva, es decir, que se realice con el equipo en la condición normal de funcionamiento.
El resultado de las medidas debe poder ser expresado en unidades físicas, o tambien en índices adimensionales correlacionados.
La variable medida ofrezca una buena repetibilidad. Este concepto es muy importante, ya que el mantenimiento se debe realizar de una manera periódica y por ello debe ser fácilmente llevado a cabo.
La variable predictiva pueda ser analizada y/o parametrizada para que represente algún modo típico de fallo del equipo, es decir, que se pueda tener una capacidad de diagnóstico.
Desde un punto de vista organizativo
La medida de las variables se realice de forma periódica en modo rutina.
El sistema permita la coordinación entre el servicio de vericación predictiva y la planicación del mantenimiento.
1.1.3. Ventajas del mantenimiento predictivo
Los fallos se detectan en sus etapas iniciales por lo que se cuenta con suciente tiempo para hacer la planicación y programación de las acciones correctivas (mantenimiento correctivo) en paradas programadas y bajo condiciones que minimicen los tiempos muertos y el efecto negativo sobre la producción y que en general garantice una mejor calidad en las reparaciones.
Permite seguir la evolución de un defecto en el tiempo. Como se ha comentado antes, todos los defectos que tratan de encontrarse con este tipo de mantenimiento son nacientes o incipientes.
Por lo tanto puede que un defecto sea detectado, pero que no repercuta en la vida útil de la máquina hasta después de un periodo de tiempo en el cual, este defecto supere unos límites de seguridad establecidos. Por lo tanto se puede seguir la evolución de este defecto y programar la parada en el momento más adecuado.
La mayoría de las técnicas de detección del mantenimiento predictivo son en mayor parte técnicas on-condition, esto quiere decir que las inspecciones pueden ser realizadas con la maquinaria en funcionamiento a pleno rendimiento o máxima velocidad.
Optimiza la gestión de personal de mantenimiento. Como se ha comentado con anterioridad las paradas de mantenimiento pueden ser programadas con anterioridad y además de ello se cuenta con una gran información sobre el tipo de defecto que los operarios van a encontrarse.
Por lo tanto se puede hacer un mejor uso por parte de RRHH para asignar solamente los medios necesarios para cada parada.
El mantenimiento predictivo es un mantenimiento pro-activo, ya que permite anticiparse a los fallos antes de que ocurran en operación y no después, como hace el mantenimiento correctivo.
1.1.4. Aplicaciones del mantenimiento predictivo por técnica predictiva
Para iniciar un mantenimiento predictivo se debe contar con datos que nos permitan conocer de un modo directo o indirecto una condición no deseable de la máquina analizada.
Un valor de temperatura, un nivel de vibración, la viscosidad del lubricante, etc, son parámetros a partir de los cuales se puede supervisar el estado de las máquinas de una planta industrial.
El mantenimiento predictivo, modulador de las acciones correctivas y preventivas, necesita nu- trirse de información procedente de los sistemas de monitorización de las plantas.
En las últimas décadas se han producido importantes avances en este campo que ya se aplica con éxito en las industrias más productivas.
Las técnicas predictivas más relevantes en la actualidad son:
Análisis de lubricantes.
Termografía.
Análisis de vibraciones
Analisis de motores eléctricos de inducción.
Análisis de máquinas alternativas.
Detección ultrasónica.
Descargas parciales en máquinas eléctricas.
Parámetros de supervisión de grandes máquinas eléctricas.
Aislamiento en hexaoruro
A continuación se resumirá brevemente en que consisten las mayoría de las técnicas que se han expuesto anteriormente.
Análisis de lubricantes
El análisis de aceite es una técnica simple, que realizando medidas de algunas propiedades físicas y químicas proporciona información con respecto a:
La salud del lubricante.
Contaminación del lubricante.
Desgaste de la maquinaria.
El análisis de aceite no sólo va a permitir monitorear el estado de desgaste de los equipos, de- tectar fallas incipientes, sino también establecer un Programa de Lubricación basado en Condición.
Las técnicas de análisis son muy diversas y su utilización depende de la aplicación del aceite.
A continuación se detallan las más habituales:
Espectroscopia de Emisión.
Espectroscopia de Absorción FTIR.
Ferrografía.
Recuento de partículas.
Viscosidad.
Contenido en agua.
Grado de Acidez TAN.
Figura 1.1: Análisis de lubricantes
Termografía
La termografía por infrarrojos se ha ido extendiendo durante más de 20 años desde el campo de aplicación médico y militar a otras aplicaciones de mantenimiento industrial, especialmente en equipo y aparellaje eléctrico en alta y baja tensión (líneas, subestaciones, centros de control, etc.).
La medida de temperatura sin contacto es una técnica fundamental en mantenimiento eléctrico que ha experimentado grandes cambios en los equipos e instrumentación disponibles, y que está aún en continua evolución.
Se caracteriza por su espectacularidad, facilidad de manejo y capacidad de detección de puntos calientes.
Figura 1.2: Termografía de mantenimiento eléctrico
Análisis de Vibraciones
Inicialmente, se emplearon equipos analógicos para la medida de la vibración en banda ancha, lo que hacía imposible el diagnóstico able de fallos en rodamientos y engranajes. Luego de ello, se incorporaron ltros sintonizables a la electrónica analógica, lo que incrementó enormemente la capacidad de diagnóstico, pero sin poder tratar la información de forma masiva. Desde 1984, se comenzaron a emplear equipos digitales con FFT en tiempo real y capacidad de almacenamiento (analizadores- colectores) y tratamiento en software para PC.
Figura 1.3: Medición de vibración mediante colector de datos
La información que puede procurar el análisis de vibraciones de forma exhaustiva en forma de parámetros de supervisión y grácos de diagnóstico.
Análisis de motores eléctricos de inducción
Los análisis de vibraciones pueden complementarse con análisis de corriente de alimentación y
ujo magnético de dispersión cuando se trata de diagnosticar motores eléctricos de inducción.
Figura 1.4: Análisis de defectos en motores eléctricos de inducción.
Detección ultrasónica
Existen numerosos fenómenos que van acompañados de emisión acústica por encima de las frecuencias del rango audible.
Las características de estos fenómenos ultrasónicos hacen posible la utilización de detectores de ultrasonidos en innidad de aplicaciones industriales dentro del mantenimiento:
Detección de grietas y medición de espesores por impulso eco.
Detección de fugas de uidos en conducciones, válvulas, etc.
Vericación de purgadores de vapor.
Inspección de rodamientos.
Figura 1.5: Análisis mediante ultrasonidos para detección de defectos.
Descargas parciales en maquinas eléctricas
La técnica de descargas parciales es conocida desde hace más de 30 años y va a camino de con- vertirse poco a poco en la más aplicada a los sistemas de aislamiento en media tensión, por tratarse de la única técnica que permite evaluar el aislamiento de una máquina rotativa en operación.
Los equipos de medida, inicialmente analógicos, han sufrido también una revolución para ha- cerse compatibles con todas las aplicaciones de equipos eléctricos (motores y alternadores, cables, interruptores,...), ofreciendo la siguiente información:
Parámetros de supervisión:
Descarga aparente (pC) Corriente de Fuga (nA) Grácos de Diagnóstico:
PDA (Distribución de pulsos por amplitud)
PRPD (Distribución de pulsos por amplitud y fase, o "ngerprint")
Figura 1.6: Detector de descargas parciales.
1.2. Punto de partida y objetivos
Como se ha visto en el apartado anterior existen varios métodos de mantenimiento predictivo.
El presente proyecto busca el estudio de las vibraciones existentes en ejes rotatorios.
Uno de los métodos más extendidos y ecaz en el diagnóstico predictivo para el mantenimiento es la medida de las vibraciones, así pues puede ser considerado el punto de partida de cualquier mantenimiento basado en la condición de la maquinaria.
Normalmente el estudio de las vibraciones centra su atención en las componenetes radiales y axiales de un equipo, ya que este fue el punto de partida del mantenimiento predictivo en este ámbito.
Por esta razón la medida de la vibración torsional queda relegada un segundo plano, salvo en aquellos casos donde el predominio de este fenomeno es tan grande que es necesaria su medida, tal es el caso de los cigüeñales en los motores de explosión, los ejes de las hélices de los buques y algún otro caso aislado.
La causa por la cual no se ha extendido en gran medida como otros sistemas de predicción hay que buscarlas en el hecho de que es muy compleja de llevar a cabo además del elevado coste que supone para una empresa el tener este tipo de mantenimiento por el equipo necesario.
Por lo tanto puede decirse que las condiciones de análisis de las vibraciones torsionales son severas, complejas y generalmente costosas.
La detección y medida de las vibraciones torsionales es un factor importante a tener en cuenta para un diagnóstico prematuro en el fallo de un equipo, ya que estas pueden evolucionar de ma- nera rápida y causar defectos de fatiga en el material. Una proporción de los problemas propios que tienen los Equipos Dinámicos Rotativos vienen dados por vibraciones torsionales, provocando aparición de inestabilidades cíclicas en el régimen de velocidad de la máquina llegando a ser más perjudiciales que las vibraciones por exión.
Los problemas descritos hacen pues, que sea necesario contar con medios ecaces para la de- tección y medida de estos defectos, ya que si se encuentran estos fallos en forma incipiente puede controlarse la velocidad con la que se propaga y evitar problemas por fatiga.
El presente proyecto tratara de abordar el problema de la obtención de las medidas necesarias y su posterior procesado para el análisis de las vibraciones torsionales en un eje.
1.2.1. Antecedentes de la medida angular instantánea de una máquina rotativa
Este proyecto busca el estudio de las medidas de las vibraciones torsionales que experimenta un eje rotatorio mediante la medida de las velocidades intantáneas, por ello, a partir de ahora se centrará toda la atención en este tipo de instrumentación.
A continuación se explicarán algunos ejemplos de los dispositivos existentes en la actualidad para comprender mejor algunas de sus características y dar un pase al desarrollo que se va a llevar
a cabo.
Dispositivos existentes en la actualidad
En la actualidad existen multiples opciones si lo que se pretende es medir la velocidad angular instantánea de una máquina.Cada una de las técnicas tendrá sus pros y sus contras. Generalmente se tendrá que hacer un balance entre la presición que sea necesaria y la inversión con la que se cuenta.
Un dato que no se puede olvidar es que la mayoría de los sistemas de medida de vibración torsional requieren, con mayor o menor importancia, modicaciones sobre la maquinaria en cues- tión para poder llevarse a cabo, así pues, este también debe ser un punto a tener en cuenta en la elección del método a utilizar.
Los principales transductores de medida de variación angular que actualmente se utilizan son:
Interferómetro laser.
Codicadores de pulso.
Dispositivos resistivos.
Dispositivos inductivos.
Dispositivos capacitivos.
De los tipos de transductores mencionados los dos primeros son los más adecuados si lo que se pretende medir es la velocidad en máquinas industriales en general, ya que son los que presentan mejores respuestas dinámicas. Los tres restantes son más adecuados para la medida de la posición o de desplazamiento angular cuando los movimientos de giro se realizan con velocidades y acelera- ciones bajas.
Se describe brevemente el método de interferometria laser, ya que es el más preciso y que pre- senta mejores cualidades. El métidi basado en codicadores de pulso se describirá más adelante puesto que es la base de este proyecto.
Este se basa en el cambio de longitud de onda que experimenta un rayo láser cuando se hace incidir sobre una supercie en movimiento (Efecto Doppler).
Con esta técnica no solo es posible medir velocidades de giro sino también desplazamientos lineales: no solo en ejes o supercies totalmente lisas sino también en objetos con ciertas irregula- ridades en su forma.
1.2.2. Objetivos del proyecto
En este proyecto se busca estudiar el funcionamiento y desarrollo de los sistemas de medida de velocidad instantánea de giro para maquinas rotativas de uso general.
El proyecto queda dividido en dos partes bien diferenciadas:
Figura 1.7: Interferometro Laser
1. Por un lado se hará uso de un placa micontroladora con el n de recibir datos provinientes de una placa codicadora de velocidad. Esta placa debe recibir las señales y en un caso procesarlas si es posible, o por lo menos enviar la información a un PC para su posterior procesamiento.
2. Por otro lado, en el caso de que la placa micontroladora no sea capaz de realizar la toma de datos además del procesamiento de estos, se la relegará a solamente la recepción de la información y al envío a un PC, en el cual, mediante un lenguaje de programación adecuado se contruirá un script, el cual permita guardar toda la información que pueda ser relevante y mostrar al usuario de una manera gráca los datos que se han obtenido del procesamiento.
Este estudio partirá de una descripción detallada del sistema de medida de velocidad, donde las características generales que denen este tipo de medidas serán expuestas.
Debido a la escasez de proyectos similares se describirán distintos métodos que a priori pueden ser válidos para el presente proyecto, además se pondrán a prueba con el n de detallar si los resultados son válidos y si la posible solución puede llevarse a cabo. Se descartarán aquellas que no cumplan las espectativas y se detallarán tanto las ventajas como las desventajas de cada elección tomada.
1.3. Esquema de memoria. Desarrollo del proyecto
Para presentar de la forma más comprensiva el proyecto, la memoria se ha dividido en los siguientes capítulos:
Capítulo 1: Introducción al mantenimiento y mantenimieto predictivo.Descripción de las distintas opciones que existen en la actualidad y los objetivos del proyecto.
Capítulo 2: Uso del lenguaje de programación Arduino y de la placa Chipkit Max32. Los programas llevados a cabo con dicha placa y los resultados obtenidos.
Capítulo 3: Exposición de los caminos que pueden seguirse para el desarrollo del proyecto, además de las herramientas utilizadas respectivamente en cada uno de ellos.
Capítulo 4: Detalles de las placas Arduino candidatas, así como la posibilidad de incorporar las herramientas necesarias para el buen funcionamiento del proyecto. Por último se elegirá la placa sobre la cual se trabajará denitivamente.
Capítulo 5: Programa base, herramientas de uso de los registros en lenguaje AVR y pro- puesta de código de las dos soluciones tomadas.
Capítulo 6: Pruebas del programa desarrollado en el capítulo anterior mediante simulacio- nes.
Capítulo 7: Explicación del lenguaje Python, desarrollo y pruebas del programa de pospro- cesamiento de datos. Muestra de resultados de forma gráca.
Capítulo 8: Pruebas en entorno real de los programas Arduino+Python.
Capítulo 9: Conclusiones del proyecto.
Capítulo 2
Uso del lenguaje Arduino y la placa microcontroladora ChipkitMax32
2.1. Arduino y ChipKit Max32
Arduino es una plataforma de hardware libre, basada en una placa con un microcontrolador y un entorno de desarrollo, diseñada para facilitar el uso de la electrónica en proyectos multidisciplinares.
El hardware consiste en una placa con un microcontrolador Atmel o AVR y puertos de entra- da/salida.
Los microcontroladores más usados son el Atmega168, Atmega328, Atmega1280, y Atmega8 por su sencillez y bajo coste que permiten el desarrollo de múltiples diseños. Por otro lado el software consiste en un entorno de desarrollo que implementa el lenguaje de programación Proces- sing/Wiring y el cargador de arranque que es ejecutado en la placa.
Se programa en el ordenador para que la placa controle los componentes electrónicos.
Desde octubre de 2012, Arduino se utiliza también con microcontroladoras CortexM3 de ARM de 32 bits, que coexistirán con las más limitadas, pero también económicas AVR de 8 bits. ARM y AVR no son plataformas compatibles a nivel binario, pero se pueden programar con el mismo IDE de Arduino y hacerse programas que compilen sin cambios en las dos plataformas. Eso sí, las microcontroladoras CortexM3 usan 3,3V, a diferencia de la mayoría de las placas con AVR, que generalmente usan 5V.
Es necesario hacer hincapié en el punto de que los microprocesadores ARM y AVR no son compatibles a nivel binario, ya que esto puede provocar problemas a la hora de buscar bibliografía a un nivel de programación bajo. Se volverá sobre este punto en momentos de programación en los que sea necesario.
Arduino se puede utilizar para desarrollar objetos interactivos autónomos o puede ser conectado a software tal como Adobe Flash,Processing, Max/MSP, Pure Data. Las placas se pueden montar a mano o adquirirse. El entorno de desarrollo integrado libre se puede descargar gratuitamente.
Arduino puede tomar información del entorno a través de sus entradas analógicas y digita- les, puede controlar luces, motores y otros actuadores. El microcontrolador en la placa Arduino se programa mediante el lenguaje de programación Arduino (basado en Wiring) y el entorno de desarrollo Arduino (basado en Processing). Los proyectos hechos con Arduino pueden ejecutarse sin necesidad de conectar a un ordenador.
También cuenta con su propio software que se puede descargar de su página ocial que ya incluye los drivers de todas las tarjetas disponibles lo que hace más fácil la carga de códigos desde el ordenador
2.1.1. ¾Por qué Arduino?
Hay muchos otros microcontroladores y plataformas con microcontroladores disponibles para la computación física. Parallax Basic Stamp, BX-24 de Netmedia, Phidgets, Handyboard del MIT, y muchos otros ofrecen funcionalidades similares. Todas estas herramientas organizan el compli- cado trabajo de programar un microcontrolador en paquetes fáciles de usar. Arduino, además de simplicar el proceso de trabajar con microcontroladores, ofrece algunas ventajas respecto a otros sistemas a profesores, estudiantes y amateurs:
Asequible - Las placas Arduino son más asequibles comparadas con otras plataformas de microcontroladores. La versión más cara de un modulo de Arduino puede ser montada a mano, e incluso ya montada cuesta bastante menos de 60 euros.
Multi-Plataforma - El software de Arduino funciona en los sistemas operativos Windows, Macintosh OSX y Linux. La mayoría de los entornos para microcontroladores están limitados a Windows.
Entorno de programación simple y directo - El entorno de programación de Arduino es fácil de usar para principiantes y lo sucientemente exible para los usuarios avanzados. Pensando en los profesores, Arduino está basado en el entorno de programación de Procesing con lo que el estudiante que aprenda a programar en este entorno se sentirá familiarizado con el entorno de desarrollo Arduino.
Software ampliable y de código abierto- El software Arduino esta publicado bajo una licencia libre y preparado para ser ampliado por programadores experimentados. El lenguaje puede ampliarse a través de librerías de C++, y si se está interesado en profundizar en los detalles técnicos, se puede dar el salto a la programación en el lenguaje AVR C en el que está basado.
De igual modo se puede añadir directamente código en AVR C en tus programas si así lo deseas.
Hardware ampliable y de Código abierto - Arduino está basado en los microcontroladores ATMEGA168, ATMEGA328 y ATMEGA1280. Los planos de los módulos están publicados bajo licencia Creative Commons, por lo que diseñadores de circuitos con experiencia pueden hacer su propia versión del módulo, ampliándolo u optimizándolo. Incluso usuarios relativa- mente inexpertos pueden construir la versión para placa de desarrollo para entender cómo funciona y ahorrar algo de dinero.
2.1.2. ¾Por qué ChipKitMax 32?
Como se ha visto hasta el momento Arduino es la conjunción de un microcontrolador de bajo precio y un IDE simplicado para que la tarea de la programación sea mucho más fácil para todo aquel que no esté familiarizado, entonces queda muy clara una pregunta.
¾Por qué elegir otra placa que no es Arduino para el proyecto?.
La respuesta viene dada por dos razones fundamentales.
1. La placa Digilent es compatible con el lenguaje de programación Arduino en su totalidad según el fabricante, por lo tanto, se pueden utilizar las mismas líneas de código para crear los mismos proyectos. Esto en sí no es una ventaja, pero queda complementado por la segunda razón.
2. La placa Max32 tiene un precio similar a la placa Arduino MEGA, pero tiene la peculiaridad de que monta un procesador de 32 bits en lugar de uno de 8 bits. Por lo tanto hace que sea mucho más potente.
El hecho de que una empresa pueda competir a un mismo rango de precios ofreciendo estructura de programación superior es muy importante para el proyecto que se va a desarrollar, ya que lo que se pretende es tomar medidas de velocidades instantaneas de puntos de un eje rotativo, para este aspecto prima la velocidad de procesamiento sobre cualquier otra cualidad.
El reloj interno del PIC32 funciona a 80MHz, mientras que el procesador Atmel tiene una velo- cidad de 16MHz, lo cual hace que sea signicativamente menor y por lo tanto nos pone a ChipKit Max32 como una opción 'a priori' más viable.
A lo largo de los ensayos tendremos que ver si las herramientas con las que cuenta esta placa nos permiten llegar a nuestro cometido de una forma correcta.
2.2. Detalles de la placa ChipKit Max32
La ChipKit Max32 es una placa microcontroladora basada en el PIC32MX79F512L fabricado por la empresa Microchip, se engloba en la familia de los microcontroladores de 32 bit.
La Max32 tiene la misma forma que la placa Arduino Mega y es compatible con la mayoría de los shields que existen el mercado para Arduino.
Es una placa fácilmente utilizable tanto para experimentos sencillos como para los más com- plejos. Cuenta con un puerto USB para el control del puerto serie y su conexión para el uso del IDE que usará para su programación.
Las especicaciones que tiene la placa son las siguientes:
Un microcontrolador PIC32MX79F512L de MIcrochip (80MHz, 512K Flash, 128K RAM) Voltaje de operación de 3.3V
Corriente de operación de 90mA
Voltaje de entrada de 7V - 15V (recomendado) Voltaje máximo de entrada 20V
83 pins de E/S disponibles 16 entradas analógicas
rango de voltaje de entradas analógicas de 0V a 3.3V +/-18mA DC intensidad por pin
Un USB para control
Figura 2.1: Placa ChipKit Max32
Y el esquemático correspondiente al microcontrolador de la placa se muetra a continuación:
Figura 2.2: Esquemático del procesador PIC32MX79F512L
2.3. Software de Programación
La Max32 puede ser programada usando MPIDE (Multi-Platform Integrared Development En- voronment), el cual es un software de programación basado en el IDE de Arduino y modicado para dar soporte al PIC32. Todos los comandos empleados con similares a los del lenguaje Arduino, además su estructura es idéntica.
Este IDE contiene todo lo que se necesita para dar soporte en la creación de las aplicaciones que vamos a necesitar.
En un principio se nos dice que esta placa es compatible en su totalidad con Arduino, pero no hay que olvidar que mientrar Arduino monta procesadores AVR y Atmel, esta placa tiene un PIC32MX79F512L del fabricante Microchip.
Por ello pueden exitir problemas con algunas librerías (programadas para Arduino) si estas fueran necesarias o problemas a la hora de programar a bajo nivel, ya que tendríamos que utilizar los comandos especícos de Microchip y adaptarlos para nuestro programa. La búsqueda de ins- trucciones a bajo nivel es una tarea ardua, ya que normalmente no se utilizan y el código usado no es tan accesible como lo es el lenguaje Arduino o el equivalente MPIDE. Para que
Además el desarrollo de esta placa es relativamente nuevo, por ello en la actualidad no existe una bibliografía extensa sobre proyectos similares en los que poder apoyarse o librerías especícas para la placa MAX32.
La interfaz gráca de MPIDE es en muchos aspectos igual a la utilizada por el lenguaje de programación Arduino, podemos ver a continuación uno y otro y apreciar sus similitudes:
Figura 2.3: Interfaz de MPIDE
Por otro lado el entorno gráco de Arduino es el siguiente:
Figura 2.4: Interfaz de Arduino
Antes de continuar con la siguiente sección es importante volver sobre dos conceptos antes mencionados y dar una pequeña denición de ellos ya que son conciderados importantes en los desarrollos sucesivos que se verán a lo largo del proyecto.
2.3.1. Librerías y estructura a bajo nivel
Se mencionó con anterioridad que uno de los grandes problemas con los que el desarrollo del proyecto puede encontrarse es con la diferencia existente en estos dos apartados al utilizar la placa MAX32 y la información existente sobre Arduino. Pero antes de encarar ese problema conviene ver que se entiende por cada uno de estos conceptos y como es que se implementan y relacionan.
Librerías o bibliotecas
En informática, una biblioteca (del inglés library) es un conjunto de implementaciones funcio- nales, codicadas en un lenguaje de programación, que ofrece una interfaz bien denida para la funcionalidad que se invoca.
A diferencia de un programa ejecutable, el comportamiento que implementa una biblioteca no espera ser utilizada de forma autónoma (un programa sí: tiene un punto de entrada principal), sino que su n es ser utilizada por otros programas, independientes y de forma simultánea. Por otra parte, el comportamiento de una biblioteca no tiene porqué diferenciarse en demasía del que pudiera especicarse en un programa. Es más, unas bibliotecas pueden requerir de otras para fun- cionar, pues el comportamiento que denen rena, o altera, el comportamiento de la biblioteca original; o bien la hace disponible para otra tecnología o lenguaje de programación.
Las bibliotecas pueden vincularse a un programa (o a otra biblioteca) en distintos puntos del desarrollo o la ejecución, según el tipo de vínculo que se quiera establecer.
La mayoría de los sistemas operativos modernos proporcionan bibliotecas que implementan los servicios del sistema. De esta manera, estos servicios se han convertido en una "materia prima"que cualquier aplicación moderna espera que el sistema operativo ofrezca. Como tal, la mayor parte del código utilizado por las aplicaciones modernas se ofrece en estas bibliotecas.
Dicho de otra manera una biblioteca o librería es un conjunto de líneas de código agrupadas en un conjunto, las cuales tienen diversar funcionalidades dependiendo del uso que se necesite.
Este conjunto puede llamarse al inicio de un programa que se esté creando y utilizar partes de las líneas de código existentes en dicha librería, de esta manera puede reutilizarse ese código sin la necesidad de volver a escribir el código nuevamente sino que solamente habría que llamarlo en aquellos momentos en los que se concidere necesarios.
Figura 2.5: Esquema sobre el uso de librerías
Como puede verse es posible el uso de una o varias librerías, esto dependerá de las funciones que sean necesarias.
El punto importante de la compatibilidad viene dado porque la mayoría de las librerías vienen codicadas en un lenguaje de programación mucho más bajo que el utilizado normalmente por el IDE.
Es decir, que si nos encontramos trabajando con una placa Arduino MEGA, la mayoría de las librerías vendrán programadas directamente en lenguaje AVR (el propio del microprocesador), si trabajamos con un Arduino DUE, el cual es de 16 bits tendrá un procesador Cortex de ARM y las librerías disponibles tendrán que venir expresadas en lenguaje ARM.
Por lo tanto, si en el caso que se va a estudiar, el procesador de monta la placa MAX32 es un Microchip, el lenguaje de programación de las librerías no será el mismo que en las disponibles
para las placas Arduino. Habrá que buscar entonces las librerías correspondientes para dicha placa y aprender su uso, ya que las llamadas a las funciones serán diferentes en cada caso.
Este es el primer gran problema con el uso de una placa híbrida. Por otro lado, no sería grande si las librerías existentes fueran igual de extensas que para su contraparte en Arduino.
Escritura a bajo nivel
Un lenguaje de programación de características bajo nivel es aquel en el que sus instrucciones ejercen un control directo sobre el hardware y están condicionados por la estructura física de las computadoras que lo soportan. El uso de la palabra bajo en su denominación no implica que el lenguaje sea menos potente que un lenguaje de alto nivel, sino que se reere a la reducida abstrac- ción entre el lenguaje y el hardware.
Por ejemplo, se utiliza este tipo de lenguajes para programar tareas críticas de los sistemas operativos, de aplicaciones en tiempo real o controladores de dispositivos.
Por lo tanto, la programación a bajo nivel es la aplicación directa de las llamadas al hardware requerido con una función especíca. Una de las necesidades básicas del programa a desarrollar es la velocidad con la que se ejecuten las operaciónes, y en algunos casos habrá que implementar funciones o llamadas al más bajo nivel de programación posible para que los tiempos de ejecución y reacción sean los más cortos posibles.
Si estudiamos la placa MAX32 y la disposición del PIN OUT veremos lo siguiente:
Figura 2.6: Esquemático de los pines disponibles para la placa MAX32
Como puede verse se tienen en total 85 pines, de los cuales no todos son accesibles, o podrán accerderse a ellos.
Por otro lado el esquemático del microprocesador montado se muestra a continuación:
Figura 2.7: Esquemático de los pines disponibles para el microprocesador MX79F512L
Como puede verse existen 100 pines dispobibles y no 85 como se mostraban antes, esto quiere decir que muchos de ellos no tendrán acceso y no podrán ser llamados, este hecho es importante en programación a bajo nivel, ya que las llamadas se harían directamente a los pines del microproce- sador y habrá que ver si se puede acceder físicamente a ellos para poder implementar las órdenes deseadas.
2.4. Principios de la programación en MPIDE
Dado que este software está basado en Arduino, los pasos para programar a un nivel alto son comunes.
De este modo se explicará como debe de ser programado en lenguaje Arduino y esto nos será totalmente válido para MPIDE, aunque hay que tener cuidado con los comandos avanzados, ya que normalmente se reeren a los procesadores Atmel.
2.4.1. Programa
La estructura básica del lenguaje de programación de Arduino es bastante simple y se compone de al menos dos partes, más adelante se verá que para el script que se requiere es necesaria la
inclusión de otras partes. Estas dos partes necesarias, o funciones, encierran bloques que contienen declaraciones, estamentos o instrucciones.
void setup() //Primera Parte { estamentos;
}void loop() //Segunda Parte { estamentos;
}
En donde setup() es la parte encargada de recoger la conguración y loop() es la que contiene el programa que se ejecutará cíclicamente (de ahí el término loop bucle-). Ambas funciones son necesarias para que el programa trabaje.
La función de conguración (setup) debe contener la declaración de las variables. Es la primera función a ejecutar en el programa, se ejecuta sólo una vez, y se utiliza para congurar o inicializar pinMode (modo de trabajo de las E/S), conguración de la comunicación en serie y otras.
La función bucle (loop) siguiente contiene el código que se ejecutara continuamente (lectura de entradas, activación de salidas, etc) Esta función es el núcleo de todos los programas de Arduino y la que realiza la mayor parte del trabajo.
2.4.2. setup()
La función setup() se invoca una sola vez cuando el programa empieza. Se utiliza para inicializar los modos de trabajo de los pins, o el puerto serie. Debe ser incluido en un programa aunque no haya declaración que ejecutar. Así mismo se puede utilizar para establecer el estado inicial de las salidas de la placa.
void setup()
{pinMode(pin, OUTPUT); // configura el 'pin' como salida digitalWrite(pin, HIGH); // pone el `pin' en estado HIGH }
También puede servir para realizar aquellas tareas que solamente se requieran una vez, como poner algunos pines a cero. No se debe olvidar que el puerto serie será congurado en este espacio, es decir, la velocidad de transmisión de datos puede variarse en este apartado adaptándola a la necesaria.
2.4.3. loop()
Después de llamar a setup(), la función loop() hace precisamente lo que sugiere su nombre, se ejecuta de forma cíclica, lo que posibilita que el programa esté respondiendo continuamente ante los eventos que se produzcan en la placa.
void loop()
{digitalWrite(pin, HIGH); // pone en uno (on, 5v) el 'pin'
delay(1000); // espera un segundo (1000 ms)
digitalWrite(pin, LOW); // pone en cero (off, 0v.) el 'pin' delay(1000);
}
2.4.4. Funciones
Una función es un bloque de código que tiene un nombre y un conjunto de instrucciones que son ejecutadas cuando se llama a la función. Son funciones setup() y loop() de las que ya se ha hablado. Las funciones de usuario pueden ser escritas para realizar tareas repetitivas y para reducir el tamaño de un programa. Las funciones se declaran asociadas a un tipo de valor type. Este valor será el que devolverá la función, por ejemplo 'int' se utilizará cuando la función devuelve un dato numérico de tipo entero. Si la función no devuelve ningún valor entonces se colocará delante la palabra void, que signica función vacía. Después de declarar el tipo de dato que devuelve la función se debe escribir el nombre de la función y entre paréntesis se escribirán, si es necesario, los parámetros que se deben pasar a la función para que se ejecute.
type nombreFunción(parámetros) {instrucción;
}
La función siguiente devuelve un número entero, delayVal() se utiliza para poner un valor de retraso en un programa que lee una variable analógica de un potenciómetro conectado a una entrada de Arduino. Al principio se declara como una variable local, 'v' recoge el valor leído del potenciómetro que estará comprendido entre 0 y 1023, luego se divide el valor por 4 para ajustarlo a un margen comprendido entre 0 y 255, nalmente se devuelve el valor 'v' y se retornaría al programa principal. Esta función cuando se ejecuta devuelve el valor de tipo entero 'v'.
int delayVal()
{int v; // crea una variable temporal 'v'
v= analogRead(pot); // lee el valor del potenciómetro
v /= 4; // convierte 0-1023 a 0-255
return v; // devuelve el valor final
}
2.4.5. Entre llaves
Las llaves sirven para denir el principio y el nal de un bloque de instrucciones. Se utilizan para los bloques de programación setup(), loop(), if.., etc.
type funcion() {instrucciones;
}
Una llave de apertura siempre debe ir seguida de una llave de cierre , si no es así el pro- grama dará errores.
El entorno de programación de Arduino incluye una herramienta de gran utilidad para com- probar el total de llaves. Sólo tienes que hacer click en el punto de inserción de una llave abierta e inmediatamente se marca el correspondiente cierre de ese bloque (llave cerrada).
2.4.6. ; Punto y coma
El punto y coma ; se utiliza para separar instrucciones en el lenguaje de programación de Arduino. También se utiliza para separar elementos en una instrucción de tipo bucle for.
int x = 13; /* declara la variable 'x' como tipo entero de valor 13 */
Nota: Olvidaos de poner n a una línea con un punto y coma o se producirá en un error de compilación. El texto de error puede ser obvio, y se referirá a la falta de una coma, o puede que no. Si se produce un error raro y de difícil detección lo primero que debemos hacer es comprobar que los puntos y comas están colocados al nal de las instrucciones.
2.4.7. /*. . . */ Bloque de comentarios
Los bloques de comentarios, o comentarios multi-línea son áreas de texto ignorados por el programa que se utilizan para las descripciones del código o comentarios que ayudan a comprender el programa. Comienzan con / * y terminan con * / y pueden abarcar varias líneas.
/* esto es un bloque de comentario no se debe olvidar cerrar los comentarios estos deben estar equilibrados */
Debido a que los comentarios son ignorados por el compilador y no ocupan espacio en la memoria de Arduino pueden ser utilizados con generosidad. También pueden utilizarse para ço- mentar"bloques de código con el propósito de anotar informaciones para depuración y hacerlo mas comprensible para cualquiera.
Nota: Dentro de una misma línea de un bloque de comentarios NO se puede escribir otro bloque de comentarios (usando /*..*/).
2.4.8. // Línea de comentarios
Una línea de comentario empieza con // y terminan con la siguiente línea de código. Al igual que los comentarios de bloque, los de línea son ignoradas por el programa y no ocupan espacio en la memoria.
// esto es un comentario
Una línea de comentario se utiliza a menudo después de una instrucción, para proporcionar más información acerca de lo que hace ésta o para recordarla más adelante.
2.4.9. Ejemplo de un programa
A continuación se muestra el código de un pequeño programa como ejemplo.
// EL setup solamente se ejecutará una vez al inicio del programa void setup()
{// inicializamos el pin 13 como salida pinMode(13, OUTPUT);
}
// El loop se ejecuta de forma continua void loop()
{ digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Este programa hace que un led conectado a al pin 13, el cual ha sido programado como salida, parpadee con con lapso de un segundo entre encendido y apagado.
Es un código muy sencillo pero ejemplica muy bien la sencillez de esta programación.
Así pues una unión entre una placa con un procesador potente como el PIC32 y un lenguaje de programación sencillo como el MPIDE (basado en Arduino) parece una opción viable aunque con algunas complicaciones que en parte se han expuesto en las secciones anteriores y que veremos a continuación también.
2.5. Problemas del lenguaje de programación
El punto crítico de este proyecto es la velocidad de transmisión y procesamiento de datos, por lo tanto se buscarán aquellas ordenes dentro del lenguaje Arduino que sirvan para poder realizar la labor encomendada de la manera más fácil y eciente posible.
En un primer momento se tratará de solventar el problema de adquisición de datos y más adelante el de envío o almacenamiento de estos para un posterior post procesado.
2.5.1. Velocidad de lectura y escritura de datos
El lenguaje Arduino cuenta con funciones básicas para la adquisición de datos digitales como DigitalRead(); o para la escritura de los mismos en un pin como DigitalWrite().
Estas funciones nos dan un problema muy grande a la hora de ser utilizadas, ya que su tiempo de acción es demasiado largo para poder introducirlas en el programa que necesitamos, por ello estas no serán utilizadas y se tendrá que usar instrucciones más avanzadas aunque todavía estarán
incluidas dentro del lenguaje a un nivel alto.
La información referente a la duración de las intrucciones anteriormente expuestas no puede ser encontrada dentro de la propia página de Arduino o de Digilent (esta última toma como referencia todo lo que se expone en la página de Arduino). Por ello se buscó información de análisis realizados por usuarios que pusieron a prueba dichas instrucciones.
El estudio realizado fue publicado en el enlace www.billporter.info/2010/08/18/ready-set-oscillate- the-fastest-way-to-change-arduino-pins y fue realizado de la siguiente manera:
Se utilizó una placa Arduino con una velocidad de procesamiento de 16 MHz
Se puso a prueba la velocidad con la que era capaz de realizar las intrucciones pedidas y se cuanticó en ciclos de reloj necesarios. Hay que tener en cuenta que la duración de los ciclos del reloj dependerán en primer momento de la velocidad del procesador y después del preescalado que se esté utilizando, en todos los casos se supone que el preescalado no ha sido modicado.
Se comparó tres tipos diferentes de métodos para lectura de pin.
Los resultados son los siguientes:
Figura 2.8: Duración de la intrucción DigitalWrite()
Figura 2.9: Duración de la intrucción DigitalRead()
Como puede observarse la duración es de 56 y 121 ciclos respectivamente para cada instrucción.
Lo que hace totalmente inviable su uso para las necesidades requeridas.
2.5.2. Problema de la estructura tradicional de un programa
La estructura tradicional de un programa también crea un problema si lo que se pretende es crear un detector de una señal, y más aún si esta señal es extremadamente rápida.
El funcionamiento habitual en un script es el siguiente:
Se crea un loop en el cual están recogidas todas las instrucciones necesarias para el funcio- namiento deseado.
Este loop se ejecuta de manera ininterrumpida de forma secuencial.
Se podrían añadir instrucciones adicionales en el setup, pero estas solo se ejecutarían una sola vez.
Para el planteamiento del problema que puede generarse es mejor ver el gráco que se coloca a continuación:
Figura 2.10: Estructura secuencial de programación
El caso planteado es una simplicación de un problema que puede darse con la estructura como está planteada:
Un programa está ejecutando su loop y se encuentra leyendo una línea de código dada.
La señal que se debe leer entra en estado HIGH, pero como todavía no se está leyendo esa línea de código el programa no la detecta por el momento.
Puede que por un lado, la señal en estado HIGH sea detectada, pero ya existiría un retardo desde que esta se produjo hasta que es leía.
También puede darse el caso de que la señal pase del estado HIGH a un estado LOW en un periodo de tiempo menor al necesario para que sea detectada, con lo cual, esta señal simplemente no se detectaría y los datos obtenidos de esta manera estarían falseados.
Esto muestra claramente que la estructura tradicional de programación no puede ser llevada a cabo en la creación del programa necesario para el programa que se quiere generar.
Es por ello necesario una estructura en la cual se esté ejecutando el loop con las instrucciones que se crean adecuadas, pero en el momento en el que la señal que debe ser detectada el loop debe parar y el programa debe priorizar la lectura de esta señal y su guardado o envío y luego volver al loop.
Dentro de la programación de MPIDE existe lo que se conoce como interrupciones, las cuales están ligadas totalmente al uso de los timers y es lo que se verá a continuación.
2.5.3. Timers
Un timer no es mas que un contador cuya entrada está conectada al reloj del sistema. De hecho la mayoría de los timers pueden recongurarse como contadores. En este caso, en lugar de contar los pulsos del reloj cuentan lo puntos de un determinado pin.
Por defecto la señal que van a contabilizar los timers corresponde a la frecuencia del oscilador dividida por cuatro (debido al preescalado). Por lo tanto en realidad cuentan ciclos máquina, no ciclos de reloj. Con un reloj de 20 Mhz tendríamos una frecuencia de ciclos máquina de 20/4 = 5 MHz, por lo que un ciclo máquina corresponde a 0.2 usec. En principio, el contador del timer se incrementará cada 0.2 microsegundos o 5 veces en 1 microsegundo.
La mayoría de los microcontroladores tienen uno o varios timers. Serán muy útiles para medir el tiempo que ha pasado entre dos eventos, establecer tareas para ejecutarse a intervalos regulares, etc. Dependendo del modelo los PICs cuentan con un número variable de timers.
Por lo tanto, se tendrá que hacer uso de estos contadores para que las señales que se quieren en- contrar queden perfectamente registradas con la velocidad sucientemente alta como sea necesaria.
2.5.4. Uso de interrupciones
Las interrupciones por hardware se diseñaron por la necesidad de reaccionar a suciente velo- cidad en tiempos inimaginablemente cortos a los que la electrónica trabaja habitualmente.
La idea es que se denirá una función, la cual se ejecutará de forma asíncrona, sin planicación, cuando ocurra un cierto suceso electrónico.
Para denir una interrupción son necesarias tres cosas:
1. Un pin de de la placa que recibirá la señal de disparo 2. Una condición de disparo
3. Una función que se ejecutará cuando se dispare la interrupción (llamada función call back) Pin de disparo
Lo primero de todo es localizar el pin al cual se actuará de receptor de la señal de interrupción, estos son unos pines especiales, ya que están conectados internamente a los timers de los chips de las placas, es decir, cada placa tiene unos pines asignados según el número de timers que poséa y solo podremos utilizar estos.
Este es un punto importante, ya que si existen pines que están internamente ligados a determi- nados timers quiere decir que si son utilizados para esta función quedarán totalmente bloqueados y no se pondrán tocar ningún otro cometido.
Para el caso de la placa Max32 se tendrá que los timers ligados a los pines son:
Así que la placa Max32 tiene en total 5 timers, de los cuales solamente se pueden usar 4, ya que el timer0 queda reservado para todas las funciones propias de la placa y su modicación provocaría funcionamientos diferentes todas las funciones existentes.
Figura 2.11: Pins aptos para attachinterrupt
Condición de disparo
La condición de disparo puede ser variable y puede elegirse de acuerdo con las necesidades, los tipos existentes son:
LOW, La interrupción se dispara cuando el pin es LOW.
CHANGE, Se dispara cuando pase de HIGH a LOW o viceversa.
RISING, Dispara en el anco de subida (Cuando pasa de LOW a HIGH).
FALLING, Dispara en el anco de bajada (Cuando pasa de HIGH a LOW).
La condición óptima de disparo para el programa que queremos contruir es la de CHANGE, ya que se podría detectar cualquier cambio en la señal entrante y disparar nuestro call back, pero esta opción fué rechazada debido a que al introducirla en programas no funcionaba de forma adecuada.
Al indagar más información sobre el fucionamiento del microprocesador de chipkit se llegó a que la Max32 solo admitía como condición de disparo RISING o FALLING; así pues solo se utilizarán estas condiciones en los programas desarrollados para esta placa.
Función Call back
La función call back se ejecutará si la condición de disparo queda vericada. A continuación se muestra las líneas de código que se deben seguir.
Si el call back recibe el nombre de Analizar, la forma en la que será llamado es la siguiente:
attachInterrupt(interrupt, ISR, mode)
Donde interrupt es el número de la interrupción o el número del timer internamente conectado, ISR es Analizar, y mode será el modo de detección escogido para el programa. Así para la Max32 un ejemplo de uso podría ser:
attachInterrupt(0, Analizar, RISING)
Suponiendo que el pin utilizado para recibir la interrupción es el 3.
2.5.5. Programa básico con interrupciones
Para el primer programa en el que se usarán interrupciones utilizaremos conjuntamente la op- ción millis(), aunque está lejos de la velocidad a la que necesitamos capturar las interrupciones, es muy útil para una primera prueba y depuración de errores con la función attachinterrupt; de esta
manera se pudo llegar a la conclusión de que los modos CHANGE y LOW no son compatibles con la placa Max32.
El esquema del programa se muestra a continuación:
Figura 2.12: Programa con interrupciones
Las líneas de código con sus correspondientes explicaciones se muestran a continuación:
const int Pinreceptor = 3;
//utilizamos el pin 3 como el receptor de la interrupción const int numerodeEntradas = 10;
// tomaremos 10 datos de entradas volatile unsigned long microsegundos;
//variable para el cálculo entre interrupciones volatile byte ind= 0;
//valor en microsegundos de la duración entre interrupciones volatile unsigned long resultados[numerodeEntradas];
//array donde los resultados serán guardados byte i = 0;
//este es el puntero que se usará
void setup()
{
pinMode(Pinreceptor, INPUT);
//Se define el Pinreceptor como entrada Serial.begin(9600);
//Utilizamos una transmisión de datos de 9600 baudios attachInterrupt(0, analizar, FALLING);
//Se define la interrupción resultados[0];
//Se inicia el array a cero }
void loop()
//La función del loop es la de mostrar en la pantalla los //resultados en el momento que el array está lleno
{ if(ind>= numerodeEntradas)
{Serial.println("La duracion en microsegundos es:");
for(i=0; i< numerodeEntradas;i++);
{ Serial.println(resultados[i]);
} ind=0;
//Se vuelve a poner el valor de los tiempos entre interrupciones a cero } }
void analizar()
//La función de analizar es la de encontrar el tiempo entre dos //interrupciones sucesivas y guardarlo
{ if(ind<numerodeEntradas) { if(ind>0)
{ resultados[ind]=micros()-microsegundos;
}ind=ind+1;
}microsegundos=micros();
//Se guarda este valor para la siguiente comparación }
2.5.6. Resultados obtenidos y observaciones
Los resultados obtenidos fueron satisfactorios para lo que se pretendía, ya que aunque no se pudiese medir las señales a la velocidad necesaria, si que se pudieron utilizar de un modo correcto las interrupciones.
Algo que cabe destacar en este apartado es que mietras se buscaba información referente al uso de interrupciones para la placa Max32 se dieron muchos problemas debido a que toda la informa- ción que el fabricante daba de la placa estaba referida a Arduino y es el propio usuario el que debía adaptarla, lo cual es un problema para el buen desarrollo del proyecto.
Otro problema añadido es que este es el punto más bajo de programación que nos permite el lenguaje Arduino entendiendolo como tal, así que a partir de este punto las líneas de código tendrán que ser una mezcla entre lenguaje Arduino y el lenguaje del propio procesador de la placa, para de ese modo obtener las máximas prestaciones de la placa y poder aspirar a satisfacer las necesidades del proyecto, este puede resultar un punto crítico, ya que el PIC32MX79F512L es relativamente nuevo en su formato de Max32, por lo que la información necesaria es algo escasa y créa un gran conicto a la hora de su búsqueda y adaptación.
Este problema es el resultado de este híbrido entre Arduino y la programación más convencional, es posible que a un nivel más básico de programación esta placa pueda utilizarse de manera óptima en la creación y manipulación de programas, pero cuanto más bajo es el nivel necesario empiezan a aparecer serias carencias; aún así su estudio se continuará y se buscará la mejor solución posible en el caso de existir problemas.
2.6. Programa avanzado de MPIDE
En esta sección se verán algunos conceptos importantes antes de poder escribir el código nece- sario para obtener el tiempo que necesitamos entre interrupción e interrupción.
Estos conceptos son:
2.6.1. Cambio del preescalado
La mayoría de los microcontroladores tienen uno o varios timers. Serán muy útiles para medir el tiempo que ha pasado entre dos eventos, establecer tareas para ejecutarse a intervalos regulares, etc. Dependendo del modelo los PICs cuentan con un número variable de timers.
La conguración de los timers está basada en ciclos del oscilador.Un timer no es más que un contador cuya entrada está conectada al reloj del sistema. De hecho, la mayoría de los timers pueden recongurarse como contadores. En ese caso, en lugar de contar pulsos de reloj cuentan los pulsos que llegan a un determinado pin. Por defecto la señal que van a contabilizar los timers corresponde a la frecuencia del oscilador dividida por cuatro. Por lo tanto en realidad cuentan ciclos máquina, no ciclos de reloj. Con un reloj de 20 Mhz tendríamos una frecuencia de ciclos máquina de 20/4 = 5 MHz, por lo que un ciclo máquina corresponde a 0.2 usec. En el caso de la placa que nos ocupa, esta división es de 8, es lo que se conoce como preescalado.
Debido al hecho de que necesitamos una velocidad muy alta de medida, lo primero que se tendrá que hacer es cambiar este preescalado para conseguir la máxima velocidad del timer, es decir, si fuese necesario el timer debería ir a la misma velocidad que los ciclos del oscilador sin ninguna división o preescalado.
En los ensayos, se empezará haciendo uso del preescalado tal como viene por defecto, para aprender a usarlo correctamente y detectar errores ocacionados por otras líneas de código y más adelante el preescalado será cambiado poco a poco cumpliendo el cometido deseado.
2.6.2. Input capture o Modo de Captura en el módulo CCP
Como su nombre indica, este modo se usa para capturar eventos. Para la captura se precisa que un timer este corriendo. Este timer será nuestro reloj": capturar un evento será grabar la "ho- ra"(contador del timer) en que se ha producido.Por supuesto, será nuestra responsabilidad guardar dicho valor en otra variable antes de que se repita el evento y se machaque con otro valor.
Por lo tanto para poder utilizar el Input capture es imprescindible asociarle un timer especí-
co, y la velocidad máxima de este módulo vendrá dada por la velocidad del timer, así pues si el preescalado del timer asociado es menor, nuestro módulo de captura podrá realizar medidas en periodos de tiempo más pequeños.
Para la conguración del módulo de captura asociado al timer2 deberemos seguir los siguientes pasos:
Congurar el timer a usar (TMR2) en modo 16 bits, con el prescalado escogido, deniendo así la base de tiempos a usar.
Arrancar el timer (TMR2) a usar.
Poner los bits T2CCP2 y T2CCP1 (bits asociados al módulo de captura) de T2CON a 1 para seleccionar el uso de TMR2 como timer asociado a ambos módulos CCP.
Declarar el pin correspondiente como entrada.
Habilitar el módulo CCP1 en modo CAPTURE con la denición de evento que se desee.
Si vamos a usar la interrupción de CCP1, habilitarla y declararla de alta prioridad (aconse- jable pues no queremos "saltarnosün evento).
Así pues el módulo de captura nos servirá para guardar el tiempo en el que se producza cada interrupción, con una velocidad tan alta como se desée, ya que esta depende del timer asociado y como se ha visto el preescalado de los timers se puede cambiar a conveniencia.
2.6.3. Resumen del programa a desarrollar
El programa a desarrollar usará los conceptos vistos hasta el momento:
Se pondrán las líneas de código necesarias para el cambio de preescalado.
Se añadirá una señal periódica cada 500ms de salida, esta será usada como interrupción en un primer momento para comprobar que el módulo de captura funciona correctamente.
Existirán dos valores (actual y anterior), en los cuales se guardarán los tiempos capturados por el módulo de captura, y su resta será el tiempo que ha pasado entre interrupciones.
Se creará un array donde estos valores de tiempo entre interrupciones serán guardados y posteriormente se enviarán al ordenador para su posterior procesamiento.
La conguración del módulo de captura se realizará como se comentó con anterioridad.
Para la detección de errores en algunos puntos se han puesto mensajes que deben aparecer en pantalla si el programa ha llegado a dicha línea, estos son: çomprobado boton.enel caso de que el programa arranque correctamente, ya que se ha puesto un botón conectado al pin 35, el cual inicializa correctamente la captura y el otro mensaje es "HOLA", este debería salir cuando la transmisión de los resultados está a punto de darse.
2.6.4. Programa desarrollado
A continuación se muestra las líneas de código que han sido generadas para el programa que se pretende crear, este es:
#include <plib.h>
#define FOSC 80E6 //frecuencia del oscilador de la placa
#define PB_DIV 8 //división a efectuar para obtener el preescalado
#define PRESCALE 1 //número del preescalado
#define MSEC 10E-3 //constante para que la variable este en milisegundos
#define T2_TICK (500 * MSEC * FOSC)/(PB_DIV * PRESCALE) // cada 500 ms el timer da una interrupción
#define muestras 1000 //tomaremos 1000 muestras
#define DEBUG 1
volatile unsigned int actual=0;
//tiempo actual de medida
volatile unsigned int anterior=0;
//tiempo anterior de medida volatile int resta=0;
//resta de los dos tiempos byte flagcap=0;
//bandera para la captura de datos volatile int array[muestras]={0};
//array para el almacenamiento de las muestras volatile int i=0;
//puntero del array