UNIVERSIDAD DE CASTILLA-LA MANCHA ESCUELA SUPERIOR DE INFORMÁTICA
GRADO EN INGENIERÍA INFORMÁTICA
TRABAJO FIN DE GRADO
Diseño e implementación de prototipo Hardware/Software para la automatización de procesos industriales en la Harinera Castellana José Antonio de la Torre las Heras
Julio, 2016
D ISEÑO E IMPLEMENTACIÓN DE PROTOTIPO H ARDWARE /S OFTWARE PARA LA AUTOMATIZACIÓN DE PROCESOS INDUSTRIALES EN LA H ARINERA C ASTELLANA
Escuela Superior de Informática
UNIVERSIDAD DE CASTILLA-LA MANCHA ESCUELA SUPERIOR DE INFORMÁTICA Tecnologías y Sistemas de Información TECNOLOGÍA ESPECÍFICA DE INGENIERÍA DE COMPUTADORES
TRABAJO FIN DE GRADO
Diseño e implementación de prototipo Hardware/Software para la automatización de procesos industriales en la Harinera Castellana
Autor: José Antonio de la Torre las Heras Director: Julio Daniel Dondo Gazzano Julio, 2016
José Antonio de la Torre las Heras Ciudad Real – Spain E-mail:
[email protected] Teléfono: 647904870 c 2016 José Antonio de la Torre las Heras
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". Se permite la copia, distribución y/o modificación de este documento bajo los términos de la Licencia de Documentación Libre GNU, versión 1.3 o cualquier versión posterior publicada por la Free Software Foundation; sin secciones invariantes. Una copia de esta licencia esta incluida en el apéndice titulado «GNU Free Documentation License». Muchos de los nombres usados por las compañías para diferenciar sus productos y servicios son reclamados como marcas registradas. Allí donde estos nombres aparezcan en este documento, y cuando el autor haya sido informado de esas marcas registradas, los nombres estarán escritos en mayúsculas o como nombres propios.
i
TRIBUNAL:
Presidente: Vocal: Secretario:
FECHA DE DEFENSA:
CALIFICACIÓN:
PRESIDENTE
Fdo.:
VOCAL
SECRETARIO
Fdo.:
Fdo.:
iii
Resumen La industria, al igual que el ser humano ha ido evolucionando con el paso de los tiempos. Desde la primera revolución industrial, la industria no ha parado de innovar en todos los aspectos. La globalización, por otro lado, ha obligado a las empresas a adoptar otros modelos económicos y estratégicos en sus modelos de negocio. Actualmente nos encontramos ante la cuarta revolución industrial que promete diversas mejoras en muchos planos mediante sistemas ciber-físicos, industria y productos inteligentes, Internet of Things (I OT), hiperconectividad y big data. En este Trabajo Fin de Grado (TFG) se tratará de aplicar algunas de las filosofías de la última revolución industrial (Industria 4.0) a un prototipo cuyo objetivo principal será la automatización de uno de los procesos industriales de la «Harinera Castellana». La elaboración de este prototipo requiere de la colaboración de diferentes partes, estas son: software, hardware y software de gestión. En este documento se describirá cómo se ha implementado cada una de estas partes. Durante todo el documento se hará referencia a las restricciones en cuanto a coste y fiabilidad, esto será un reto durante todo el proyecto debido a que el prototipo se basará en Arduino (bajo coste) el cual no es conocido por su alta fiabilidad en ambiente industrial. El resultado de este proyecto será un producto completamente funcional el cual será desplegado en la «Harinera Castellana» en colaboración con la empresa «Automatinfo» en la cual se ha realizado parte de este proyecto.
V
Abstract Industry, as well as human beings, has evolved with the passage of time. Since the First Industrial Revolution, Industry has not stopped innovating in all different aspects. Globalisation, on the other hand, has forced companies to adopt new economic and strategic models in their business models. Currently, we faced with the Fourth Industrial Revolution which promises several improvements in many levels through out cyber-physical systems, industry and intelligent products, hyperconnectivity and big data. In this TFG, We will try to implement some of the philosophies of the last Industrial Revolution (Industry 4.0) to a prototype whose main objective will be the automation of one of the industrial processes in the company “Harinera Castellana”. The development of this prototype requires the collaboration of different parts, these are: software, hardware and management software. This document will describe how each of these parts have been implemented. Throughout all the document restrictions in cost and reliability will be referenced. This will be a challenge in the project because the prototype will be based on Arduino which is not known for its high reliability in industrial environments. The result of this project will be a completely functional product which will be deployed in “Harinera Castellana” in collaboration with the company “Automatinfo” where part of this project has been developed.
VII
Agradecimientos Cuando entré en la carrera creí sinceramente que me iba a costar mucho conseguir acabarla. Sin embargo aquí estoy, escribiendo las últimas páginas de esta etapa de mi vida que sin duda alguna me han hecho crecer como profesional y sobre todo, como persona. Ojalá fuera tan sencillo agradecer solo con palabras lo que mis padres han hecho por mí. Me dieron la vida, se sacrificaron por que tuviera una educación, tuvieron que aguantar una adolescencia rebelde y finalmente me han dado la oportunidad de estudiar esta carrera que sin su ayuda hubiera sido imposible acabar. Mi única manera de darles las gracias por todo lo que han hecho por mi es haciéndoles sentir orgullosos. Espero haberlo conseguido. También quiero dar las gracias a mis abuelos, ellos han sido y serán un referente para mi y una inspiración en mi vida. A mi abuelo Manolo quien de pequeño me enseñaba sus equipos de radioaficionado y las placas de cobre diseñadas con su rotulador. Probablemente sin ti este TFG jamás hubiera sido escrito, espero que esto te haga sentir orgulloso. A mi abuelo Ciro, uno de mis ídolos, sabio, obrero y deportista me ha enseñado a luchar por mi futuro además de enseñarme la importancia de los estudios, aquellos de los que él no pudo disfrutar todo el tiempo que hubiera querido, pero que no le impidieron darle la oportunidad a sus tres hijos. A mis abuelas, Amparo y Pepita solo puedo deciros que os quiero, gracias por cuidar y confiar en mi. A mi hermana quien ahora se enfrenta a las duras pruebas de las oposiciones y que seguro que conseguirá aprobar del mismo modo que ha conseguido todo aquello que se ha propuesto. Gracias también a Julio Daniel por confiar en mí desde el primer día que me presenté en su despacho porque quería investigar con él. Gracias por darme tantas oportunidades. Espero seguir trabajando a tu lado muchos años. De nuevo gracias al grupo ARCO por todo lo que me habéis dado, desde recursos, oportunidades y conocimientos, hasta compañeros que a día de hoy son amigos (Ana, Rubén, Barbara, Javier, Lalio. . . ). Agradecer también la oportunidad y la ayuda prestada por la empresa «Automatinfo» de quien me llevo una experiencia laboral y personal de valor incalculable. Gracias a cada uno de sus miembros por la confianza depositada en mí. También dar las gracias (como no podía ser de otro modo) a cada uno de los compañeros de la carrera y a mis compañeros de piso Jesús y Antonio con los que he vivido todo tipo de aventuras que jamás serán olvidadas. Finalmente quería dedicarle unas palabras a la chica que me ha aguantado durante este último año en mis momentos buenos y sobre todo en los malos. Gracias Mari Carmen por estar a mi lado, ayudarme tantísimo en este TFG y enseñarme a ser fuerte. Tu apoyo ha sido fundamental, espero poder devolverte todo lo que has hecho por mi. José Antonio de la Torre las Heras
IX
Hay una fuerza motriz más poderosa que el vapor, la electricidad y la energía atómica: la voluntad — Albert Einstein
xi
Índice general
Resumen
V
Abstract
VII
Agradecimientos
IX
Índice general
XIII
Índice de cuadros
XVII
Índice de figuras
XIX
Índice de listados
XXIII
Listado de acrónimos
XXV
1. Introducción
1
1.1. Estructura del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Objetivos
2 5
2.1. Objetivo general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2. Objetivos específicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2.1. Estudio de alternativas . . . . . . . . . . . . . . . . . . . . . . . .
6
2.2.2. Desarrollo de la plataforma hardware . . . . . . . . . . . . . . . .
6
2.2.3. Análisis y elección de la arquitectura de comunicaciones . . . . . .
6
2.2.4. Diseño del firmware . . . . . . . . . . . . . . . . . . . . . . . . .
6
2.2.5. Implementación del software de gestión . . . . . . . . . . . . . . .
7
2.2.6. Presentación de alternativa . . . . . . . . . . . . . . . . . . . . . .
7
2.2.7. Despliegue del sistema . . . . . . . . . . . . . . . . . . . . . . . .
7
3. Antecedentes
9
3.1. PLCs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XIII
9
3.1.1. Introducción a los PLCs . . . . . . . . . . . . . . . . . . . . . . .
9
3.1.2. Historia de los PLCs . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.1.3. Estructura de un PLC . . . . . . . . . . . . . . . . . . . . . . . . .
13
3.1.4. Principales fabricantes . . . . . . . . . . . . . . . . . . . . . . . .
14
3.1.5. Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.1.6. Desventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
3.2. Fenómenos maker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
3.2.1. ¿Qué es el fenómeno maker? . . . . . . . . . . . . . . . . . . . . .
17
3.2.2. Impresión 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
3.2.3. El fenómeno maker dentro del TFG . . . . . . . . . . . . . . . . .
20
3.3. Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
3.3.1. Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
3.3.2. Arquitectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
3.3.3. Casos de éxito . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.3.4. Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.3.5. Desventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.4. Industria 4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.4.1. Contextualización en la industria española . . . . . . . . . . . . . .
27
3.4.2. Los beneficios de la industria 4.0 . . . . . . . . . . . . . . . . . . .
28
3.4.3. Retos y propuestas de la industria 4.0 . . . . . . . . . . . . . . . .
29
3.4.4. La industria 4.0 en el proyecto . . . . . . . . . . . . . . . . . . . .
29
3.4.5. Casos de éxito . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
3.5. Alternativas PLCs basadas en Arduino . . . . . . . . . . . . . . . . . . . .
31
3.5.1. ArduPLC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
3.5.2. Análisis del producto . . . . . . . . . . . . . . . . . . . . . . . . .
32
3.5.3. Industrino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.5.4. Industrial Shields . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
3.5.5. Valoración general . . . . . . . . . . . . . . . . . . . . . . . . . .
44
3.6. Sistemas embebidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
3.6.1. Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
3.6.2. Los sistemas embebidos en el TFG . . . . . . . . . . . . . . . . .
49
4. Metodología de trabajo
53
4.1. Introducción a las metodologías de diseño en sistemas embebidos . . . . .
53
4.2. Metodología iterativa e incremental . . . . . . . . . . . . . . . . . . . . .
56
4.3. La metodología iterativa e incremental en el TFG . . . . . . . . . . . . . .
58
xiv
4.3.1. La metodología iterativa e incremental en el Hardware . . . . . . .
58
4.3.2. La metodología iterativa e incremental en el Software . . . . . . . .
59
4.3.3. Realimentación del cliente en el TFG . . . . . . . . . . . . . . . .
60
4.4. Herramientas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4.4.1. Herramientas software para el desarrollo . . . . . . . . . . . . . .
60
4.4.2. Herramientas software para la documentación . . . . . . . . . . . .
62
4.4.3. Lenguajes de programación y frameworks . . . . . . . . . . . . . .
62
5. Desarrollo del proyecto
65
5.1. Análisis del problema y desarrollo de la arquitectura . . . . . . . . . . . .
65
5.2. Organización del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . .
67
5.2.1. Los 3 proyectos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
5.2.2. Proyecto PCB . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
5.2.3. Proyecto Firmware . . . . . . . . . . . . . . . . . . . . . . . . . .
110
5.2.4. Proyecto Software, Sistema de gestión . . . . . . . . . . . . . . . .
146
6. Resultados
187
6.1. Proyecto hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
187
6.2. Proyecto firmware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
188
6.3. Proyecto software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
188
6.4. Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
188
7. Conclusiones
189
7.1. Objetivos alcanzados . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
189
7.1.1. Objetivo general . . . . . . . . . . . . . . . . . . . . . . . . . . .
189
7.1.2. Objetivos específicos . . . . . . . . . . . . . . . . . . . . . . . . .
189
7.2. Trabajo futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
192
7.3. Conclusiones personales . . . . . . . . . . . . . . . . . . . . . . . . . . .
192
A. Tutorial Kicad
197
A.1. Creación del esquemático . . . . . . . . . . . . . . . . . . . . . . . . . . .
197
A.2. Creación de componente para una librería . . . . . . . . . . . . . . . . . .
200
A.3. Creación de footprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
202
A.4. Capas Printed Circuit Board (PCB) . . . . . . . . . . . . . . . . . . . . . .
203
A.5. Herramienta DRC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
205
xv
B. Instalación de Arduino en entorno Eclipse
209
B.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
209
B.2. Qué es Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
209
B.3. Instalación del entorno . . . . . . . . . . . . . . . . . . . . . . . . . . . .
209
B.4. Configuración del entorno . . . . . . . . . . . . . . . . . . . . . . . . . .
211
B.5. Creando el proyecto: ArduinoCore . . . . . . . . . . . . . . . . . . . . . .
212
B.6. Creando el proyecto final . . . . . . . . . . . . . . . . . . . . . . . . . . .
214
B.7. Subiendo el proyecto a nuestro Arduino . . . . . . . . . . . . . . . . . . .
214
C. Requisitos formales de la Harinera Castellana
217
D. Código y documentación extra
223
E. GNU Free Documentation License
225
E.0. PREAMBLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
225
E.1. APPLICABILITY AND DEFINITIONS . . . . . . . . . . . . . . . . . . .
225
E.2. VERBATIM COPYING . . . . . . . . . . . . . . . . . . . . . . . . . . .
226
E.3. COPYING IN QUANTITY . . . . . . . . . . . . . . . . . . . . . . . . . .
226
E.4. MODIFICATIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
227
E.5. COLLECTIONS OF DOCUMENTS . . . . . . . . . . . . . . . . . . . . .
228
E.6. AGGREGATION WITH INDEPENDENT WORKS . . . . . . . . . . . .
228
E.7. TRANSLATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
228
E.8. TERMINATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
228
E.9. FUTURE REVISIONS OF THIS LICENSE . . . . . . . . . . . . . . . . .
229
E.10. RELICENSING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
229
Referencias
231
xvi
Índice de cuadros
3.1. Tabla de fabricantes de PLCs . . . . . . . . . . . . . . . . . . . . . . . . .
51
3.2. Productos Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
3.3. Tabla de precios de Industrino . . . . . . . . . . . . . . . . . . . . . . . .
52
5.1. Tabla comparativa de tecnologías groov . . . . . . . . . . . . . . . . . . .
181
XVII
Índice de figuras
3.1. Representación sencilla del flujo de trabajo de un Programable Logic Controllers (PLC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
3.2. Relé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
3.3. Modicom 084 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
3.4. Comparación sistema basado en relés vs sistema basado en PLC . . . . . .
12
3.5. Modicom 084 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.6. Dos de los productos maker de BQ . . . . . . . . . . . . . . . . . . . . . .
18
3.7. Extrusor impresora 3D (Fuente BQ) . . . . . . . . . . . . . . . . . . . . .
20
3.8. Plataforma wiring (Fuente: Massimo Banzi) . . . . . . . . . . . . . . . . .
22
3.9. Shields de expansión para Arduino . . . . . . . . . . . . . . . . . . . . . .
22
3.10. Entorno Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.11. Impresora 3D prusa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.12. PIB a partir de los datos del Banco Mundial, Fuente: Instituto Nacional . .
27
3.13. Niveles organizativos en la industria . . . . . . . . . . . . . . . . . . . . .
30
3.14. Pequeño armario de conexiones . . . . . . . . . . . . . . . . . . . . . . .
32
3.15. Optoacoplación línea 485 . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
3.16. Salida aislada mediante relés . . . . . . . . . . . . . . . . . . . . . . . . .
34
3.17. Ejemplo de entrada filtrada . . . . . . . . . . . . . . . . . . . . . . . . . .
35
3.18. Protección frente a voltajes indeseados . . . . . . . . . . . . . . . . . . . .
35
3.19. Industrino Proto Kit, fuente: https://industruino.com . . . . . . . . . . . .
36
3.20. Industrino IND, fuente: https://industruino.com . . . . . . . . . . . . . .
37
3.21. Carta de expansión Ethernet, fuente: https://industruino.com . . . . . . . .
39
3.22. Diagrama de bloques industrino proto kit, fuente: https://industruino.com .
39
3.23. Controlador Básico Arduino BC16DA, fuente: http://www.industrialshields. com/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 3.24. Resistencia de Pull-Up DIN, fuente: http://www.industrialshields.com/ . .
42
3.25. TouchBerry Pi 10.1, fuente: http://www.industrialshields.com/ . . . . . .
42
3.26. Diagrama en bloques ARDBOX 20, fuente: http://www.industrialshields. com/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
XIX
3.27. Corriente sinusoidal. Fuente: wikipedia . . . . . . . . . . . . . . . . . . .
48
3.28. Sensor de CO2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
3.29. Estructura interna de un regulador de tensión . . . . . . . . . . . . . . . .
49
4.1. Resultados del estudio Embedded Market Survey del 2013 . . . . . . . . .
54
4.2. Herramienta Trello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
5.1. Foto de un silo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
5.2. Rasera (no corresponde a la utilizada en la fábrica. Sin embargo, las características son las misma) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
5.3. Sistema SCADA Web desarrollado por INDAS . . . . . . . . . . . . . . .
68
5.4. Módulo L298. Fuente: http://blog.codebender.cc/ . . . . . . . . . . . . .
70
5.5. Puente en H. Fuente: http://letsmakerobots.com/ . . . . . . . . . . . . . .
71
5.6. Cilindro Hiwin LAS3-1-1250-24GE . . . . . . . . . . . . . . . . . . . . .
71
5.7. Primera versión del prototipo . . . . . . . . . . . . . . . . . . . . . . . . .
72
5.8. Descripción de pines obtenido del datasheet . . . . . . . . . . . . . . . . .
74
5.9. Datasheet módulo de control de motores . . . . . . . . . . . . . . . . . . .
75
5.10. Conexión del cilindro al controlador de motores. . . . . . . . . . . . . . .
77
5.11. L298 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
5.12. Conexión de potenciometro a Arduino. Fuente: http://arduineando.matem. unam.mx/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
5.13. LCD Nokia 5110 utilizada para el proyecto. Fuente: http://www.hobbytronics. co.uk/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
5.14. Esquema de conexionado del LCD. Fuente: http://electronilab.co/ . . . .
81
5.15. Prueba del LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
5.16. Esquema de conexión del módulo infrarrojo. Fuente: Datasheet AX-138HS
83
5.17. Impresión de salida obtenida del módulo infrarrojo . . . . . . . . . . . . .
83
5.18. Montaje módulo infrarrojo . . . . . . . . . . . . . . . . . . . . . . . . . .
83
5.19. Shield para prototipado de Sparkfun. Fuente: https://www.sparkfun.com . .
84
5.20. Prototipo final con el firmware resultado de la iteración inicial . . . . . . .
85
5.21. Hoja de datos para la familia LM78XX . . . . . . . . . . . . . . . . . . .
87
5.22. Esquema de alimentación implementado. . . . . . . . . . . . . . . . . . .
88
5.23. Cargador genérico de smartphone . . . . . . . . . . . . . . . . . . . . . .
89
5.24. Esquema de alimentación del Arduino. Fuente: http://www.arduino.cc . . .
89
5.25. Esquema de comparación de voltajes. Fuente: http://www.arduino.cc . . . .
90
5.26. Esquema con Diodo D1 en antiparalelo. Fuente: http://ovtoaster.com/ . . .
92
5.27. Esquema de transistores con carga inductiva y no inductiva. . . . . . . . . .
92
xx
5.28. Representación de un optocoplador formado por un diodo led y un fototransistor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
5.29. Esquema implementado para la optoacoplación del módulo de motores. . .
94
5.30. Esquema implementado para la optocoplación del módulo de comunicaciones. 95 5.31. Prototipo implementado para el aislamiento y pruebas con el osciloscopio. .
96
5.32. Retardos debido a optocoplamiento . . . . . . . . . . . . . . . . . . . . . .
96
5.33. Hoja principal del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . .
100
5.34. Conector molex utilizado . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
5.35. Hoja de alimentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
5.36. Ventana de diálogo Electrical Rules Check (ERC) . . . . . . . . . . . . . .
104
5.37. Resultados del ERC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
105
5.38. Proceso de emplazamiento de componentes finalizado . . . . . . . . . . . .
106
5.39. Proceso de enrutado completo . . . . . . . . . . . . . . . . . . . . . . . .
107
5.40. Proceso de creación de zonas de tierra . . . . . . . . . . . . . . . . . . . .
108
5.41. Placa final en 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
108
5.42. Bus 485 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
112
5.43. Repetidor 485 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
113
5.44. Comparación de señales filtrada/no filtrada en un bus 485 . . . . . . . . . .
113
5.45. Esquema módulo 485 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
114
5.46. Representación del offset . . . . . . . . . . . . . . . . . . . . . . . . . . .
115
5.47. Sistema infrarrojo utilizado . . . . . . . . . . . . . . . . . . . . . . . . . .
118
5.48. Tren de pulsos código NEC . . . . . . . . . . . . . . . . . . . . . . . . . .
118
5.49. Pantalla principal del Human Machine Interface (HMI) . . . . . . . . . . .
122
5.50. Sistema HMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
123
5.51. Diagrama de estados de la máquina de estados . . . . . . . . . . . . . . . .
133
5.52. Proceso HMAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
139
5.53. Caja con un controlador . . . . . . . . . . . . . . . . . . . . . . . . . . . .
141
5.54. Groov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
148
5.55. Ignition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
150
5.56. Aggregate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
151
5.57. Conversor FTDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
152
5.58. Sistema de registro realizado con Flask . . . . . . . . . . . . . . . . . . . .
162
5.59. Captura del formulario web para añadir raseras . . . . . . . . . . . . . . .
167
5.60. Formularios de gestión implementados . . . . . . . . . . . . . . . . . . . .
168
5.61. Página principal de la aplicación web . . . . . . . . . . . . . . . . . . . .
172
xxi
5.62. Pantalla de login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
182
5.63. Pantalla de inicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
183
5.64. Pantalla de monitorización . . . . . . . . . . . . . . . . . . . . . . . . . .
184
5.65. Pantalla desde donde se pueden gestionar los procesos . . . . . . . . . . .
185
5.66. Pantalla desde donde se pueden gestionar las raseras por cada proceso . . .
185
6.1. PCB final en 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
187
A.1. Retardos debido a optocoplamiento . . . . . . . . . . . . . . . . . . . . . .
198
A.2. Alternativa al conexionado con cables mediante etiquetas. Las etiquetas con el mismo nombre están conectadas entre si . . . . . . . . . . . . . . . . . .
198
A.3. Resultado con etiquetas estándar . . . . . . . . . . . . . . . . . . . . . . .
199
A.4. Diseño jerárquico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
199
A.5. Diseño jerárquico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
200
A.6. Diseño jerárquico exportación de pines . . . . . . . . . . . . . . . . . . . .
201
A.7. Hoja de comunicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . .
201
A.8. Diálogo para la configuración de pines del componente . . . . . . . . . . .
202
A.9. Proceso de traducción de componentes esquemáticos a footprint . . . . . .
203
A.10. PCB footprint editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
203
A.11.Footprint RS-485 terminado . . . . . . . . . . . . . . . . . . . . . . . . .
204
A.12.Capas en Kicad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
205
A.13.Cuadro de diálogo Design Rules Check (DRC) . . . . . . . . . . . . . . . .
207
A.14.Cuadro de ejecución DRC . . . . . . . . . . . . . . . . . . . . . . . . . . .
207
B.1. Pantalla inicial de Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . .
210
B.2. Descarga del plugin AVR . . . . . . . . . . . . . . . . . . . . . . . . . . .
211
B.3. Configuración de ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . .
212
B.4. Configuración de las librerías . . . . . . . . . . . . . . . . . . . . . . . . .
215
B.5. Configuración de AVRdude . . . . . . . . . . . . . . . . . . . . . . . . . .
216
xxii
Índice de listados 5.1. Prueba de envío por módulo 485 . . . . . . . . . . . . . . . . . . . . . . .
73
5.2. Prueba de envío por módulo 485 . . . . . . . . . . . . . . . . . . . . . . .
74
5.3. Interrupciones en SoftwareSerial . . . . . . . . . . . . . . . . . . . . . . .
76
5.4. Programa de prueba L298 . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
5.5. Prueba del LCD de nokia . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
5.6. Sensorización de posición . . . . . . . . . . . . . . . . . . . . . . . . . . .
115
5.7. Movimiento en un sentido . . . . . . . . . . . . . . . . . . . . . . . . . .
116
5.8. Ejemplo librería IRremote . . . . . . . . . . . . . . . . . . . . . . . . . .
119
5.9. Decodificación de los valores leídos . . . . . . . . . . . . . . . . . . . . .
120
5.10. Ejemplo de codificación de la pantalla principal . . . . . . . . . . . . . . .
121
5.11. Movimiento entre pantallas . . . . . . . . . . . . . . . . . . . . . . . . . .
122
5.12. Encapsulamiento del movimiento del motor. . . . . . . . . . . . . . . . . .
128
5.13. Uso de la herencia en sistemas embebidos . . . . . . . . . . . . . . . . . .
129
5.14. Polimorfismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
131
5.15. Implementación de la máquina de estados de comunicaciones . . . . . . . .
133
5.16. Utilización de la librería CryptoSuite. Fuente: http://spaniakos.github.io/ Cryptosuite/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 5.17. Definición de la clase Payload . . . . . . . . . . . . . . . . . . . . . . . .
140
5.18. Definición de la clase Slavebox . . . . . . . . . . . . . . . . . . . . . . . .
142
5.19. Método scan del objeto Slavebox . . . . . . . . . . . . . . . . . . . . . . .
143
5.20. Ejemplo mínimo de aplicación Flask . . . . . . . . . . . . . . . . . . . . .
151
5.21. Formulario básico html . . . . . . . . . . . . . . . . . . . . . . . . . . . .
153
5.22. Backend del formulario básico . . . . . . . . . . . . . . . . . . . . . . . .
153
5.23. Fichero de configuración para Flask . . . . . . . . . . . . . . . . . . . . .
156
5.24. Fichero «__init__.py» . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
156
5.25. Fichero «models.py», modelo User . . . . . . . . . . . . . . . . . . . . . .
157
5.26. Fichero «routes.py», ruta de registro . . . . . . . . . . . . . . . . . . . . .
158
5.27. Fichero «routes.py», ruta de registro . . . . . . . . . . . . . . . . . . . . .
159
5.28. Template para la renderización del formulario . . . . . . . . . . . . . . . .
160
XXIII
5.29. Extracto de código donde se pueden ver relaciones . . . . . . . . . . . . .
162
5.30. Extracto de código con los formularios para la creación y eliminación de raseras y procesos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
163
5.31. Lógica de negocio para la gestión de procesos y raseras . . . . . . . . . . .
165
5.32. Template para la renderización de formularios anidados . . . . . . . . . . .
166
5.33. Código javascript para la creación de nuevas filas en el formulario . . . . .
166
5.34. Código para la definición de la clase Arduino . . . . . . . . . . . . . . . .
168
5.35. Código para conectarse al bus de comunicaciones . . . . . . . . . . . . . .
170
5.36. Librería para gestionar el protocolo de comunicaciones . . . . . . . . . . .
171
5.37. Método para gestionar la petición de cambio de posición . . . . . . . . . .
173
5.38. Código para capturar el click de un elemento . . . . . . . . . . . . . . . .
173
5.39. Función para realizar la petición ajax . . . . . . . . . . . . . . . . . . . . .
174
5.40. Función para realizar la petición ajax . . . . . . . . . . . . . . . . . . . . .
176
5.41. Head del template «base.html» . . . . . . . . . . . . . . . . . . . . . . . .
179
B.1. Esqueleto de programa . . . . . . . . . . . . . . . . . . . . . . . . . . . .
215
xxiv
Listado de acrónimos TFG
Trabajo Fin de Grado
UCLM
Universidad de Castilla La Mancha
TIC
Tecnologías de la Información y la Comunicación
ISO
Ingeniería del software
PLC
Programable Logic Controllers
PCB
Printed Circuit Board
ADC
Analog Digital Converter
DAC
Digital Analog Converter
GMC
General Motors Corporation
SCADA
Supervisory Control And Data Acquisition
TTM
Time To Market
DDC
Direct Digital Control
DCS
Direct Control System
CPU
Central Power Unit
RAM
Random Access Memory
ROM
Read Only Memory
PROM
Programmable Read Only Memory
EEPROM
Electrical Erasable Programmable Memory
ERP
Enterprise Resource Planning
DIY
Do It Yourself
FPGA
Field Programmable Gate Array
I OT
Internet of Things
IDE
Integrated Development Environment
PIB
Producto Interior Bruto
FTTH
Fiber To The Home
W3C
World Wide Web Consortium
XXV
MES
Manufacturing Execution System
TVS
Transient Voltage Suppressor
HMI
Human Machine Interface
SOC
System on Chip
EMI
ElectroMagnetic Interference
ALU
Arithmetic Logic Unit
ASIC
Application Specific Integrated Circuit
ASIP
Application Specific Instruction Set Processor
DSP
Digital Signal Processor
EU
Execute Unit
CU
Control Unit
GPP
General Purpose Processor
GPU
Graphics Processor Unit
GUI
Graphical User Interface
NIC
Network Interface Card
PID
Proportional Integral Derivative controller
RTOS
RealTime Operating System
PLA
Poliácido láctico
PYME
Pequeña Y Mediana Empresa
ESD
ElectroStatic Discharge
TODO
To-Do
CAD
Computer-Aided Design
CERN
Conseil Européen pour la Recherche Nucléaire
CMOS
Complementary Metal-Oxide Semiconductor
DE
Driver Enable
DI
Driver Input
FET
Field-Effect Transistor
PWM
Pulse Width Modulation
RE
Receive Enable
RO
Receive Output
TTL
Transistor Transistor Logic
CTR
Current Transfer Ratio
xxvi
ERC
Electrical Rules Check
CNC
Control Numérico Computerizado
DRC
Design Rules Check
SMD
Surface Mounted Device
ATEX
ATmosphères EXplosives
HMAC
keyed-Hash Message Authentication Code
CSRF
Cross-Site Request Forgery
DNI
Documento Nacional de Identidad
HTTP
HyperText Transfer Protocol
ORM
Object-Relational Mapping
SDK
Software Development Kit
SQL
Structured Query Language
URL
Uniform Resource Locator
USB
Universal Serial Bus
CSS
Cascading Style Sheets
DOM
Document Object Model
HTML
HyperText Markup Language
SMS
Short Message Service
CDN
Content Delivery Network
REST
Representational State Transfer
BSD
Berkeley Software Distribution
GPL
GNU General Public License
xxvii
Capítulo 1
Introducción
N
OS encontramos en un marco socioecononómico llamado «mundialización»1 en el cual
los mercados de diferentes países se agrupan como uno único y en donde las necesidades de productividad en los procesos de producción aumenta día a día ante el incesante aumento de la competencia.
Hace escasos años, la panadería de un pequeño pueblo era capaz de producir lo suficiente para cubrir la demanda requerida por sus habitantes. No obstante, a día de hoy, en cualquier pueblo podemos encontrar grandes superficies donde además del pan, el consumidor puede obtener otros productos a un precio más competitivo. La diferencia entre la panadería del pueblo y el supermercado no es otra que el volumen de producción. Mientras el supermercado tiene un nicho de mercado que sobrepasa las fronteras del pueblo, la panadería apenas cubre una parte de los habitantes. Existen numerosas ventajas estratégicas y económicas derivadas de los volúmenes de producción de las grandes empresas. Una estrategia que se podría adoptar sería la firma de contratos con grandes proveedores de tal manera que el coste por unidad se reduzca. Sin embargo, otra estrategia puede ser la de invertir en la modernización de los procesos de producción (algunos supermercados tienen sus propias marcas) de tal manera que se pueda reducir aun más el precio por unidad. Con el objetivo de reducir los costes, así como, aumentar la productividad de las líneas de producción se han ido automatizando paulativamente las industrias. Los costes generados por la automatización de las líneas de producción, actualmente, no son asumibles por todas las empresas, dejando fuera del mercado a aquellas que no son capaces de hacer frente a dicho gasto. Por otro lado, durante los últimos años, la ingeniería informática y en general las Tecnologías de la Información y la Comunicación (TIC) han ido incrementando su influencia en muchas áreas donde hace unos años era inimaginable. Cualquier vehículo actual cuenta con cientos de sensores digitales que envían su señal a diferentes procesadores distribuidos y permiten tomar decisiones al coche. Otro ejemplo muy representativo de la aparición de la ingeniería 1
Algunos autores consideran más adecuado el término mundialización globalización.[UNE] En este documento se utilizarán indistintamente ambos términos.
1
frente
al
término
informática dentro del dominio de los ingenieros industriales es el de los contadores eléctricos. Dichos contadores son inteligentes y facilitan la tarea de los operarios, además de aumentar la fiabilidad de la instalación. El software empotrado dentro de dichos dispositivos requiere de alta disponibilidad, seguridad, y fiabilidad, por estas razones disciplinas como Ingeniería del software (ISO) o ingeniería de computadores son claves para asegurar el cumplimiento de dichos objetivos. El presente trabajo se enmarca dentro de un convenio de prácticas entre la empresa «Automatinfo» y la Universidad de Castilla La Mancha (UCLM). En estas prácticas, se presentó un proyecto de automatización para una harinera en Medina del Campo, Valladolid. Entre los requisitos del proyecto, que serán tratados con más detalle en la Capítulo 5, se encontraba el bajo coste y la fiabilidad del diseño. Afrontar un proyecto de automatización industrial supone un gran reto para un ingeniero informático dado que hasta ahora ese trabajo quedaba delegado en su mayoría a los ingenieros industriales o a los ingenieros de automatismos. Para completar con éxito un trabajo de esta envergadura es necesario aplicar los conocimientos adquiridos durante la carrera además de complementar los mismos en diversas áreas de la electrónica. En este documento se tratará de diseñar una solución segura y de bajo coste para la automatización de diferentes procesos productivos con el objetivo de poder aumentar la productividad y competitividad de las pequeñas empresas en la marco económico actual. Con el objetivo de presentar un escenario real, se detallará la implementación de la solución desarrollada para la «Harinera Castellana».
1.1 Estructura del documento Este documento está formado por los siguientes capítulos: Capítulo 1: Introducción Capítulo donde se da una breve introducción sobre el trabajo descrito en este documento. Capítulo 2: Objetivos En este capítulo el lector encontrará cada uno de los objetivos a alcanzar en la realización de este proyecto. Por un lado encontrará el objetivo general que define en términos generales el propósito del TFG y por otro lado cada uno de los subobjetivos que permiten dividir el diseño en pequeños hitos. Capítulo 3: Antecedentes Durante este capítulo, el lector podrá obtener una visión general de cada uno de los temas involucrados en la realización de este TFG. Capítulo 4: Metodología de trabajo En este capítulo se aborda la metodología seguida en el desarrollo del proyecto. Por 2
un lado se dará una breve descripción teórica de dicha metodología y por otro lado se mostrará la instanciación de dicha metodología en el proyecto. Finalmente, se nombrarán cada una de las herramientas utilizadas en el desarrollo del proyecto. Capítulo 5: Desarrollo del proyecto El lector podrá encontrar en este capítulo cómo se han desarrollado cada una de las partes del proyecto. Tal y como se verá, el proyecto está dividido en tres subproyectos: hardware, firmware, software de gestión. En este capítulo, en cada subproyecto se analizará el desarrollo por iteraciones. Cada subproyecto tiene una fase de inicio y un bucle de iteración con diferentes iteraciones. Por cada iteración se definen los requisitos o restricciones que afectaron a la implementación, las características añadidas o mejoradas, así como las decisiones de diseño y la elaboración de dicha iteración. Capítulo 6: Resultados En este capítulo se analizarán los resultados en cada uno de los subproyectos en los que se divide el proyecto. Capítulo 7: Conclusiones Por último, en este capítulo se hace una breve reflexión sobre cada uno de los objetivos que se buscaba alcanzar así como un análisis sobre el trabajo futuro a realizar y las conclusiones personales obtenidas al finalizar el proyecto.
3
Capítulo 2
Objetivos
2.1 Objetivo general
E
proyecto surge ante la necesidad real de la «Harinera Castellana» de automatizar uno de sus procesos de elaboración de harina. El proyecto se encarga a la empresa «Automatinfo» quien plantea los diferentes problemas existentes a la hora de automatizar estas líneas. Una de las restricciones más importantes de este proyecto es reducir el coste de implementación. Además, la empresa «Automatinfo» busca realizar una implementación real y en funcionamiento que pueda servir en el futuro para demostrar la rentabilidad de los diseños ad hoc apoyados en sistemas TIC. STE
Actualmente la mayoría de automatizaciones industriales se realizan mediante Programable Logic Controllers (PLC)s. Este tipo de diseño requiere de un presupuesto significativo debido a los costes de dichos dispositivos. En este trabajo se desarrollará una solución integra para la automatización de las líneas de producción anteriormente citadas como alternativa a los PLCs. Para diseñar dicha solución, se deberán realizar varios subproyectos que irán desde la creación de una Printed Circuit Board (PCB) hasta el software de gestión pasando por el firmware empotrado en los controladores. Como resultado del proyecto, se deberá presentar a la «Harinera Castellana», un prototipo funcional que será probado en algunas de sus líneas de producción para posteriormente ser desplegado en toda la fábrica. Además, con el objetivo de cumplir con los requisitos de bajo coste y fiabilidad, se presentará ante «Automatinfo» un informe con la estimación de horas de trabajo requeridas para el proyecto así como un informe económico del prototipo.
2.2 Objetivos específicos El proyecto se divide en 4 subproyectos bien diferenciados. Por una parte tenemos el proyecto hardware donde se diseñará la plataforma sobre la que más tarde, en el proyecto de desarrollo del firmware se programará. En un nivel más alto, el software de gestión será el encargado proveer de una interfaz al operario apoyándose en el firmware y el hardware existente. La comunicación entre los diferentes elementos del sistema así como el despliegue de los mismo dentro de la fábrica se engloban dentro del último subproyecto. 5
Derivados de estos subproyectos se pueden definir los siguiente subobjetivos que guiarán el desarrollo del proyecto.
2.2.1
Estudio de alternativas
Antes de realizar una nueva plataforma hardware se debe comprobar si existen otros productos que se puedan adaptar a nuestras necesidades, además, a partir de este análisis previo de alternativas se podrá concluir con una primera aproximación del precio por unidad por lo que ya se partirá de un coste de referencia. Concluido este estudio se realizará una reunión con «Automatinfo» para comenzar con el desarrollo del proyecto.
2.2.2
Desarrollo de la plataforma hardware
Con el objetivo de presentar un diseño realizado íntegramente para esta necesidad, se desarrollará una plataforma hardware que dará soporte a los diferentes software, tanto de aplicación como de control. Como resultado de este objetivo se mandará elaborar una PCB resultado del diseño realizado.
2.2.3
Análisis y elección de la arquitectura de comunicaciones
La arquitectura de comunicaciones es de vital importancia en entornos industriales. Elementos como el ruido eléctrico pueden hacer que un diseño que funciona bien dentro de un edificio convencional, no pueda ser utilizado en un entorno industrial. Con el objetivo de realizar un diseño fiable, se analizarán los diversos estándares de comunicación existentes en la industria y se investigará la compatibilidad oficial con la plataforma hardware. Como resultado de este objeto se concluirá con una especificación de la arquitectura de comunicaciones así como un análisis de tiempos que permita verificar si el diseño podrá soportar las necesidades de las aplicaciones de nivel superior.
2.2.4
Diseño del firmware
El firmware es una parte esencial dentro de los sistemas embebidos1 . Este elemento es el encargado de dotar de «lógica» al hardware habilitando salidas y generando diferentes señales. Como cabe esperar, en este proyecto se abordará la programación de un sistema empotrado. Uno de los subobjetivos dentro del diseño del firmware es facilitar el mantenimiento del software de tal manera que más adelante, los empleados de «Automatinfo» o la «Harinera Castellana» sean capaces de depurar y expandir el diseño en caso de que sea necesario. En este caso se hace de vital importancia el hecho de que sea fácilmente depurable y expandible dado que los equipos de ambas empresas no cuentan con una formación especializada en ingeniería informática. Su campo de formación es el de los automatismos. 1
Durante este documento se utilizará indistintamente los términos sistema embebidos y sistemas empotra-
dos
6
2.2.5
Implementación del software de gestión
En los sistemas de automatización industrial normalmente se dota al operario de una interfaz Supervisory Control And Data Acquisition (SCADA). Las interfaces SCADA permiten al operario tener una representación virtual de la fábrica, así como la supervisión de parámetros críticos del sistema de manera rápida y sencilla. Con el objetivo de presentar una solución completamente funcional y que pueda competir contra las soluciones tradicionales, en este proyecto se realizará una interfaz Supervisory Control And Data Acquisition (SCADA) añadiendo características de las TIC de tal modo que se pueda hacer visible la ventaja que representa este tipo de sistemas.
2.2.6
Presentación de alternativa
Una vez realizado el prototipo y realizadas las pruebas pertinentes, se procederá a presentar el sistema propuesto ante la «Harinera Castellana». En esta reunión se presentarán los informes pertinentes como puedan ser: informe de viabilidad, storyboards, fotografías, informe de despliegue, etc. Tras la reunión se concluirá con la autorización para realizar el despliegue así como con un cuadro organizativo para orquestar dicho despliegue.
2.2.7
Despliegue del sistema
El despliegue del sistema consistirá en la producción en masa de las plataformas hardware así como la instalación de las mismas en cada una de las líneas a automatizar. Para la realización de este trabajo únicamente se probaría con una unidad, no obstante, el proyecto concluirá con la instalación de todas las unidades.
7
Capítulo 3
Antecedentes
E
este capítulo se hará una revisión sobre los principales temas que han intervenido en el desarrollo de este proyecto. Desde la historia de los PLC, Arduino o la Industria hasta una breve descripción de la Industria 4.0 y las implicaciones que tendrá en la economía de este sector. N
3.1 PLCs 3.1.1
Introducción a los PLCs
Los PLC son «dispositivos de estado solido los cuales se encuentran dentro de la familia de los computadores y que utilizan circuitos integrados en vez de dispositivos electromecánicos para realizar funciones de control»[E.A98]. Los PLC son capaces de ejecutar la mayor parte de las funciones que realiza un computador de uso general, no obstante, los primeros no están pensados para ser reprogramados. Los programas realizados sobre PLC suelen seguir un flujo bastante sencillo (en la Figura 3.1 se puede observar una representación simple de dicho flujo). Medición: Se miden las variables de control necesarias. Normalmente estas mediciones suelen ser tanto analógicas como digitales. Para realizar este tipo de conversión, los PLC suelen estar dotados de poderosos Analog Digital Converter (ADC)s y Digital Analog Converter (DAC)s. Control: Con las mediciones realizadas el PLC calcula la siguiente acción a realizar en función de la lógica del programa. Realimentación: Es bastante común que se produzca una fase de realimentación o feedback de modo que el proceso pueda responder a cambios en alguna de las variables de proceso.
3.1.2
Historia de los PLCs
Los PLCs aparecieron aproximadamente sobre 1968. Fue entonces cuando General Motors Corporation (GMC) lanzó la primera especificación de un PLC. La primera versión de esta especificación estuvo motivada por la necesidad principal de eliminar los costes asociados a los sistemas basados en relés. Los relés tenían muchos problemas. Uno de los problemas 9
Figura 3.1: Representación sencilla del flujo de trabajo de un PLC
principales era la vida útil dado que son dispositivos completamente mecánicos y con el tiempo solían romper algunas de sus partes (ver Figura3.2). Los relés se siguen utilizando en los PLCs, si bien, la frecuencia de conmutación de los mismos es mucho más reducida dado que únicamente se utilizan en las etapas de salida para aislar la lógica del control. Además de los problemas de vida útil, los sistemas basados en relé tenían un problema muy importante y era la incapacidad de expandir el diseño además de que el Time To Market (TTM) aumentaba considerablemente debido a la falta de herramientas de diseño para el desarrollo de estos sistemas. Con estas limitaciones presentes, GMC lanzó la primera especificación. Esta especificación buscaba obtener sistemas capaces de ser fiables en entornos industriales, ser fácilmente programables y reusable[E.A98]. Algunas de las características claves dentro de esta especificación eran: El sistema deberá tener un precio competitivo frente a los sistemas basados en relés. Reemplazar los módulos de entrada/salida deberá ser sencillo. El sistema deberá ser capaz de convivir en un entorno industrial, esto es, mantenerse inmune ante el ruido eléctrico, humedad, calor. . . El controlador se deberá diseñar de forma modular, de tal manera que, se puedan ir añadiendo en el futuro módulos. A estos módulos, en la jerga de automatismos se les llama «cartas de expansión». Deberá existir una realimentación desde el subsistema de control al subsistema de procesamiento. El sistema deberá ser reusable. El lenguaje de programación o más genéricamente el método de programación deberá ser fácilmente entendible por todo el personal. Debido a que el sistema desarrollado será mantenido por Automatinfo, es importante que el lenguaje de programación se parezca lo máximo posible a los métodos de programación que usan con los PLCs1 . 1
Durante el documento se ahondará en este hecho dado que es de vital importancia en el mantenimiento de los sistemas
10
Figura 3.2: Relé
El white paper fue presentado en 1968 en la conferencia de Westinghouse. Tras la publicación de la especificación varias compañías empezaron la fabricación de este tipo de dispositivos, entre ellas: 1. Allen-Bradley: Compañía muy reconocida en el sector a día de hoy. La compañía presento el PDQ II y el PMD pero ambos fueron rechazados debido a las dimensiones así como la dificultad de programación. 2. Digital Equipment Corporation (DEC): Digital Equipment estaba muy especializada en el desarrollo de computadores y propuso un «mini ordenador». Esta propuesta no fue aceptada debido a la memoria estática. 3. Century Detroit 4. Bedford Associates: Ganaron el concurso con el Modicon 084 (ver Figura 3.3). Los primeros PLCs eran «muy simples» y básicamente eran un reemplazo de los sistemas basados en relés, es decir, no añadía excesivas funcionalidades. Se empezaron a utilizar en máquinas que realizaban operaciones repetitivas como los transfer, máquinas de troquelamiento, etc. Los PLCs mostraron el gran potencial que suponían incorporando mecanismos de degradamiento así como la posibilidad de reutilización en diferentes proyectos. Aun con la demostración del potencial, la industria tardó en aceptarlos como un sistema viable a la hora de reemplazar los sistemas basados en relés. Richard Morley dijo: «Es difícil convencer a la gente que una pequeña caja puede reemplazar armarios de conexiones de 50 pies» (ver Figura 3.4 para ver la diferencia). En la industria es bastante común (y por otra parte lógico) el no aceptar un cambio a no ser que el sistema esté muy probado y certificado y los PLCs contaban con el handicap de que en cierto modo se asimilaban a los computadores y estos últimos, en aquella época, tenían fama de no ser fiables. 11
Figura 3.3: Modicom 084
Por otro lado, Neil Taylor de Taylor Industrial Software afirmó: «He estado consultando y observando la necesidad existente de reemplazar las tablas producidas por los diagramas ladder2 las cuales, cuestan mucho tiempo para crearse y mucho dinero a la hora de mantenerse». Esta frase señalaba la necesidad existente para documentar los diseños basados en PLCs y que hasta ahora no había sido contemplada.
(a) Sistema basado en relés
(b) Sistema basado en PLC
Figura 3.4: Comparación sistema basado en relés vs sistema basado en PLC
Según [AT] la historia de los PLCs y en general, los Direct Control System (DCS) se puede dividir en 7 periodos: Antes de 1950 (Early Process Control): En este periodo los sistemas de control estaban comandados por dispositivos analógicos los cuales eran cableados a mano y como »
2
Ladder es el lenguaje de programación utilizado en los PLCs
12
anteriormente se ha comentado, poseían muy poca flexibilidad. El principal coste de estos sistemas estaba en los dispositivos analógicos. Únicamente se automatizaba los ciclos sencillos. 1950 (Pioneering Period): En este periodo se diseñan computadores como el MTBF que conseguía tiempos de ejecución de 1 ms para la suma y 20 ms para la multiplicación. Los sistemas de control seguían siendo analógicos. 1960 (Direct Digital Control): Empiezan a aparecer los primeros sistemas de control digital en productos como el misil «Bloodhound Mk2». Solo los sistemas de gran envergadura se sometían a este tipo de control. Surgen los primeros lenguajes Direct Digital Control (DDC) pero todavía se tratan de sistemas fijos y con poco nivel de programación. 1970 (Cheaper computers): Los computadores empiezan a abaratarse y a reducirse en tamaño, además los procesadores son cada vez más rápidos y algunos procesos críticos empiezan a confiar en estos dispositivos. 1980 (DCS emerges): Los Direct Control System (DCS) empiezan a implantarse en las industrias. La empresa Midac implementa un sistema DCS en la Universidad de Melbourne mediante el hardware R-Tec. Este sistema utilizaba comunicación serial[Dis] para conectar cada uno de las unidades remotas, compuestas por dos Z80 a la unidad encargada del frontend, esta última compuesta por 8 procesadores Z80. Con este primer sistema se demostró a la industria la necesaria actualización hacia los DCS 1990 (Fieldbus wars): Se pasa de la comunicación analógica a la comunicación digital. En este momento no existían estándares de comunicación y diferentes empresas empiezan a lanzar al mercado buses de campo como: Fieldbus, Hart, Devicenet, Profibus. . . A día de hoy: Actualmente los sistemas DCS son una realidad y prácticamente la totalidad de las grandes factorías confían en estos sistemas apoyados en PLCs para gestionar sus procesos productivos.
3.1.3
Estructura de un PLC
Los PLCs están formados por diferentes macro-unidades cada una de ellas con una funcionalidad concreta. Aunque cada PLC tiene sus variaciones, en general todos suelen estar compuestos por unos elementos comunes (ver Figura 3.5): Central Power Unit (CPU): La CPU es la encargada de leer e interpretar las instrucciones guardadas dentro de la memoria de programa. En función del PLC, se dispondrá de un procesador con una arquitectura de 8, 16, 32 o incluso 64 bits. Mediante este procesador se pueden realizar sumas, divisiones, multiplicaciones u operaciones lógicas. A la hora de escoger un PLC y fijarse en la CPU se deberá tener en cuenta, entre otras 13
cosas, cuales son las necesidades de timing actuales y la futura expansión del sistema. En función de los requisitos de timing se comprobará que el ciclo de scan se adecue a este tiempo. El ciclo de scan es uno de los conceptos clave a la hora de entender los PLC. En un ciclo de scan se realizan las siguientes acciones [Ord]: 1. Lectura de señales de entrada: Lee de memoria el valor de los sensores acoplados a las interfaces de entrada. 2. Ejecución de instrucciones del programa: Se realizan la toma de decisiones, cálculos de siguiente movimiento. . . 3. Escritura de señales de salida a las interfaces de salida: Se envían los valores calculados a las interfaces de salidas. 4. Diagnóstico: En esta fase se comprueba el estado de todos los periféricos y las condiciones de degradado. Esta parte es de vital importancia dado que normalmente los sistemas a automatizar están sometidos a fuertes normativas de degradado y protección. Memoria: La memoria es donde se almacena toda la lógica de control. Los PLC suelen incorporar varios de estos tipos de memoria, tanto Read Only Memory (ROM) como Random Access Memory (RAM), Programmable Read Only Memory (PROM), Electrical Erasable Programmable Memory (EEPROM). La memoria es un elemento importante del PLC y deberá ser escogida en función del programa que se quiera crear para comandar el sistema automático. Fuente de alimentación: La fuente de alimentación merece la pena ser nombrada dado que normalmente, los PLCs suelen estar situados en entornos con un gran ruido eléctrico. Para intentar mitigar los posibles problemas generados por este tipo de ruido eléctrico, se utilizan fuentes de alimentación de gran calidad. Las fuentes de alimentación variarán en función del PLC. Las fuentes de alimentación suelen llevar protecciones para los picos de tensión y para las bajadas de tensión. Además, suelen ser capaces de mitigar el efecto de estos fenómenos durante un tiempo determinado (de 1 a 5 ciclos). Una vez transcurrido dicho tiempo, la fuente producirá un comando para apagar de forma controlada el PLC e informará de un defecto. Sistema de entrada/salida: Los elementos de entrada/salida han ido evolucionando poco a poco. La diferencia principal entre un computador de propósito general y un PLC son las cartas de entrada salida. Estas cartas tienen una circuitería que permite desacoplar la parte de potencia de la parte de control. Las cartas de entrada/salida pueden ser tanto analógicas como digitales permitiendo así hacer del PLC un dispositivo versátil.
3.1.4
Principales fabricantes
En la Tabla 3.1 se muestra una relación con los fabricantes más relevantes en el sector de los PLCs. Normalmente, por cada sector, hay un fabricante concreto que destaca frente al 14
Figura 3.5: Modicom 084
resto, sin embargo, en sectores como la industria del automóvil puede que coexistan varios fabricantes de PLCs. Es precisamente esta fidelidad a los fabricantes lo que ha llevado a la creación de diversos estándares para facilitar la programación de estos dispositivos. Por poner un ejemplo, Siemens está liderando la industria del automóvil junto a Omron. Existen diversos estándares dentro de cada fábrica que proporcionan pequeños bloques de función simplificando así la labor de los programadores. Debido a la fidelidad de las industrias a los fabricantes de PLCs la barrera de entrada es bastante elevada por lo que para presentar un alternativa viable se deberá intentar imitar en la mayor parte posible la arquitectura de dichos PLCs de modo que sea sencilla la transición de los diversos estándares a la nueva plataforma.
3.1.5
Ventajas
Como ya se ha comentado durante esta breve revisión de los PLC, estos dispositivos están claramente asentados en el mundo de la automatización industrial debido a sus diversas ventajas que hacen de ellos una apuesta segura para las empresas. Entre las ventajas más relevantes podemos destacar las siguientes: Seguridad: Se tratan de dispositivos muy seguros tanto a nivel de software como a nivel hardware. Es en este último nivel donde estos dispositivos tienen una clara ventaja al ser ensamblados con materiales de muy alta calidad y bajo estándares de seguridad muy restrictivos. Aun con esta seguridad no siempre es posible confiar en ellos, como caso de ejemplo se podría hablar de Stuxnet [Stu] y [Lan13] . Garantía: La mayoría de fabricantes proveen de garantías que cubren a la empresa en caso de que exista algún parón en producción debido a un fallo en un PLC provocado por un fallo interno del mismo. Este punto es muy importante para las empresas de automatización dado que un parón en producción puede suponer unas perdidas de una cuantía considerable. Modular: Los sistemas se suelen comprar en forma modular, esto es, se puede comprar el PLC por un lado y por otro lado las cartas de expansión de entrada/salida o de comunicaciones según se necesite. Una vez acoplada al sistema dicha tarjeta de expansión el PLC la reconocerá sin ningún tipo de problema y estará lista para ser uti15
lizada. Esta ventaja permite crear diseños modulares de manera muy rápida ya que los controladores han sido diseñados con ese propósito. SCADA:
Los sistemas de automatización deben mostrar una interfaz de usuario al técnico de tal manera que de una forma rápida este último sea capaz de comprobar el estado del proceso a controlar. Los PLCs están dotados de poderosos programas de diseño SCADA de modo que se simplifica mucho a los programadores las labores de representación. Protocolos de comunicación: Tal y como se verá en la Sección 5.2.2, las comunicaciones entre los PLCs y los distintos dispositivos distribuidos por la planta de producción se realiza mediante buses de campo. Estos buses de campo fueron pensados para ser operados por los PLCs por lo que la utilización de los mismos es «trivial».
3.1.6
Desventajas Precio: El precio que deberá asumir una fábrica o en general cualquier empresa que desee contar con este tipo de dispositivos para automatizar algún proceso es muy elevado. Este precio elevado viene en parte justificado por la seguridad que proveen, sin embargo, no todos los procesos son igual de críticos y no todo el precio está justificado por esta característica. Privativo: El software y hardware privativo está a la orden del día en la industria. Los ordenadores industriales suelen utilizar diversos sistemas operativos de Microsoft, los sistemas Enterprise Resource Planning (ERP) son completamente cerrados y para completar todos los niveles, los sistemas PLCs son cerrados también. El hecho de que un sistema sea cerrado no solo es una cuestión ética [fsf] también es una cuestión de seguridad. Con un sistema de control con software privativo y hardware privativo jamás se tendrá el control completo del sistema. Esto puede suponer problemas como los de Stuxnet donde el único capaz de solucionar el agujero de seguridad era el fabricante debido a su código cerrado. Además, para programar así como para gestionar alguno de estos sistemas se requieren de programas que son mantenidos y actualizados por el fabricante. Si en algún momento el fabricante deja de dar soporte a esa familia de dispositivos puede que no sea posible solucionar problemas de seguridad o mejorar dicho programa. Sistemas de gran tamaño: Normalmente estos sistemas basados en PLC están pensados para ser utilizados en sistemas de gran envergadura por lo que las pequeñas empresas tendrán el problema de tener hardware y software desaprovechado.
16
3.2 Fenómenos maker 3.2.1
¿Qué es el fenómeno maker?
El fenómeno hacedor o fenómeno maker en inglés, es una cultura o subcultura que deriva de diferentes culturas anteriores como la Do It Yourself (DIY) o la cultura hacker. La diferencia principal con estas culturas reside en que el fenómeno maker consiste en aunar tanto el software como el hardware junto con el bricolaje y otras disciplinas para crear novedosos productos y hacerlos públicos de tal modo que todas las personas puedan disfrutar de dichos productos. El fenómeno maker ha permitido la proliferación de muchas plataformas de desarrollo cuyos precios son considerablemente reducidos debido al público al que van dirigido. Desde microcontroladores hasta Field Programmable Gate Array (FPGA)s pasando por impresoras 3D se han unido a este fenómeno abriendo innumerables puertas a la imaginación. Uno de los elementos claves de este trabajo (Arduino) fue uno de los precursores de la cultura maker. Gracias al carácter libre de esta cultura, en este proyecto se ha podido estudiar e identificar cada una de las características de esta plataforma. Gracias también a esta cultura, en Internet se puede encontrar cantidades ingentes de información y documentación, facilitando mucho la labor de desarrollo. La cultura maker ha ido generando cada vez más adeptos[Tin]. En los últimos años han empezado a aparecer los llamados «Makerspaces» que son un derivado de los «Hackerspaces». El ejemplo más representativo de estos lugares de encuentro es el «Fablab» un lugar donde los maker pueden reunirse para mostrar sus creaciones o incluso desarrollar ahí sus ideas. Por citar alguno de los «Makerspaces» más relevantes se podría hablar de: Urban Workshop, Noisebridge, NYC Resistor, Pumping Station, TechShop. . . Sin duda alguna el fenómenos maker ha supuesto un gran aporte para la sociedad, poniendo a disposición de todos ,diseños e ideas que de otro modo estarían ocultas bajo fuertes patentes pagadas por grandes empresas. El fenómeno maker no solo es un fenómeno para hobbistas3 , este fenómeno ha llegado a las empresas. Un ejemplo de empresa maker es BQ. BQ, el fenómeno maker en la empresa BQ es una empresa joven y española, con una gran trayectoria que a día de hoy está fuertemente establecida en el mercado de la telefonía y de la tecnología. Una de las últimas apuestas de BQ ha sido la creación de una división maker que desarrolle productos libres y enfocados principalmente a dicha cultura. Algunos de sus productos estrella como Zowi (ver Figura 3.6a) son completamente libres, 3
Se refiere como hobbistas a aquellas personas que desarrollan algún tipo de dispositivo/producto únicamente por hobbie
17
esto significa, cualquier usuario puede acceder al software y estudiarlo o incluso modificarlo sin ningún tipo de inconveniente por parte de la empresa. Además del software, el hardware también es libre pudiendo replicar el diseño si así se quisiera.
(a) Robot de BQ Zowi
(b) BQ Zum Core
Figura 3.6: Dos de los productos maker de BQ
Otro producto bastante interesante es el BQ Zum Core (ver Figura 3.6b) el cual tiene la peculiaridad de ser un producto que ha sido derivado de otro producto perteneciente a la cultura maker. El BQ Zum Core muestra de forma clara, las posibilidades a nivel de mercado que supone esta cultura. BQ, apoyándose en Arduino como plataforma base a implementado mejoras creando su propio producto. El hecho de que Arduino sea libre permite a BQ reducir los costes de producción y de desarrollo dado que no tendrá que desarrollar de manera obligatoria herramientas (puede utilizar las existentes) y no debe pagar royalties por derivar de un proyecto existente. Esto conlleva en una bajada de precio que percibe el usuario. BQ ha visto en el fenómeno maker un nicho de mercado por explotar y por ello ha destinado muchos recursos humanos a este sector. BQLabs es un departamento de BQ que desarrolla productos para la comunidad maker. Estos productos luego pueden llegar a ser parte de su catálogo oficial como por ejemplo Zowi el cual posee de un repositorio en github desde donde se puede acceder a todos sus ficheros fuentes (https://github.com/bqlabs/zowi). Otro producto que dará mucho que hablar en los próximos años será la FPGA alhambra la cual es otro proyecto de BQ dentro de su departamento BQLabs. Mediante este producto se busca liberalizar el mercado de las FPGAs de modo que cualquier usuario pueda tener el control de todo el proceso de desarrollo dentro de las FPGAs cosa que a día de hoy es impensable. Como se puede observar con este ejemplo de empresa que ha adoptado el fenómeno maker, este fenómeno no solo se limita al ámbito hobbista, por el contrario estos productos pueden ser comercializados tal y como lo está demostrando BQ. 18
3.2.2
Impresión 3D
Sin duda alguna la impresión 3D ha sido uno de los máximos exponentes dentro de la cultura maker. Mediante estas peculiares impresoras los usuarios son capaces de crear todo tipo de objetos, desde pequeñas piezas para robots hasta otras impresoras 3D. Existen numerosos casos de éxito logrados con la impresión 3D en el ámbito de la medicina, la aeronáutica y otras disciplinas. El principio de funcionamiento de estas impresoras es muy sencillo. En primer lugar, se necesita un material especial llamado plástico Poliácido láctico (PLA) (también existen otros materiales sin embargo el más usado es el PLA), este plástico es un poliéster creado a partir de recursos renovables utilizando almidones y materia vegetal. Su punto de fundición es de 160o C. Para que la impresora sea capaz de modelar algo a partir de este plástico duro en primer lugar tiene que ser calentado hasta el punto donde sea maleable. De esta labor se encarga el extrusor . El extrusor (ver Figura 3.7 es la pieza más importante de la impresora 3D. Este elemento está formado por: Motor paso a paso: Motor que se utiliza para empujar el filamento desde la bobina hasta la base donde se va formando el objeto a imprimir. Engranaje de tracción: Esta pieza se encarga de que el filamento se deslice por el extrusor. Engranaje reductor: Es un dispositivo que cumple funciones meramente mecánicas. La finalidad de este dispositivo es la de aumentar la fuerza de arrastre sobre el PLA. Guía del filamento: Pequeño tubo de diámetro fijo que permite guiar al PLA de modo que este siga la trayectoria deseada. Hotend: Esta parte es muy importante dentro del extrusor. Mediante el hotend el filamento se calienta por su parte inferior mediante un tubo de modo que solo se caliente la parte que entrará en contacto con el objeto. Sensor de temperatura: Sensa la temperatura para realimentar el sistema de modo que este sepa que potencia debe dar a las diferentes partes. Boquilla de salida: A este cono llega el plástico derretido y se mantiene en este estado mientras sale por una pequeña abertura de un diámetro estipulado. Además del extrusor, la impresora cuenta con muchos más dispositivos de control y de gestión. Por poner un ejemplo, la impresora 3D «Prusa» está formada por un conjunto de motores para posicionar el filamento en los ejes X,Y,Z. Estos motores están controlados por una «Shield» de Arduino llamada Ramps. Además, la impresora cuenta con una pantalla LCD y un Arduino Mega 2560. De nuevo se puede ver como otro producto maker sigue la filosofía de la cultura. Utiliza elementos ya creados, en este caso el Arduino y lo personaliza 19
Figura 3.7: Extrusor impresora 3D (Fuente BQ)
para la finalidad concreta. Además, todos los planos de la impresora 3D así como los archivos fuente pueden ser descargados de forma gratuita. Las impresoras 3D son un ejemplo claro de la cultura maker permitiendo a los seguidores de este movimiento seguir creando nuevos objetos con acabados cada vez más profesionales. El modelo seguido dentro de BQ para adaptar el Arduino a su producto, es decir, la creación de la «Shield» Ramps es el mismo que se adoptará en este TFG tal y como se verá más adelante.
3.2.3
El fenómeno maker dentro del TFG
Anteriormente se ha hablado del fenómeno maker y se han citado ejemplos de diversos casos de éxito derivados de esta cultura. A continuación hablaremos de cómo el fenómeno maker ha influido dentro de la elaboración de este TFG. Como se verá a medida que se avance por el documento, para el desarrollo del prototipo se ha utilizado la plataforma Arduino. Esta plataforma deriva de la cultura maker y la mayoría de expansiones de esta plataforma siguen la misma filosofía. Gracias al fenómeno maker se ha reducido el tiempo de desarrollo debido a la gran cantidad de documentación que se puede encontrar en línea. Además, debido al software y hardware libre de Arduino se ha podido depurar «fallos» (que se verán a lo largo del documento) que de otro modo hubiera sido imposible. Por otro lado, la plataforma Raspberry Pi ha sido utilizada en este proyecto con el objetivo de reducir los costes asociados a los ordenadores de gestión. De nuevo, esta plataforma sigue la filosofía maker y nos ha brindado las mismas ventajas que las citadas para Arduino. 20
Por último y no por ello menos importante hay que citar el software Kicad del cual se hablará en la Sección 4.4.1. Este software se vio envuelto en un desarrollo intensivo tras el descubrimiento y utilización dentro de la cultura maker. Kicad es un software CAD para el diseño de circuitos electrónicos que ha sido utilizado durante este proyecto. Como se puede observar el «core» del proyecto ha sido desarrollado basándose en plataformas ya existentes y completamente abiertas, esto permite mantener un control del sistema mucho más preciso además de permitir ahorrar tiempos en el desarrollo dado que estos módulos ya han sido probados y los posibles fallos se encuentran bien documentados.
3.3 Arduino En este proyecto se ha utilizado el como plataforma base un Arduino Mega. En esta sección se pondrá en contexto la plataforma Arduino y se verá la progresión que ha seguido desde sus inicios.
3.3.1
Historia
Arduino apareció en el año 2006 de la mano del Interaction Design Institute Ivrea. El objetivo de este proyecto era simplificar a sus alumnos el proceso de aprendizaje de programación de sistemas empotrados. Durante esa época se utilizaba el microcontrolador BASIC Stamp basado en BASIC. Aunque es un microcontrolador sencillo, su precio era algo elevado pudiendo llegar a costar hasta 100 dolares. Massimo Banzi empezó entonces el desarrollo de Arduino junto a 5 compañeros más. Los primeros desarrollos se centraron en la creación de la placa de pruebas así como la creación del lenguaje Wiring y el entorno de desarrollo [The]. Una se consiguió unificar todas las partes y comprobar que las mismas funcionaban sin problema, en parte gracias al esfuerzo de Hernando Barragán, el instituto de Ivrea decidió minimizar el diseño y hacerlo más amigable para el usuario dado que las primeras versiones distaban mucho de ser un producto listo para ser comercializado (ver Figura 3.8). Según Banzi, el proyecto nunca se pensó como una idea de negocio, por el contrario se buscaba crear un producto de hardware y software abierto. Finalmente una vez asentados los primeros prototipos y en funcionamiento en el instituto de Ivrea, se inició el periodo de fabricación en serie. Uno de los requisitos claves a la hora de fabricar esta plataforma era que el coste final no superara los 30 euros, requisito que en los primeros productos se cumplió.
3.3.2
Arquitectura
Arquitectura hardware Arduino tiene una cantidad extensa de productos cada uno con características muy diferentes. En este punto se hablará de los productos más comunes, es decir, del Arduino Uno y del Arduino Mega, ambos microcontroladores de 8 bits. Aunque en este documento se hable 21
de las placas de 8 bits esto no significa que Arduino no posea placas con mayor potencia. En la Tabla 3.2 se puede comprobar alguno de los productos del fabricante.
Figura 3.8: Plataforma wiring (Fuente: Massimo Banzi)
La placas de desarrollo están basadas en un microcontrolador AVR. Los microcontroladores AVR están fabricados por la empresa Atmel la cual tiene un gran recorrido dentro de la fabricación de este tipo de microcontroladores. Los microcontroladores AVR están pensado para todo tipo de aplicaciones, desde control analógico hasta I OT. Junto con el microcontrolador AVR se incorporan diferentes componentes de seguridad. Estos componentes de seguridad (diodos, capacitores, ptc) se ponen debido al carácter educativo del proyecto. El Arduino está pensado para ser utilizado por gente con poca experiencia en el ámbito de la electrónica, de aquí la razón de dichas protecciones adicionales. Para expandir el Arduino, los diseñadores crearon lo que se ha convertido en un estándar no oficial de pines. Mediante estos pines es posible añadir escudos o shields en ingles con diferentes funcionalidades. En la Figura 3.9 se puede ver un ejemplo de estos shields.4 .
(a) Shield ethernet
(b) Shield controladora de motores
Figura 3.9: Shields de expansión para Arduino 4
En este proyecto se creará un shield para el Arduino
22
Arquitectura software Si por algo se ha diferenciado Arduino ha sido por su facilidad de programación. Algunos autores nombran Arduino como un lenguaje en si mismo. Sin embargo esto no es cierto. Arduino utiliza en su mayor parte la librería avr-libc. Esta librería es de código libre y se puede descargar desde el siguiente enlace: http://www.nongnu.org/avr-libc/. La librería avr-libc contiene la mayor parte de las funciones necesarias para programar cualquier microcontrolador. Proporciona funciones como _delay_ms() o sfr_8mem() que permiten manejar diversos aspectos del microcontrolador. Pero la librería no se queda aquí, también incorpora la mayor parte de las funciones de libc de tal manera que dispondremos de gestión de la memoria dinámica con las funciones típicas (malloc() y free()) además de control de interrupciones. Por otro lado, Arduino provee de lo que sin duda alguna ha sido clave a la hora de animar a los usuarios a programar en esta plataforma, esto es, la librería Arduino.h. Esta librería, programada en C++ permite acceder a la mayoría de las funciones del microcontrolador desde una interfaz de más alto nivel. Además añade algunas variables estáticas como Serial1, Serial2, etc que hacen que el usuario no tenga que preocuparse por detalles de más bajo nivel. El manejo del microcontrolador con esta librería supone una sobrecarga que deberá tenerse en cuenta para aplicaciones críticas. Por poner un ejemplo, poner a un valor 5 voltios 8 pines de un mismo puerto utilizando la librería Arduino, más concretamente la función (digitalWrite()) supone 8 escrituras, sin embargo, realizar esta misma acción por medio de instrucciones de bajo nivel supone una única escritura. Junto a la librería Arduino.h y todo lo comentado anteriormente, Arduino incorpora una pieza clave llamada bootloader. El bootloader es el encargado de cargar el programa desde el ordenador hasta la memoria flash del microcontrolador. El bootloader, también es capaz de realizar la gestión del protocolo USB (esto no es del todo cierto dado que existe otro pequeño circuito integrado que realiza esta acción), esto permite que el Arduino no requiera de ningún tipo de hardware extra para programarlo, únicamente un cable USB (en la mayoría de los casos). Por último, Arduino también incorpora varios Integrated Development Environment (IDE) que permiten programar el Arduino así como añadir librerías que simplificarán la interacción con el microcontrolador. En la Figura 3.10 se puede ver el aspecto del IDE más utilizado actualmente5 . 5
Arduino está trabajando en un nuevo IDE basado en atom
23
Figura 3.10: Entorno Arduino
3.3.3
Casos de éxito
Para mostrar la repercusión de esta plataforma, en este apartado se describirá brevemente algunos casos de éxito que se han basado en Arduino: Robot Zowi: El robot Zowi de BQ ha sido fabricado como uno propuesta de uno de los grupos dentro de BQLabs. Este robot cuenta con una conexión con Android que permite interacturar con el mismo. Algunas de las acciones que realiza este robot son: andar, bailar, gesticular mediante una matriz led, etc. Arduino es la plataforma utilizada para conectar cada uno de los servomotores y dar «vida» a este robot. Ahondando un poco más en el diseño y siendo exactos Arduino no es como tal la plataforma utiliza dado que BQ realiza derivados de Arduino, sin embargo el software subyacente así como el conexionado es el mismo Impresora 3D prusa: En la Figura 3.11 se puede ver el aspecto de esta impresora. Fabricada por BQ, esta impresora 3D es sin duda alguna una de las impresoras más utilizadas a día de hoy. Para controlar cada uno de los motores paso a paso así como la cama caliente, extrusor y lcd, se utiliza una shield llamada Rasp. Esta shield sigue el conexionado Arduino R3. Además, la impresora se vende junto a un Arduino Mega 2560 sin modificar por lo que claramente esta impresora hace uso intensivo de Arduino. Ardupilot: Los drones son pequeños cuadricopteros que permiten realizar diversas mi24
siones como: salvamento, grabación, carreras, etc. Con el auge de estos pequeños cuadricopteros la comunidad maker decidió utilizar la plataforma Arduino para crear un controlador universal para los drones. La plataforma ArduPilot fue incrementando su desarrollo hasta convertirse en una plataforma capaz de comandar todo tipo de vehículos, desde helicopteros hasta aviones pasando por barcos. Sin duda alguna Ardupilot es un caso de éxito notable dentro de la comunidad Arduino y que a día de hoy ha permitido crear diversas compañías especializadas en esta tecnología. Sondas espaciales: En los últimos años se han desarrollado diversas sondas espaciales con fines educativos. Estas sondas permiten recoger diversos datos para más tarde estudiarlos. La mayoría de estas sondas utilizan un Arduino junto a Raspberry Pi para la recogida de datos.
Figura 3.11: Impresora 3D prusa
Estos son algunos de los casos de éxito que podemos encontrar a día de hoy. Sin embargo, muchos otros proyectos han tenido mucha relevancia aunque no hayan sido nombrados en este apartado.
3.3.4
Ventajas
A continuación citaremos algunas de las ventajas de utilizar Arduino frente a otros microcontroladores de otras marcas como por ejemplo ARM. Libre: Tal y como ya se ha comentado, el Arduino es completamente libre, esto es, todos los ficheros fuentes (tanto hardware como software) están disponibles para su descarga y modificación. Este hecho permite tener un mayor control sobre el diseño. Estandarizado: Aunque no es un estándar de jure si que se puede considerar un estándar de facto dado que a día de hoy no solo tarjetas basadas en microcontrolador si no que algunas FPGAs como Artix o Smartfusion 2 started kit están utilizando dicho conexionado en la distribución de sus pines. 25
Numerosas placas de expansión: En el mercado existen placas de expansión o shields para casi todos los propósitos. Existen placas para agregar ethernet al Arduino así como placas para dotar a la plataforma de conexión GPS, Wifi, o Bluetooth. La facilidad de conexión así como el software existente para controlar dichas placas hacen de esta solución una manera muy sencilla de reducir el coste de diseño o de prototipado. Barato: El coste de esta plataforma dependerá del modelo concreto, sin embargo, la gama de 8 bits tiene precios que no superan los 30e un precio muy competitivo si se compara con otras soluciones como alguna placa de desarrollo ARM. Documentación: En la red existen numerosas páginas de documentación tanto a nivel software como hardware por lo que muy probablemente cualquier duda que pueda producirse a la hora de diseñar algo basado en Arduino estará resuelta en Internet. Estas son solo algunas de las ventajas de esta plataforma sin embargo son muchas otras las razones que hacen de esta plataforma un lugar de desarrollo a tener en cuenta a la hora de realizar los prototipos o incluso los diseños finales de los sistemas electrónicos.
3.3.5
Desventajas
A continuación se mostraran algunas desventajas de utilizar la plataforma Arduino frente a otras plataformas del mismo estilo. Sobrecarga: La capa de más alto nivel provista por la librería Arduino.h hacen que el tamaño disponible en flash para los datos y el programa se reduzcan. Esto es debido al carácter educativo y a las diversas simplificaciones que se intentan realizar. Entorno de desarrollo: Aunque Arduino se puede configurar para ser utilizado desde otros entornos de desarrollo como Eclipse o AVR Studio, el entorno principal y patrocinado dista mucho de ser un entorno profesional. A día de hoy este entorno no permite la gestión de versiones integrada, proceso de compilación personalizada, gestión de proyectos, etc. Como se puede observar las desventajas son mínimas y es por ello que Arduino se puede considerar una de las plataformas basadas en microcontrolador más exitosa de los últimos tiempos.
3.4 Industria 4.0 La industria desde sus inicios ha estado en constante evolución. En 1800 la creación de la máquina de vapor y la puesta en producción del primer telar mecánico supuso un cambio social, económico y cultural que marcó el futuro de los países desarrollados. Este acontecimiento recibe el nombre de la primera revolución industrial. Sin duda alguna hoy no tendríamos muchas de las facilidades de las que disponemos si no fuera por la máquina de vapor. En 1900 tiene lugar la segunda revolución industrial. Esta revolución se debió a la aparición 26
de la energía eléctrica y la producción en cadena. Del mismo modo que en la primera revolución indutrial, esto supuso un cambio socioeconómico así como diferentes dilemas éticos y morales debido al lugar del trabajador dentro de la cadena productiva. La producción en cadena se basa en los principios del Fordismo[Pag95]6 . El Fordismo se basa en estrategias de expansión del mercado. La razón radica en que si existe un mayor volumen de unidades de un producto a un precio reducido la producción será suficiente para satisfacer la demanda. El Fordismo también trae consigo una revolución social muy criticada por el marxismo y otras corrientes sin embargo eso queda fuera del alcance de este trabajo. A la segunda revolución industrial le sigue una tercera que incorpora de los PLCs así como los sistemas de la información en las diferentes etapas, esto es, sistemas ERP, sistemas SCADA, etc. . . Actualmente nos encontramos ante la cuarta revolución industrial que promete diversas mejoras en muchos planos mediante sistemas ciber-físicos, industria y productos inteligentes, I OT, hiperconectividad y big data.[dIEyT]
3.4.1
Contextualización en la industria española
España con 1,4 millones de dolares de Producto Interior Bruto (PIB) es la quinta potencia económica europea y la número trece a nivel mundial (ver Figura 3.12).
Figura 3.12: PIB a partir de los datos del Banco Mundial, Fuente: Instituto Nacional
Alrededor del 13 % del valor añadido del país proviene de la industria. De este 13 %, el 50 % deriva de tres sectores: 1. Alimentación y bebidas 2. Manufactura de metales 6
El nombre Fordismo deriva de Henry Ford creador de la línea de ensamblaje
27
3. Vehículos de motor y componentes Por otro lado, la industria española presenta una distribución que deberá ser tenida en cuenta a la hora de iniciar la actualización de las industrias hacia la industria 4.0. La mayor parte del tejido empresarial industrial español lo conforman las Pequeña Y Mediana Empresa (PYME), por lo que incidir en este sector es de vital importancia. Otro punto importante a la hora de implantar soluciones basadas en las TIC es la infraestructura de comunicaciones. En España en los últimos años se ha desplegado una gran infraestructura Fiber To The Home (FTTH) por lo que en este sentido la mayor parte del tejido industrial está preparado para recibir esta nueva revolución.
3.4.2
Los beneficios de la industria 4.0
La industria 4.0 se basa en el paradigma de acercar lo físico a lo virtual, esto es, todo artefacto físico tiene una representación virtual exactamente igual. La representación virtual posibilita la aparición de nuevos procesos y mecanismos que permiten una gestión más eficiente de los recursos y de los tiempos de producción. Aplicando la transformación digital a la industria obtenemos beneficios en toda la cadena de valor, más concretamente en el producto, proceso y modelo de negocio. Niveles de impacto Proceso: La industria 4.0 aplicada a los procesos brinda dos alternativas: mejorar los procesos actuales de manera que estos sean más eficientes y flexibles o crear nuevos procesos que apliquen de forma directa las directrices de la industria 4.0. Como ejemplo podríamos nombrar la impresión 3D que facilita la creación de prototipos reduciendo los costes asociados y reduciendo también el TTM. Existen aviones de combate que a día de hoy están activos y que han solucionado algunos de sus problemas mediante la impresión 3D de alguna de sus piezas. También la industria de las prótesis está utilizando esta tecnología para crear prótesis que facilitan la recuperación de paciente. Por otro lado, la aplicación de tecnologías digitales garantiza una mayor eficiencia y una mayor flexibilidad reduciendo así los plazos y tiempos de espera de los clientes Producto: La industria 4.0 también se aplica a la inserción de tecnologías de la información a los productos de tal manera que aumente la trazabilidad de los mismos y se añadan funcionalidades extra de cara al usuario. Un caso representativo de esta evolución se encuentra en el sector del automóvil donde el 45 % del valor del producto se encuentra en la electrónica y en los componentes digitales. Modelo de negocio: La industria 4.0 y los habilitadores tecnológicos de los cuales se hablará más adelante permiten abrir unos nuevos modelos de negocio como podría ser el alquiler de maquinaria mediante tarificación en base al uso. Para poder llevar a cabo este modelo de negocio, en este caso sería necesario que la maquinaria con28
tará con sensores de diferentes tipos para medir el uso de la máquina. Dentro de los habilitadores tecnológicos se encuentran los sensores.
3.4.3
Retos y propuestas de la industria 4.0
Con la industria 4.0 se identifican nuevos retos y necesidades que permitirán aumentar la eficiencia de los procesos productivos. Uno de los principales retos viene de la mano del cliente hiperconectado, esto es, a día de hoy el cliente dispone de un sin fin de información a la que puede acceder desde su smartphone, tablet u ordenador. El cliente deja de ser un eslabón separado de la cadena de producción para ser parte del proceso productivo. El cliente podrá saber en cualquier momento la situación de su pedido y podrá dentro de lo posible interactuar con el proceso de producción de tal manera que se le permita formar parte de la toma de decisiones que conllevará a la elaboración de su producto. Lógicamente esto conlleva una gran intervención de las máquinas de producción que deberán adaptarse a las tecnologías de la información bien mediante la actualización o mediante el reemplazo de dichas máquinas por máquinas 4.0. Aquí se hace notable un nuevo concepto, que cambia radicalmente con respecto a lo planteado por el taylorismo y el fordismo. La cadena de producción no esta gobernada por stocks de producción sino por demanda. Especializando la fábrica a cada uno de los pedidos realizados, esto es, cada producto se trata como un individuo y no como un elemento más dentro de un grupo de productos. Desde esta idea aparece una nueva necesidad como es la necesidad de sistemas interoperables y abiertos que permitan gestionar la información generadas por todas las máquinas así como por el cliente de forma homogénea. Esta homogeneidad está siendo tratada por la World Wide Web Consortium (W3C) entre otros. En la Figura 3.13 se puede ver los diferentes niveles organizativos dentro de la industria. El nivel ERP deberá adoptar una posición inteligente de tal forma que este sea capaz de administrar la información proveniente de cada unas de las máquinas y sea capaz de recomendar diferentes tipos de acción. Otra de las ventajas de la industria 4.0 es la de ahorrar dinero en el mantenimiento apoyándose en el sistema ERP y en lo sensores acoplados a cada una de las máquinas de tal forma que se pueda aplicar un mantenimiento preventivo en momentos no críticos.
3.4.4
La industria 4.0 en el proyecto
El prototipo presentado en este proyecto intentará demostrar las capacidades de los sistemas abiertos y la posición de los mismos dentro de la industria 4.0. Mediante este proyecto se podrá comprobar cómo mediante software libre y hardware libre se simplifica la expansión del sistema con respecto a otras soluciones basadas en software privativo. De este modo se verá cómo utilizando diferentes piezas software se puede expandir el diseño con el mínimo coste siempre y cuando se opten por soluciones abiertas. Aunque no 29
Figura 3.13: Niveles organizativos en la industria
es el objetivo principal del proyecto, se verá cómo añadir un pequeño sistema de fichaje es tan sencillo como unas pocas líneas de código. Cosa que en sistemas convencionales basados en PLCs tendría que ser realizado mediante software externo probablemente delegando esta tarea a los sistemas ERP
3.4.5
Casos de éxito
La implantación de la industria 4.0 aun está en una etapa preliminar. Por esta razón numerosas empresas están haciéndose hueco en el sector. A continuación se nombrará alguna de estas empresas: MESlider Gestión de Operaciones SL: MESBook es el primer sistema que lleva a acabo la representación virtual de los objetos físicos. El sistema MESBook pretende gestionar de forma íntegra la fábrica en tiempo real. Mediante este sistema el equipo directivo puede saber en cada momento dónde se están produciendo pérdidas económicas dentro del proceso productivo de tal manera que se puedan tomar acciones inmediatas en dicho proceso. MESLider ha recibido numerosos premios por su producto MESBook. Libelium[Abo]: Libelium es una empresa centrada en el sector I OT. El principal aliciente de la plataforma Libelium es su sistema de Wireless Sensor Network. Estas plataformas permiten crear redes de sensores mediante dispositivos de bajo coste como Wasmote[New]. Wasmote ha sido uno de los últimos productos de Libelium que se ha adaptado a la industria 4.0, incorporando interfaces de comunicación como RS232, RS-485 o incluso CAN-Bus y Modbus que son algunos de los protocolos de comunicación más utilizados en la industria (junto a Profibus y Profinet). Libelium se 30
ha implantado en diversas plantas industriales abriéndose hueco en el mercado de la industria 4.0. Inductive automation: Con su software Ignition pretende resolver dos de los niveles vistos en la Figura 3.13, más concretamente el nivel Manufacturing Execution System (MES) y el nivel SCADA añadiendo también un nivel que permite incorporar algunos de los retos de la industria 4.0 a su sistema, esto es, I OT. Algunas de las empresas que están utilizando este software son: CocaCola, WaltDisney, Kellogg’s, etc. . . Ignition es un sistema que dice reinventar SCADA mediante un sistema basado en la web, seguro, en tiempo real, rápido y escalable[Sca]. Ignition es sin duda una plataforma referente en cuanto a la nueva implementación de los sistemas SCADA basados en los sistemas de la información, sin embargo, todavía requiere de una inteligencia artificial que permita analizar diferentes factoras tal y como lo hace MESBook. Aquí solo se han citado 3 empresas, sin embargo la lista de pequeñas y medianas empresas que se están incorporando a este sector crece día a día. Algunas de estas empresas ofrecen servicios de consultoría, otras plataformas ERP complejas como Odoo[Ope] o incluso plataformas I OT como Libelium para la sensorización de los procesos productivos.
3.5 Alternativas PLCs basadas en Arduino Como ya se ha nombrado anteriormente, en este proyecto se buscará realizar un prototipo como alternativa a los sistemas de automatización basados en PLCs. Para ello, tal y como se verá más adelante, antes de realizar el diseño de este prototipo se buscaron diferentes alternativas ya existentes basadas en Arduino. Aunque tal y como veremos a continuación, se encontraron alternativas con diferente grado de adecuación, llegando alguna incluso a ser válida con mínimos cambios, la empresa, con el objetivo de reducir los costes así como tener un diseño de referencia para futuros proyectos, se optó por un desarrollo ad hoc para este proyecto. A continuación se dará una breve explicación de cada uno de los productos estudiados.
3.5.1
ArduPLC
ArduPLC es un PLC basado en el Arduino Uno y Arduino Mega, más concretamente: Atmega2560 y Atmega328p. Entre las características de este PLC podemos encontrar: Microcontrolador Atmel ATmega328: Microcontrolador utilizado por el Arduino Uno. Programación directa mediante entorno de desarrollo Arduino: El PLC lleva incorporado el bootloader de Arduino por lo que desde el mismo entorno de desarrollo se podrá programar este PLC 4 salidas basadas en relés: En este caso, para aislar las salidas de la lógica se ha optado por la utilización de relés. Los PLC convencionales utilizan este tipo de desacoplo, esta 31
es la razón por la que ArduPLC mantiene esta línea. Entradas optocopladas: El ArduPLC cuenta con 4 entradas optocopladas, esto permite que en todo momento se tenga aislado el «exterior» del «interior» (lógica y potencia). Entradas analógicas: Diferentes entradas analógicas desde 0 a 10 voltios o desde 0 a 5. Comunicación RS485 aislado: Este punto es muy importante dado que en el diseño final realizado se tuvo muy en cuenta este tipo de aislamiento. Más adelante se verá la implementación de esta característica. Regulador conmutado: El regulador conmutado tiene sus ventajas y desventajas según la aplicación, a continuación veremos la utilización de este regulador dentro del esquemático. Zócalo para shields compatibles con Arduino: Este apartado es un punto a favor del ArduPLC debido a que mediante este zócalo podríamos expandir para cualquier característica nueva. Caja para carril DIN: Los PLC y en general, en la industria este tipo de conexión es el preferido dado que los armarios de conexiones suelen llevar este tipo de carril (ver Figura 3.14).
Figura 3.14: Pequeño armario de conexiones
3.5.2
Análisis del producto
Precio En la página oficial del desarrollador el precio de este PLC es de 84esin IVA para el ArduPLC basado en Arduino Uno y 165esin IVA para el ArduPLC basado en Arduino Mega, a esto habría que añadirle el coste de una fuente de 24 voltios estándar. El precio del 32
producto no es excesivo dado que tal y como veremos en la Sección 3.5.2 el ensamblaje así como las diferentes protecciones son de buena calidad. Expansión El ArduPLC ha sido pensado para ser expandido, quizás la opción más viable es el ArduPLC basado el Arduino Mega. Este PLC cuenta con más salidas basadas en relés y además cuenta con un puerto Ethernet. ArduPLC tiene la característica de poseer un zócalo para tarjetas shield. Mediante este zócalo se pueden implementar funciones extras en hardware de manera muy sencilla, por ejemplo, en el caso de que se necesitara controlar un motor paso a paso, se podría crear una shield con un L298 y diferentes jumpers de tal manera que ahora el ArduPLC podría aceptar conexiones para motores paso a paso. El sistema modular en el que se han basado el ArduPLC está basado en el puerto I2C, este puerto está recomendado para comunicaciones Inter-Circuitos por lo que considero una buena elección el uso de este protocolo. Aunque en la web señalan las posibilidad de expansión mediante el protocolo I2C, en la labor de investigación no se ha encontrado ningún ejemplo que lo demuestre. Implementación Debido a que ArduPLC tiene a disposición de todos los usuarios sus esquemáticos, podemos estudiar la implementación para comprobar si se adecua a nuestros requisitos o no. Además, en base a esta implementación podemos justificar el precio del diseño final. El repositorio se encuentra disponible desde github y se puede acceder desde la siguiente url: https://github.com/raymirabel/ArduPLC. A continuación veremos cada una de las partes de implementación más interesantes desde el punto de vista del proyecto desarrollado en este TFG Protecciones ESD y filtrados: Aunque las protecciones ESD en este proyecto no es un punto prioritario, el diseño teniendo en cuenta estos fenómenos siempre es un acierto. Como se puede ver en la Figura 3.17 cada entrada de alimentación está filtrada mediante capacitadores de 100 nf. El uso de este tipo de capacitadores permite que las altas frecuencias sean derivadas a tierra (ver Formula 3.1). Si la frecuencia fuera infinita entonces la impedancia capacitiva sería mínima y por lo tanto se comportaría como un cortocircuito, es decir, derivaría todo a tierra. Por otro lado el ArduPLC incorpora núcleos de ferrita y Transient Voltage Suppressor (TVS) para eliminar los voltajes transitorios debido a descargas electrostáticas. En la Figura 3.18 se puede ver un ejemplo de un TVS. Desacoplo control-potencia: Como es de esperar, el ArduPLC cuenta con salidas basadas en relés tal y como se puede ver en la Figura 3.16. Los relés sin embargo tienen el problema de ser un dispositivo mecánico y por lo tanto tienen un desgaste con el 33
tiempo. Para este proyecto no era necesario el uso de relés por lo que este tipo de desacoplo no resultaría útil. ArduPLC no dispone de salidas optocopladas lo cual ayudaría a comandar diferentes interfaces de potencia TTL. Aislamiento del bus de comunicaciones: El bus de comunicaciones RS-485 es un punto de interferencias significativo. Por otro lado, un fallo en el proceso de despliegue en el cual se hiciera una descarga a uno de los cables podría quemar cada uno de los controladores unidos al bus. En la Figura 3.15 se puede ver la opción elegida para optocoplar el bus 485. Tal y como se explicará en el desarrollo de la PCB la optoacoplación se realiza en la parte TTL. En este caso se ha utilizado el integrado HCPL0600 este optocoplador está pensado para optocoplar las líneas de comunicación por lo que se podrá alcanzar las velocidades máximas sin ningún problema.
Figura 3.15: Optoacoplación línea 485
Figura 3.16: Salida aislada mediante relés
Xc =
1 2∗π∗f ∗C
Siendo :
(3.1)
f → F recuencia C → Capacitancia 34
Figura 3.17: Ejemplo de entrada filtrada
Figura 3.18: Protección frente a voltajes indeseados
Valoración ArduPLC es una alternativa a los PLC bien implementada. El diseño modular así como las protecciones tanto ElectroStatic Discharge (ESD) como el aislamiento potencia-control hacen de este dispositivo un sistema de control seguro. No se ha utilizado ArduPLC para el proyecto debido al precio elevado y al exceso de periféricos no necesarios además de 35
la necesidad de la empresa Automatinfo de tener un proyecto de referencia a medida. Este proyecto no se basa en la creación de una alternativa genérica para los PLC, se basa en una alternativa para un proceso concreto mostrando así las posibilidades reales del software libre y hardware libre y demostrando también el nicho de mercado existente dentro del mundo de los PLC, ArduPLC es un ejemplo de aprovechamiento de dicho nicho de mercado.
3.5.3
Industrino
Industrino, al igual que ArduPLC es otra alternativa a los PLC basada en Arduino. Industrino está pensado para proyectos de menor envergadura, esto es, proyectos de domótica, puertas automáticas o pequeñas automatizaciones. Industrino tiene dos vertientes o dos productos diferenciados: 1. Industrino Proto (ver Figura 3.19): Este producto contiene una pequeña placa protoboard desde la cual el usuario puede añadir el hardware que crea necesario. 2. Industrino Ind.I/O (ver Figura 3.20): Plataforma sin ningún tipo de posibilidad de modificación, esto lo hace más robusto al no tener «conexiones abiertas».
Figura 3.19: Industrino Proto Kit, fuente: https://industruino.com
Las características más relevantes de esta alternativa son: Estandarizado para la industria: Los niveles de voltaje estándares para la industria en el apartado de control son de 24v digitales y de 0-10 voltios para las entradas y salidas 36
Figura 3.20: Industrino IND, fuente: https://industruino.com
analógicas. Aislamiento RS-485: El bus 485 se encuentra aislado de modo que tanto las interferencias externas así como los posibles riesgos en el despliegue queden subsanados. DIN: Al igual que ArduPLC, industrino cuenta con una interfaz DIN, esto permite colocarlo en los armarios de conexión de una manera muy cómoda. 128x64 LCD: Industrino cuenta con una pequeña pantalla de 128x64 píxeles que permite tener una pequeña HMI. Compatible con entorno Arduino: Mediante la incorporación del bootloader y las creación de los diferentes ficheros para que el PLC sea reconocido. Esto implica crear fichero de mapeo de entrada/salida y diferentes ficheros de reconocimiento del microcontrolador, de tal manera que el IDE sea capaz de preparar el entorno para la programación de dicha placa. Análisis del producto Precio El precio de este PLC varía en función del modelo elegido. En la Tabla 3.3 se puede ver una tabla con los precios de cada uno de los modelos. Como se puede observar, el modelo proto kit es bastante económico y podría ser una alternativa viable para pequeños módulos 37
de automatización. Al precio inicial del proto kit habría que añadirle el coste de la fuente de alimentación así como el coste del hardware extra a incorporar, dado que el industrino proto no cuenta con ningún tipo de hardware más que el LCD y el Arduino, es decir, se puede decir que este modelo simplemente es un Arduino encapsulado en una caja de PLC. Expansión Siguiendo la filosofía modular de los PLC, Industrino tiene la capacidad de ser expandido mediante un conector de 14 pines IDC. Actualmente, industrino solo cuenta con una carta de expansión oficial para Ethernet por un precio de 29 euros, esta carta permite la comunicación del PLC con otros dispositivos mediante Ethernet y la librería estándar de Arduino. Implementación Al igual que se vio con ArduPLC, en este apartado veremos como se han abordado diferentes cuestiones de diseño en este producto. El objetivo de esta sección consiste en comprobar la calidad del producto así como ver las decisiones de diseño de diferentes fabricantes de modo que a la hora de diseñar nuestro propio hardware podamos tener una base de conocimiento fundamentada en soluciones ya implantadas. Industrino no pone a disposición de todos los usuarios todos sus esquemáticos por lo que en este caso analizaremos el Industrino proto kit del cual sí poseemos el esquemático. En primer lugar analizaremos el diseño en bloques proporcionado por Industrino. Como se puede observar en la Figura 3.22 el Industrino ha optado por una división en niveles desde mi punto de vista muy acertado. Por una lado se encuentra el nivel de control, formado por el microcontrolador Atmega32u4 en este caso, y el LCD. Desde este nivel se deriva mediante un conectar PFC, de 40 pines, los diferentes pines del encapsulado Atmega32u4. Estos pines serán utilizados en la parte de potencia. La división física permite aislar de fenómenos derivados de las diferentes corrientes inducidas en la parte de potencia así como en la parte de alimentación. En el nivel más bajo encontramos la parte de prototipado y en general de potencia. Esta parte está formada por una fuente de alimentación regulada a la que nos referiremos más adelante. Además, en este nivel se encuentra el conector PFC para recibir el nivel de control. Por otro lado, en el área de prototipado se puede ver como se han incorporado unas resistencias de 0 ohmios que servirán para conectar o desconectar los pines internos hacia el exterior. La decisión de diseño de poner resistencias de 0 ohmios en vez de jumpers supongo que se deberá al tipo de máquina utilizada en el proceso de «pick and place» o se comporta como un elemento de protección haciendo la función de fusible. Por último, en la parte superior del nivel inferior o nivel de prototipado, se puede observar cómo se ha añadido un conector de 14 pines IDC para añadir los módulos de expansión. Se deberá tener en cuenta que el conector IDC y el módulo comparten algunos pines de tal manera que si se conecta una carta 38
de expansión y cómo la carta Ethernet (ver Figura 3.21 no se podrá utilizar ni el pin SDA ni el pin SDL al que podrían estar conectados otros periféricos.
Figura 3.21: Carta de expansión Ethernet, fuente: https://industruino.com
Figura 3.22: Diagrama de bloques industrino proto kit, fuente: https://industruino.com
En cuanto al esquemático, se puede observar como al igual que en ArduPLC se han implementado numerosas etapas de desacoplo en todas las fases de alimentación así como 39
diferentes protecciones contra ElectroMagnetic Interference (EMI) y ESD en cada una de las interfaces externas. Esto reduce la posibilidad de falsos valores debido al efecto antena de los pines dirigidos al exterior. Valoración El Industrino es una buena alternativa genérica para pequeñas automatizaciones frente a PLCs como el Siemens Logo. Al ser más barato que ArduPLC este PLC se podría utilizar en diseños donde no se requiera tanta potencia como en ArduPLC.
3.5.4
Industrial Shields
Industrial shields es sin duda la familia de PLCs basada en hardware y software libre más exitosa hasta el momento. Actualmente este fabricante cuenta con una gran gama de productos que se pueden ajustar a todas las necesidades, desde pequeños proyectos hasta grandes proyectos. Además de Arduino, Industrial Shields trabaja con la Raspberry Pi para dotar al sistema de un componente System on Chip (S O C) que podrá ser utilizado en la parte de interfaz SCADA. Con el objetivo de analizar alguno de los productos de Industrial Shields, seleccionaremos el dispositivo básico el cual servirá de referencia para tener una visión global de los productos del fabricante. El controlador básico es el «Controlador Básico Arduino BC16DA (16 I/Os)» (ver Figura 3.23) y puede ser adquirido desde el siguiente enlace: http://www. industrialshields.com/es/shop/plc-Arduino-based-16-i-os-analog/
Las características de este producto son: 4 Entradas analógicas: Entradas analógicas de 0 a 10 voltios de corriente continua. 5 entradas digitales: Entradas digitales de 0 a 24 voltios según normativa. 2 salidas analógicas: Salidas analógicas optocopladas de 0 a 10 voltios. 5 salidas PNP: Salidas aisladas mediante transistores. Comunicaciones: Comunicaciones mediante RS-485, I2C, SPI. Análisis del producto Precio En general el precio de los productos de Industrial Shields son algo elevados, sin embargo, gracias al gran abanico de productos que poseen el usuario puede seleccionar el PLC más competitivo para sus necesidades. En el caso del PLC BC16DA, se puede adquirir por el precio de 100e, a esto habrá que añadirle al igual que en la mayoría de PLC el precio de la fuente de alimentación. El precio comparado con el Industrino es un poco más elevado no obstante se puede comprobar dando un vistazo rápido a su web como este fabricante de PLC tiene acabados muy 40
Figura 3.23: Controlador Básico Arduino BC16DA, fuente: http://www.industrialshields. com/
profesionales, acompañando cada uno de sus productos diferentes casos de éxito donde han sido desplegados sus productos. Expansión En este apartado Industrial Shields sigue un poco el modelo de los demás PLC, mediante el bus I2C se puede expandir el diseño con hasta 127 módulos contado con hasta 2540 Entradas/Salidas en conexión Master-Slave. Industrial Shields proporciona las resistencias pull-up para el bus I2C en su vertiente industrial mediante la interfaz DIN (ver Figura 3.24). Aunque todos los PLC estudiados en este apartado dicen poder expandir su diseño mediante I2C en ninguno se muestra las capacidades reales de esta expansión, es decir, no se puede encontrar ningún ejemplo de librería o comunicación entre dos módulos PLC. Otro de los productos prometedores de Industrial Shields es el «TouchBerry Pi 10.1» (ver Figura 3.25). Este pequeño PC basado en Raspberry Pi y en consecuencia en GNU/Linux permite controlar diferentes procesos productivos mediante la conexión del mismo al bus de comunicaciones, ya sea mediante I2C, RS-485, Ethernet, o WI-FI. El TouchBerry Pi cuenta con una pantalla capacitiva de 10.1 pulgadas lo que le convierte en un dispositivo ideal para instalar un sistema SCADA. Sin embargo aunque es un diseño prometedor en este caso el precio es excesivo yendo desde 375e hasta 405e en función de la versión elegida. Si comparamos esta pantalla con la gama básica de Siemens como por ejemplo el 6AV21232DB03-0AX0, llega a ser incluso más barato el HMI de Siemens, por lo que en este punto 41
Figura 3.24: Resistencia de Pull-Up DIN, fuente: http://www.industrialshields.com/
Industrial Shields no es del todo competitiva.
Figura 3.25: TouchBerry Pi 10.1, fuente: http://www.industrialshields.com/
42
Implementación Aunque en la web de Industrial Shields aparece numerosas veces la palabra «Hardware Libre» y «Software Libre» en este caso no he podido encontrar ningún esquemático en el cual comprobar qué decisiones de diseño se han tomado para cada uno de los retos a los que se enfrenta este tipo de PLC. El único documento podría llegar a asemejarse a un esquemático es el layout, en este caso no disponible para el «Controlador Básico Arduino BC16DA (16 I/Os)» por lo que en esta subsección se estudiará el «ARDBOX 20 I/Os Analog 7.0». En la Figura 3.26 se puede ver el diagrama en bloques de este PLC
Figura 3.26: Diagrama en bloques ARDBOX 20, fuente: http://www.industrialshields.com/
Como se puede observar en la Figura 3.26, el ARDBOX tiene dos fuentes de alimentación. La primera de ellas se utiliza para la lógica, pudiendo admitir desde 12 hasta 24 voltios. Por otro lado, la segunda (Vin) se utiliza para todas las salidas optoacoplados o en general aisladas. El ARDUBOX cuenta con dos tipos de salidas, las analógicas y las digitales. Las analógicas van desde 0 a 10 voltios, sin embargo las digitales van desde 0 a Vin admitiendo una intensidad máxima de 0,3A. Por otro lado, el apartado de comunicaciones se hace disponible al exterior mediante diversos conectores. Entre estos conectores podemos encontrar «A» y «B», utilizados para el par diferencial RS-485 o incluso MISO MOSI y SCK para el bus SPI. La mayoría de entradas y salidas permiten ser desconectadas, esto ayuda a que no se produzca el efecto antena y por tanto se reduzca las posibles interferencias. Como se puede observar, la información sobre el hardware y su implementación es bastante escasa por lo que el análisis sin tener el dispositivo en la mano es bastante complejo. 43
Valoración Industrial Shields es una compañía con un gran numero de PLCs todos ellos con una calidad bastante notable. El principal fallo de esta compañía reside en el acceso a la documentación de cara al cliente que todavía no ha comprado su producto. Un punto a favor de esta compañía es el de ofrecer una amplia gama de productos que permita al usuario homogeneizar sus líneas de producción y obtener una automatización integral.
3.5.5
Valoración general
En general, las diferentes alternativas vistas en este apartado son todas muy similares entre ellas. Las ventajas del uso de estas tecnologías frente a los PLC convencionales favorecen la aparición de nuevas industrias 4.0. Sin embargo, el problema de todas estas alternativas son el enfoque seguido a la hora de planificar el desarrollo del producto. Aunque todas están dotadas de hardware de calidad, el apartado software no ha sido trabajado. La fiabilidad de los sistemas no solo recae en el hardware, el software tiene un gran peso a la hora de realizar sistemas fiables. Todas las alternativas estudiadas utilizan el entorno Arduino de desarrollo y ninguna de ellas proporciona nuevos paradigmas que se acerquen a la programación de PLCs. En este trabajo se verán diferentes alternativas de implementación para simplificar la labor de programación de sistemas embebidos y reducir en consecuencia el coste de desarrollo y el coste del producto final.
3.6 Sistemas embebidos En este trabajo se desarrolla un sistema embebido por lo que es recomendable recordar qué significado tiene esta palabra y qué consideraciones hay que tener en cuenta a la hora de realizar un desarrollo para este tipo de plataformas. Según [gus09], un sistema embebido es un circuito electrónico computarizado que está diseñado para cumplir una labor específica en un producto. Esta definición aunque acertada, ignora alguna característica clave de los sistemas embebidos como el hecho de que normalmente estos sistemas no están pensados para tener una fuerte interacción con el usuario o que suelen requerir de una gran disponibilidad. La definición exacta de sistema embebido no está del todo clara, cada autor ha definido este concepto de forma diferente, a continuación se muestra algunos ejemplos de definición: [emb00] Un sistema embebido es aquel sistema que contiene un microprocesador o microcontrolador pero no debe ser pensado como un computador de uso genérico. El procesador o microcontrolador no es visible y es una parte más del sistema embebido oculta al usuario. [com08] Si se pregunta por un sistema embebido se puede contestar de una forma un tanto vaga como cualquier dispositivo que incluye un ordenador pro44
gramable pero no pensado para ser utilizado como un ordenador de propósito general. Un fax o un reloj realizado con un microcontrolador es un sistema embebido. [emb99] La gente utiliza el término sistema embebido para referirse a cualquier sistema basado en computador ocultado dentro de algún producto. Un factor común en la mayoría de las definiciones es que dichos sistemas están formados por un microcontrolador o microprocesador y que no son sistemas de propósito general. Podemos encontrar ejemplos de sistemas embebidos en la mayoría de electrodomésticos que poseemos en nuestro hogar. El software que controla las revoluciones de la lavadora o incluso el software y el hardware incorporado en el frigorífico de nuestra cocina son ejemplos de sistemas embebidos. Otro sector donde existen muchos sistemas embebidos y que a día de hoy representan un gran porcentaje del valor final percibido por el usuario, es la industria del automóvil. Antiguamente los automóviles patrocinaban nuevos motores, nuevos sistemas de transmisión, etc. Sin embargo, hoy en día los anuncios de coches se basan en mostrar las funcionalidades software de las que se ha dotado al vehículo como por ejemplo: detectores de peatones, detección de señales. . . Como se puede imaginar, este tipo de sistemas requieren de una gran fiabilidad y de un plan «B» en caso de que los mismos fallen (no siempre se incorpora este plan «B»), es decir, de algún tipo de replicamiento y sistema de degradado. Para diferenciar entre un computador de propósito general y un sistema embebido pasaremos a nombrar los componentes principales[emb00]. Componentes de los computadores de propósito general: Poseen un microprocesador. Gran cantidad de memoria: • Memoria principal: Memorias RAM y ROM además de las caches. • Memoria secundaria: Memoria magnética, discos CD-ROMs. Unidades de entrada/salida como pantalla táctil, módem, fax, etc. Unidades de red: Sistemas de conexión con redes como Ethernet. Sistema operativo: Sistema operativo de propósito general el cual permite la instalación de programas de usuario y utilidades. Por otro lado, los componentes de los sistemas embebidos son: Contiene diferentes unidades hardware llamados periféricos como por ejemplo los timers, módulos de entrada salida. . . Aplicación o software que realiza diferentes procesos normalmente codificados como tareas. 45
Algunos sistemas embebidos poseen un RealTime Operating System (RTOS), este sistema operativo se encarga de coordinar el acceso a los diferentes periféricos, así como, asegurar que cada acción se realiza dentro de un tiempo específico y acordado. Un sistema embebido se caracteriza, normalmente, por poseer restricciones de tiempo real. Esto influye en la gestión de procesos, gestión de accesos a memoria y gestión de interrupciones. Un sistema embebido con restricciones de tiempo real debe asegurar que las tareas se completen dentro de un deadline. Por otro lado, un sistema embebido puede tener que realizar diferentes algoritmos complejos como Proportional Integral Derivative controller (PID), transformadas de Fourier, etc. En los últimos años también se ha añadido la necesidad de añadir una Graphical User Interface (GUI) para los sistemas HMI. Como se puede observar todas estas características requerirán de un procesador con la suficiente potencia para cumplir con ellas. Y cuando un sistema requiere de potencia en consecuencia requiere de una fuente de energía. A continuación se explicarán algunos de los conceptos inherentes a los sistemas embebidos de tal manera que se pueda tener una visión global de los requisitos para desarrollar un sistema embebido genérico.
3.6.1
Componentes
Procesador De forma resumida el procesador está formado por dos grandes unidades, la Control Unit (CU) y la EU. La CU es la encargada de obtener las instrucciones de memoria y la Execute Unit (EU) tiene todos los circuitos para realizar aquellas instrucciones. En la EU es donde se encuentra la Arithmetic Logic Unit (ALU) entre otros muchos circuitos. Existen diferentes tipos de procesadores o mejor dicho, unidades de proceso que se pueden incorporar al sistema embebido. Algunas de estas unidades de proceso como los Application Specific Integrated Circuit (ASIC) y las FPGAs no siguen exactamente esta arquitectura de EU y CU, sin embargo los principios de funcionamiento se asemejan mucho. A continuación se nombrará un conjunto de unidades de proceso que podrían ser utilizados en un sistema embebido.[emb00] General Purpose Processor (GPP): Un GPP es un procesador de uso genérico con una amplia gama de instrucciones que permite el desarrollo de numerosas, es lo que conocemos por un procesador convencional. Application Specific Instruction Set Processor (ASIP): Los ASIP son microprocesadores diseñados para ser utilizados con un fin concreto. Normalmente el set de instrucciones está diseñado para una aplicación concreta. Dentro de estos procesadores se encuentran los Digital Signal Processor (DSP), los sistemas de procesamiento de red, microcontroladores, etc. Procesadores cooperativos: Más que un tipo de procesador es un tipo de arquitectura 46
en la cual cada procesador se utiliza para un conjunto de tareas, a cada procesador se le llama coprocesador. Un ejemplo podría ser una Graphics Processor Unit (GPU) o la unidad de proceso de la Network Interface Card (NIC) junto con un GPP. o ASIC: Este tipo de unidades de proceso se pueden utilizar como unidades de coprocesamiento o como unidades de procesamiento en si mismas. FPGA
Procesador multicore: Procesador con más de una unidad de cálculo permitiendo ejecutar varias tareas a la vez. Fuente de alimentación En muchas ocasiones no se da la relevancia necesaria a la fuente de alimentación y esto es un grave error. Un fallo en la alimentación o incluso una fuente de alimentación mal estabilizada puede hacer que nuestro diseño falle de forma inesperada. Los sistemas embebidos deberían tener fuentes de alimentación dedicadas siempre que se pudiera, esto permite añadir una fase más de aislamiento y además permite filtrar fenómenos que no son beneficiosos para nuestro sistema. Las fuentes de alimentación tienen diferentes rangos de voltaje, esto permite adaptar la misma a diferentes diseños. Los microcontroladores y en general las unidades de proceso suelen tener bajos requisitos de voltaje dado que debido a la Ecuación 3.2 a mayor voltaje mayor potencia disipada.
P 'V2∗F V → V oltaje
(3.2)
F → F recuencia La elección de una buena fuente de alimentación así como los filtros necesarios ayudarán a que el sistema embebido funcione con mayor fiabilidad[ele81]. Existen diversos tipos de fuentes conmutadas. A continuación se dará una breve descripción de las más comunes, no obstante no es objetivo de este documento el ahondar en teoría de circuitos y de potencia. Fuentes de alimentación lineales: Este tipo de fuentes siguen el esquema básico de transformador, rectificador, filtro, regulación y salida. El transformador aísla y adapta los niveles de voltaje de 220 voltios (en Europa) a un voltaje inferior, típicamente 24 voltios. Una vez se tiene la señal de alimentación con un menor voltaje la siguiente etapa consiste en rectificar la señal, esto es, pasar la señal de alterna (ver Figura 3.27) a pulsante. La señal pulsante tiene un rizado el cual se debe disminuir. Normalmente este paso se realiza mediante una serie de condensadores. Por último la señal necesita 47
ser estabilizada, esto se suele hacer mediante una serie de reguladores de tensión (ver Figura 3.29). Estas fuentes son menos eficientes pero pueden llegar a ser muy estables. Fuentes de alimentación conmutadas: Las fuentes conmutadas han ido ganando terreno en los últimos años. Las fuentes conmutadas utilizan reguladores de tensión conmutados, esto permite trabajar a los transistores en la parte de conmutación. El truco de estas fuentes consiste en aumentar mucho la frecuencia de conmutación desde 20kHz a 100 kHz. De esta conmutación surge una onda cuadrada que se aplica a un transformador de núcleo de ferrita obteniéndose diferentes voltajes. Con esta técnica se consiguen transformadores más pequeños y fuentes más optimizadas, sin embargo, el problema más grave de este tipo de fuente es que genera ruido eléctrico de alta frecuencia que deberá ser filtrado o generará graves problemas en el circuito.
Figura 3.27: Corriente sinusoidal. Fuente: wikipedia
Figura 3.28: Sensor de CO2
Como se puede observar, el uso de una fuente u otra puede ser de vital importancia debido a los posibles ruidos eléctricos generados. Además, si una fuente de alimentación no está bien estabilizada puede hacer que el sistema entre en defecto como por ejemplo ocurre en algún PLC. 48
Figura 3.29: Estructura interna de un regulador de tensión
Periféricos Los sistemas embebidos se caracterizan por su interacción con el medio. Para interactuar con el medio el sistema deberá tener sensores y actuadores. Existen diversos libros que hablan sobre este campo, en los últimos años han aparecido novedosos sensores que permiten medir magnitudes que hasta ahora no eran posibles y además por un precio muy bajo. Por ejemplo, un sensor de CO2 (ver Figura 3.28) cuesta aproximadamente 50e, lo cual es relativamente poco si se compara con los precios de hace unos años cuando estos sensores o no existían o podían llegar a costar el doble. Los sensores son los encargados de obtener la información del medio. Esta información puede ser digital o analógica en función del sensor utilizado. Una vez capturada la información, la unidad de proceso calcula qué debe hacer y en caso de que requiera modificar el entorno utilizará alguno de sus actuadores. Existen diferentes tipos de actuadores pero una norma general para la mayoría de ellos es que siempre que se pueda, la parte de control y de actuación deberán estar desacopladas. La teoría de sensores y actuadores es muy extensa y no es motivo de este documento el ahondar en estos conceptos, no obstante, en el prototipo planteado se utilizarán tanto sensores como actuadores para interactuar con la fábrica.
3.6.2
Los sistemas embebidos en el TFG
En este TFG se ha realizado un sistema embebido. Para abordar esta tarea con éxito se han tenido que tener en cuenta numerosos factores anteriormente citados. Tanto la elección de la fuente de alimentación como del procesador y los periféricos han sido de vital importancia para la realización de proyecto. La filosofía de trabajo así como las metodologías empleadas a la hora de realizar un sistema empotrado o sistema embebido son completamente diferentes a las que se aplican a la hora de diseñar un sistema de propósito general. Una de las características que en este TFG ha resultado más compleja de garantizar ha sido la de disponibilidad y seguridad. Dotar a un sistema de una fiabilidad alta tiene muchos costes, tanto a nivel económico como a nivel intelectual. El software debe realizar constantes comprobaciones para saber cual es el estado de cada uno de los elementos que componen el sistema embebido, 49
además, el hardware debe apoyar esta fiabilidad con elementos de protección y control. En el desarrollo del proyecto se verá cómo se han abordado cada uno de los aspectos relevantes de este tipo de sistemas.
50
Fabricante
PLCs
Precio
Siemens
Logo Simatic S7-200 Simatic S7-300 Simatic S7-400 CJ2H CPM2C CP1E Modicom M221 Modicon M238 Modicon M251 SLC 500 PLC-5 CompactLogix 5370
130 e 200 e 560 e 1700 e 3,655.74 e 823 e 400 e 200 e 600 e 300 e 800 e1 700 e 1.500 e
Omrom
Schneider
Allen Bradley
Cuadro 3.1: Tabla de fabricantes de PLCs
51
Modelo
Microcontrolador
Arduino Due Arduino Leonardo Arduino Uno - R3 RedBoard Arduino Uno SMD (descontinuado) Arduino Uno (descontinuado) Arduino Duemilanove (descontinuado) Arduino Bluetooth (descontinuado) Arduino Pro 3.3V/8MHz Arduino Pro 5V/16MHz Ethernet Pro (descontinuado) Arduino Mega 2560 R3 Arduino Mega 2560 (descontinuado) Arduino Mega (descontinuado) Mega Pro 3.3V Mega Pro 5V Arduino Mini 04 (descontinuado) Arduino Mini 05 Arduino Pro Mini 3.3V/8MHz Arduino Pro Mini 5V/16MHz Arduino Fio Mega Pro Mini 3.3V Pro Micro 5V/16MHz Pro Micro 3.3V/8MHz LilyPad Arduino 328 Main Board LilyPad Arduino Simple Board
Frecuencia
MemoriaBootloader
de Reloj
Flash
AT91SAM3X8E ATmega32U4 ATmega328 ATmega328 ATmega328
84MHz 16MHz 16MHz 16MHz 16MHz
512Kb 32Kb 32Kb 32Kb 32Kb
ATmega328 ATmega328
16MHz 16MHz
32Kb Optiboot 32Kb Atmega
ATmega328
16MHz
32Kb Atmega
ATmega328 ATmega328 ATmega328 ATmega2560 ATmega2560
8MHz 16MHz 16MHz 16MHz 16MHz
32Kb 32Kb 32Kb 256Kb 256Kb
ATmega1280
16MHz
128Kb STK500v2
ATmega2560 ATmega2560 ATmega328
8MHz 16MHz 16MHz
256Kb STK500v2 256Kb STK500v2 32Kb Atmega
ATmega328 ATmega328 ATmega328 ATmega328P ATmega2560 ATmega32U4 ATmega32U4 ATmega328
16MHz 8MHz 16MHz 8MHz 8MHz 16MHz 8MHz 8MHz
32Kb 32Kb 32Kb 32Kb 256Kb 32Kb 32Kb 32Kb
ATmega328
8MHz
32Kb Atmega
Cuadro 3.2: Productos Arduino Modelo
Microcontrolador
Precio
Industrino Proto Kit
Atmega32u4 AT90USB1286 Atmega32u4 AT90USB1286
52 e 62 e 110 e 120 e 29 e
Industruino IND.I/O kit Ethernet expansion module
Cuadro 3.3: Tabla de precios de Industrino
52
Due Leonardo Optiboot Optiboot Optiboot
Atmega Atmega Atmega STK500v2 STK500v2
Atmega Atmega Atmega Atmega STK500v2 DiskLoader DiskLoader Atmega
Capítulo 4
Metodología de trabajo
4.1 Introducción a las metodologías de diseño en sistemas embebidos Como ya se mencionó Sección 3.6, los sistemas embebidos tienen numerosas características que los hacen muy particulares. Del mismo modo en que no se programa un sistema embebido como se programa un sistema basado en un computador de propósito general, las metodologías aplicadas para el diseño de un sistema embebido no son, o no deberían ser, las mismas que las utilizas en diseños convencionales. La necesidad de nuevas metodologías de co-diseño ha sido evidenciada por varios autores, entre ellos [Her13]. Actualmente, las metodologías que se están aplicando para el desarrollo de sistemas embebidos provienen de ISO. Aunque los sistemas embebidos verdaderamente tienen una parte de software, este no es igual al software de aplicación para el que suelen estar diseñados las metodologías de ISO. Además de la naturaleza diferente de ambas disciplinas, el hecho de que determinadas características inherentes a la mayoría de los sistemas embebidos como la alta fiabilidad, necesidad de altos niveles de seguridad así como el tiempo real, hacen que se tengan que incorporar algunas etapas extras a las metodologías tradicionales. En la Figura 4.1 se puede ver cuales son las principales preocupaciones de los diseñadores de sistemas embebidos. Como se puede observar el calendario de reuniones así como el proceso de depuración son las áreas que más preocupan a los diseñadores. El proceso de depuración es preocupante por el mero hecho de la fiabilidad ya citada de los sistemas embebidos. Para cerciorarse de que un sistema es robusto se deben tomar muchas medidas. En el caso del software de carácter general es más sencillo dado que únicamente se deberán hacer pruebas unitarias y de integración o cualquier otro tipo de testing que permita cubrir todos los casos de uso de la aplicación. Sin embargo, para los sistemas embebidos, además de este tipo de pruebas se deben realizar otras que muy probablemente nunca lleguen a ocurrir en el sistema, aunque se debe tener en cuenta la probabilidad de que suceda. Por ejemplo, la corrupción de un sector de la EEPROM debe ser tenida en cuenta en la programación del sistema de tal manera que cuando ocurra esto, se tome una acción de degradado o se actualice automáticamente el mapeo de direcciones de memoria. Existen numerosos ejem53
Figura 4.1: Resultados del estudio Embedded Market Survey del 2013
plos donde se puede comprobar que la depuración de los sistemas embebidos es una tarea tediosa. Además, la falta de herramientas y la fragmentación de las mismas entre diversas compañías de microcontroladores hace aun más difícil esta tarea. Además del plano software, los sistemas embebidos incorporan un plano más al escenario. El hardware es una zona desconocida para la ingeniería del software dado que este se da por supuesto en los diseños que en esta disciplina se plantean. En los sistemas embebidos no se puede hacer esta aserción dado que la mayoría de los sistemas embebidos diseñados suelen ser soluciones ad hoc, valga de ejemplo el sistema embebido que comanda una lavadora. Este hecho hace evidente la necesidad de nuevas metodologías pues este plano hardware no es abordado en las disciplinas tradicionales y aunque es posible la modificación de las mismas para la adaptación del hardware, no es la manera más adecuada debido a las singularidades que este plano otorga al diseño. Según [Her13], «El 59 % de los encuestados no utilizan ningún método de desarrollo formal o técnica para llevar a cabo los proyectos embebidos». Esto evidencia los problemas existentes en este área dado que no se encuentra una metodología estable que seguir para desarrollar, esto hace que se perciba la fase de desarrollo como una fase insatisfactoria [MA07]. Se han realizado diversos intentos para formalizar diferentes metodologías [SVM01] de desarrollo para el diseño conjunto del software y del hardware sin embargo a día de hoy no es la solución más aceptada. Aunque el TFG es un proyecto en si mismo, para la realización de este trabajo se ha dividido en varios proyectos fuertemente relacionados. Dividir en proyectos ayuda a planificar el TFG de una manera más eficiente dado que se tienen unos requisitos, unas decisiones de diseño y una implementación en la que trabajar por cada uno de los subproyectos. Proyecto hardware: En este proyecto se desarrollará la plataforma hardware que dará 54
soporte al software de aplicación. El proyecto hardware se puede dividir en entregables que serán explicados más adelante. El proyecto hardware sigue una metodología iterativa e incremental. La decisión de esta metodología radica en las características del proyecto. El proyecto hardware requiere en primer lugar que se tenga una plataforma base sobre la que empezar a evolucionar el diseño. Con la plataforma base (en una protoboard o cualquier medio de prototipado) se comprueba la adecuación a los requisitos y se estima el progreso del prototipo. Estimar el progreso del prototipo consiste en estudiar la viabilidad del prototipo propuesto que se puede entender desde punto de vista económico, desde el punto de vista de la seguridad o desde el punto de vista de la utilidad. Una vez se aprueba este prototipo se empiezan a evolucionar el diseño sobre cada uno de los componentes. Esto supone dividir el prototipo en unidades funcionales las cuales proporcionan un valor al proyecto. Por ejemplo, el módulo de comunicaciones proporciona infraestructura de comunicaciones al diseño, el módulo de HMI proporciona una representación del proceso, etc. Por cada módulo se desarrolla su parte hardware y firmware. La parte hardware de cada modulo se tratará como un miniproyecto en si mismo de tal manera que se vuelve a prototipar de forma separada su funcionalidad, se comprueban los parámetros y se comprueba la documentación, esto permite asegurar la fiabilidad en el hardware. Una vez el prototipo se adecua a lo requerido, se aprueba su acomplamiento a la plataforma final. En el caso del software de un modulo funcional (firmware) el proceso de diseño se realiza del mismo modo. Se trata como un subproyecto, se documenta y se genera un pequeño programa autocontenido que permite comprobar el aprovechamiento de los recursos hardware de forma eficaz y eficiente. El subproyecto de un modulo funcional finaliza con el acomplamiento completo a la plataforma final. De este modo, nos aseguramos que cada módulo está completamente probado tanto a nivel software como hardware antes de implantarlo en la plataforma final. Además, se comprueba que la documentación tanto a nivel software como a nivel hardware (esquemático) es coherente con la implementación. Esta metodología es una adaptación de las metodologías tradicionales al diseño de sistemas embebidos. La trazabilidad del proyecto es máxima debido a la modularidad del diseño, además, la documentación estará siempre al día. Proyecto firmware: En el proyecto firmware se desarrolla toda la lógica de control.No se debe confundir con el firmware que se desarrolla en el proyecto hardware ya que, en ese caso, el firmware desarrollado sirve para comprobar si el diseño hardware está correcto. En este proyecto firmware se desarrollará el código embebido en la plataforma hardware, necesario para la comunicación del sistema, o la gestión de motores, etc. Proyecto software: El proyecto software es un proyecto a un nivel de abstracción mayor y consiste en la creación de un servicio web y una interfaz web de gestión que permita al operario gestionar la fábrica como si de un sistema SCADA se tratara. Este 55
proyecto se acerca más a un diseño convencional software, aunque, debido a la singularidad del proyecto se deberá matizar en las diferencias existentes. Una de las principales diferencias es la cohesión entre la plataforma hardware y la plataforma software. Otro aspecto en el que sí que coinciden los desarrollos tradicionales y este proyecto es en el cliente. El cliente será el director de «Harinera Castellana» con el que nos reuniremos para consensuar los requisitos así como para realizar un seguimiento del proyecto. La metodología seguida en este caso para el desarrollo del proyecto software es también iterativa e incremental enlazando así con el proyecto hardware. Como se puede ver tanto el proyecto software como el proyecto hardware siguen la idea del desarrollo iterativo e incremental. Este tipo de metodologías aporta muchas ventajas al producto final y se adecua de forma óptima al desarrollo hardware. En cada incremento el cliente podrá comprobar como se desarrolla el proyecto, ya sea a través de prototipos o a través de documentación adjuntada. De este modo se puede tener una rápida adaptación a los cambios. Otras metodologías más tradicionales no involucran al cliente una vez pasada la etapa de requisitos. Tal y como se verá en el desarrollo del proyecto, si el cliente no hubiese sido informado del avance del proyecto, probablemente al finalizar este TFG habría que haber diseñado otra plataforma o desestimar el proyecto debido al cambio en uno de los requisitos que determinaban el sistema. Otro punto importante a tener en cuenta es que, aunque el proyecto se divida en varios subproyectos esto no significa que los mismos no se puedan realizar de forma concurrente. Mientras se desarrolla el PCB se desarrolla el firmware final de tal manera que para realizar una entrega en algunos casos ambos subproyectos deberán haber finalizado.
4.2 Metodología iterativa e incremental Dado que esta es la metodología por la que hemos optado en este TFG, conviene aquí explicar a nivel teórico en que consiste dicha metodología, además, con el objetivo de mostrar al lector las variaciones realizadas a la metodología, se dará una breve descripción de cada una de dichas variaciones. La metodología iterativa e incremental es una evolución de la metodología en cascada. La metodología en cascada ha sido muy utilizada desde que en los inicios de la ISO se definiera el diseño en cascada[iso01]. Las ventajas de la metodología iterativa e incremental frente a la metodología en cascada son las siguientes[iso06] Los clientes no tienen que esperar hasta que se finalice el desarrollo del sistema completo para poder empezar a utilizarlo. Los clientes pueden utilizar las primeras iteraciones para ofrecer feedback a los desarrolladores. Los riesgos del sistema y el riesgo de un fallo total en el sistema disminuye debido al 56
hecho de que en cada incremento se puede ir corrigiendo los incrementos anteriores. Los incrementos iniciales poseen la parte más crítica del sistema, es por ello que en principio es menos probable que se encuentren fallos en esta parte debido a que serán más probados y utilizados. La metodología iterativa e incremental parte de dos premisas[Wik16]: Los usuarios no saben definir de forma precisa los requisitos del sistema. En el desarrollo siempre se modifica alguna parte o proceso. El proceso de diseño en la metodología iterativa e incremental consiste en los siguientes items: Inicio: En esta primera etapa, se desarrolla un producto usable por el usuario, es decir, un producto que el cliente pueda utilizar. Mediante este primer producto, se permitirá al cliente comprobar la instanciación de sus requisitos (o al menos los más críticos) y se podrá tener un feedback del usuario final. Una vez entregado el primer prototipo o sistema, se realiza una lista de control del sistema. En esta lista se agregan todos los requisitos que añadirán algún tipo de función así como las diferentes tareas de reacondicionamiento de los incrementos anteriores. Bucle de iteración: En este bucle se desarrollan cada una de las iteraciones planeadas. Las iteraciones se escogen de la lista de control del proyecto, además, en cada etapa se analiza la anterior. La idea es que en cada iteración se aporte una nueva funcionalidad o una mutación de una iteración anterior de forma modular. Existen unas guías para seguir a la hora de realizar la implementación de una nueva funcionalidad o la mutación de una anterior en base el análisis: • Las modificaciones deberían ser fácilmente trazables, de modo que la recodificación se realice sobre módulos aislados. Si no ocurre esto entonces se debe plantear la idea de un rediseño. • Según se avanza en el sistema y este se va haciendo más modular, debería ser más fácil encontrar el lugar donde realizar la modificación, si esto no ocurre entonces probablemente se haya llegado a un punto donde el código está lleno de parches y no de modificaciones estructuradas. • Se puede dar el caso en que implementando una nueva funcionalidad descubramos la necesidad de realizar una modificación en un módulo del sistema, si esto ocurre entonces se puede aplicar un parche. El parche no deberá estar más de dos o tres iteraciones. En ese periodo de tiempo se añadirá a la lista de control para que el parche se traduzca en una modificación modular. • Se debe realizar un seguimiento a largo plazo, es decir, comprobar que la línea base del proyecto crece según lo estipulado en los requisitos. 57
• Se tiene que contar con la colaboración del usuario para detectar deficiencias en el diseño. El enfoque iterativo e incremental es un enfoque ágil pero manteniendo muchas partes de las metodologías tradicionales. De este modo se tendrá facilidad para el cambio de requisitos y se podrá gestionar el proyecto de manera sencilla debido al planning basado en la lista de control.
4.3 La metodología iterativa e incremental en el TFG La teoría es un apartado importante en cualquier disciplina, sin embargo, la implementación dista muchas veces de esta primera, es por ello que en esta sección veremos cómo se ha adoptado la metodología iterativa e incremental en el desarrollo de este TFG adaptándolo a las peculiaridades del mismo.
4.3.1
La metodología iterativa e incremental en el Hardware
En primer lugar empezaremos por definir cómo se ha trabajado a la hora de desarrollar el hardware. Como ya sabemos de la Sección 4.2, la metodología necesita de unos incrementos planificados pero esto solo se aplica en la etapa del bucle de iteración, por lo que en primer lugar se deberá realizar el Inicio del proyecto. El Inicio del proyecto consiste en estudiar y definir los requisitos para más tarde presentar un prototipo funcional inicial y continuar con la elaboración de la lista de control. Los requisitos se pueden consultar en el Anexo C . En base a estos requisitos formulados por la empresa «Harinera Castellana» y tras la primera reunión en la empresa «Automatinfo», se decide una linea base para desarrollar el primer prototipo. Aquí se define que plataforma será el core del proyecto, además se definen otros compromisos como el bajo coste del diseño el cual será un elemento conductor del proyecto. Una vez se recogen los requisitos del sistema se realiza una primera versión del hardware que servirá de base para los futuros incrementos. Una vez realizado el prototipo se pondrá a disposición del usuario para que compruebe la adecuación a sus expectativas. Un ejemplo donde el cliente, que en este caso también es el experto en el dominio, podría darnos un feedback útil, podría ser en el caso de los tiempos de movimientos. Si el cliente detectara que el tiempo de movimiento del cilindro es demasiado lento, este podría comunicárnoslo en una fase temprana del proyecto para poder tomar las medidas oportunas. La siguiente etapa del desarrollo consiste en la elaboración de una lista de control, esta lista puede estar en cualquier formato aunque lo más cómodo es utilizar algunas de las herramientas existentes en Internet. En este caso, se ha utilizado la herramienta Trello. Esta herramienta es gratuita y provee de las funciones básicas para la gestión del proyecto. En la Figura 4.2 se puede ver una captura de pantalla de la herramienta. El flujo de trabajo es sencillo, por cada iteración se coge al menos una de las características en el «banco 58
To-Do (TODO)» y se mueve al banco «Doing». Una vez finalizado el desarrollo se añade al prototipo final y se enseña al cliente. En la siguiente iteración se realiza la misma operación pero en este caso se comprueba el feedback del usuario sobre la característica añadida (si hubiera) y se añaden las mismas a los comentarios de dicha ficha. En el caso de que sea necesario se mueve la ficha de «Doing» a TODO y se inician las modificaciones pertinentes en la iteración que corresponda según la prioridad.
Figura 4.2: Herramienta Trello
Esta metodología es muy acertada debido a la modularidad que se consigue en el desarrollo, estos pequeños incrementos son fácilmente trazables y por lo tanto se mantiene un control sobre el desarrollo del proyecto. En el caso del proyecto hardware, la iteración con el usuario después de cada incremento no es tal debido a que no es necesario para el proyecto. Si el prototipo inicial se adecuaba a las necesidades del proyecto, entonces las pequeñas modificaciones realizadas en hardware se adecuarán del mismo modo dado que el paso del prototipo al desarrollo final es una cuestión meramente técnica.
4.3.2
La metodología iterativa e incremental en el Software
En el proyecto software se aplica la misma metodología, es decir, la metodología iterativa e incremental. El hecho de utilizar la misma metodología nos permite fusionar los flujos de trabajo de una manera muy simple. Imaginemos que programando el software de gestión se descubre un fallo o una carencia en el firmware del hardware. Por ejemplo, el software de aplicación requiere de un sistema de «acknowledge» que no ha sido implementado en el firmware. Si esto ocurre entonces se realiza un pequeño parche para poder terminar de implementar la funcionalidad pertinente y se añade una nueva ficha o iteración en el tablero 59
de control del proyecto hardware (en este caso, al ser la misma persona el desarrollador, se ha utilizado un mismo tablero). De esta manera los dos proyectos quedan unidos dentro del flujo de trabajo en el caso de que así se necesite pero a la vez quedan bien aislados, de modo que el proyecto sea fácilmente trazable.
4.3.3
Realimentación del cliente en el TFG
El proyecto, como ya se ha comentado es parte de un acuerdo entre la empresa «Automatinfo» y la «Harinera Castellana». Este proyecto fue asignado como tarea durante las prácticas en empresa cursadas durante el grado. Seguidamente se utilizó como proyecto fin de carrera. El único desarrollador del proyecto actualmente soy yo y por lo tanto todas las reuniones las he tenido que realizar personalmente, tanto con «Automatinfo» como con la «Harinera Castellana». Las reuniones con «Automatinfo» consistieron, primordialmente, en asesoramiento a la hora de plantear diferentes cuestiones de diseño como por ejemplo la que surgió a la hora de decidir si se implementaba un sistema basado en algún PLC Arduino o se implementaba un hardware ad hoc. Por otro lado, las reuniones con la «Harinera Castellana» consistían en la revisión del estado del proyecto así como la demostración de los avances realizados, involucrando al cliente dentro del proceso de desarrollo y permitiéndole opinar sobre el mismo. En una de estas reuniones se realizaron numerosos cambios en los requisitos. Estos cambios en realidad no eran cambios como tal según el cliente si no que no habían sido bien expresados en la primera versión del documento de especificación de requisitos.
4.4 Herramientas En este apartado, veremos de forma resumida cada una de las herramientas que se han utilizado en el desarrollo y planificación de este proyecto.
4.4.1
Herramientas software para el desarrollo
Arduino: Arduino es la base de este proyecto. A nivel software se ha utilizado el entorno de desarrollo Arduino en su versión 1.6. Este entorno está basado en el entorno de desarrollo processing desarrollado por el MIT[pro14] . Este entorno de desarrollo se ha utilizado en la fase de prototipado para diseñar los programas de testing. avr-libc: La librería avr-libc es un proyecto free-software que busca implementar una librería de alta calidad para su utilización en programas realizados en C y compilados con el compilador «GCC» para los dispositivos microcontroladores de AVR. Además de la propia librería incorpora otros programas como: avr-binutils, avr-gcc, avr-libc, etc. La librería se publica bajo una licencia derivada de la licencia Berkeley Software Distribution (BSD) compatible con GNU General Public License (GPL). Compiladores: Se han utilizado diferentes compiladores, todos ellos de software libre, 60
tanto para la implementación del firmware como para pequeñas pruebas que se han ido realizando durante el desarrollo. Todos los compiladores se engloban dentro de la arquitectura GCC. Eclipse: Eclipse es un entorno de desarrollo con gran trayectoria y madurez. Eclipse está formado por un conjunto de herramientas, la mayoría de ellas de código abierto que permiten programar de un modo cómodo en diferentes lenguajes. Eclipse sirve de base para muchos entornos derivados como por ejemplo el entorno de Xilinx. En este proyecto, se utilizará eclipse con el objetivo de adaptarlo a la plataforma Arduino y programar el firmware en este entorno de desarrollo. GNU/Linux: Tal y como se verá más adelante, el desarrollo de este proyecto está conducido por costes. Los costes de desarrollo vienen determinados por las herramientas que se utilizan en el mismo (entre otros muchos factores). Con el objetivo de reducir los costes y buscar una alternativa «libre», se utiliazará un sistema GNU/Linux para el diseño y desarrollo del proyecto. Trello: Para la planificación de proyectos existen muchas herramientas como Microsoft Project, sin embargo, el precio de estas herramientas en algunos casos es inasumible y por lo tanto se deben buscar otras alternativas. En este caso, para la planificación de cada una de las iteraciones así como las diferentes tareas a realizar dentro del proyecto se ha utilizado la herramienta Trello, la cual es online y por o tanto multiplataforma. Además trello cuenta con un servicio gratuito por lo que no supondrá un incremento en el precio del producto final. Kicad: Kicad es un software Computer-Aided Design (CAD) basado en software libre y que está teniendo una gran repercusión en los últimos años. Kicad proporciona un ecosistema donde realizar todo el proceso de diseño de una plataforma hardware, desde el diseño del esquemático hasta la creación de la PCB. Python: Python, además de un lenguaje de programación es un entorno interactivo desde el que realizar muchas tareas de diversa índole. En este TFG se ha utilizado para la gestión de la base de datos en determinadas ocasiones. Vim: El editor de texto vim es uno de los editores de textos más utilizados a día de hoy. Incluido en la mayoría de sistemas GNU/Linux, ofrece un conjunto de caracteríticas que agilizan el proceso de codificación. Vim es un editor de software libre y gratuito. Git: Los sistemas de gestión de versiones se han utilizado desde los primeros años de la aparición de la Ingeniería del Software y de la gestión de la configuración. En este caso, para este proyecto se ha utilizado GIT debido a su gran popularidad y su eficiencia a la hora de gestionar los flujos de trabajo. Bitbucket: Bitbucket aunque no es un software de aplicación es una plataforma web que permite la creación y gestión de repositorios de modo que se enlace a una rama remota del 61
sistema gestor de versiones y los cambios se apliquen también a este repositorio Bitbucket. Desde este repositorio, los usuarios autorizados podrán colaborar en el proyecto. En este TFG se ha utilizado como herramienta de «backup» y como herramienta de seguimiento por parte del director. Chromium: Chromium es un navegador de software libre que sigue la línea de desarrollo de chrome pero elimina algunos componentes privativos. Chromium se ha utilizado en la fase de desarrollo de la aplicación de gestión para depurar la implementación de la misma. Las herramientas para desarrolladores de chromium permiten depurar las llamadas realizadas al servidor así como la estructura HyperText Markup Language (HTML) , diseño responsive, etc. LogicAnalizer: LogicAnalizer es una herramienta de «Saleae» que permite realizar un análisis lógico de los datos que se mandan por el bus. En este proyecto se ha utilizado para depurar el protocolo de comunicaciones así como comprobar que la capa física soportaba determinados fenómenos electromagnéticos.
4.4.2
Herramientas software para la documentación
LATEX: LATEX es un lenguaje de etiquetado que permite generar documentos de formas profesional y eficiente. En este proyecto se ha utilizado este lenguaje para la creación de este documento y otra documentación complementaria. Texmaker: Texmaker es una editor de documentos LATEX que permite la gestión de ficheros así como el autocompletado y otras características que simplifican el desarrollo de este tipo de documentación. Dia: Dia es una herramienta de software libre para la creación de diagramas. Actualmente cuenta con un gran conjunto de símbolos por lo que se pueden crear desde diagramas de uso hasta diagramas de flujo pasando por incluso diagramas de sistemas SCADA. Texlive: Texlive es el conjunto de herramientas que permite la compilación y gestión de paquetes LATEX en GNU/Linux. Doxygen: Doxygen es una herramienta que permite generar un sitio web con la documentación del código al que se aplique las directivas Doxygen. En este trabajo ha sido utilizado para generar la documentación del firmware. Libreoffice: Libreoffice es una suite ofimática de software libre muy utilizada en los entornos GNU/Linux. Esta suite se ha utilizado para la documentación del protocolo de comunicaciones.
4.4.3
Lenguajes de programación y frameworks
C++: C++ es la evolución natural de C, un lenguaje creado por Dennis M. Richie en 1969 y que ha sido la base del kernel Linux entre muchísimas otras aplicaciones. C++, 62
como ya se ha dicho es la evolución de C de la mano de Bjarne Stroustrup en el año 1980. Este lenguaje añade las características de la orientación a objetos, favoreciendo así la modularidad y reusabilidad del código. Python: Python se creo a finales de los años ochenta por el desarrollador Guido van Rossum. Este lenguaje ha sufrido muchos cambios en los últimos años, llegando a considerarse uno de los lenguajes más prometedores de los próximos años. En este proyecto se ha utilizado junto a Flask para crear la aplicación de gestión. Flask: Flask es un microframework para el desarrollo de aplicaciones web basado en Python. Este framework se ha utilizado en la etapa de diseño e implemetación de la aplicación de gestión. Bootrstrap: Framework para la aplicación de estilos para páginas web. Bootstrap ha sido desarrollado por Twitter y a día de hoy es uno de los frameworks más utilizados en Internet. En este TFG se ha utilizado en la fase de desarrollo de la aplicación de gestión para aplicar los estilos al sitio web. jQuery: jQuery es un framework para Javascript que simplifica la realización de tareas comunes como el acceso y gestión del Document Object Model (DOM). En este proyecto se ha utilizado para gestionar las llamadas ajax así como para diversos aspectos dentro de la aplicación de gestion. Javascript: Javascript es un lenguaje de programación interpretado que en su definición dice ser orientado a objetos aunque débilemente tipado y dinámico. Javascript es un lenguaje del lado del servidor el cual ha sido utilizado en la fase de implementación de la aplicación de gestión. HTML: HTML
es un lenguaje de marcado utilizado para la creación de páginas web y en los últimos años incluso utilizado en la creación de aplicaciones móviles. HTML está estandarizado por la W3C y actualmente se encuentra en la versión 5. HTML ha sido utilizado para la creación de la estructura de la aplicación de gestión. Cascading Style Sheets (CSS): CSS se utiliza en diseño web para la aplicación de estilos de diseño a los diferentes elementos HTML. En este TFG se ha utilizado para dotar a la aplicación de gestión de estilos propios en lugares donde por alguna razón se quería modificar los estilos de Bootstrap. Structured Query Language (SQL): SQL es un lenguaje para la descripción de acciones que serán ejecutadas por el sistema gestor de bases de datos. SQL es un lenguaje declarativo el cual ha sido utilizado para comprobar que el trabajo realizado por el Object-Relational Mapping (ORM) se realizaba de forma satisfactoria. 63
Herramientas Hardware utilizadas Ordenador portátil: Utilizado para las reuniones así como para el trabajo fuera del laboratorio o de la empresa «Automatinfo». El ordenador es un Dell 7520. Ordenadores de sobremesa: Ordenadores de propósito general con procesadores i3 e i7 así como 4gb de ram y 8 gb de ram. Estos ordenadores pertenecen a la empresa «Automatinfo» y el laboratorio de investigación Arco. Analizador lógico Saleale: Analizador lógico utilizado para comprobar los valores que viajan a través del bus. Con este analizador lógico se pueden descubrir los fallos ocasionados por el medio. Osciloscopio digital Agilent DSO7054A: Osciloscopio digital de 4 canales a 500 Mhz con capacidad de decodificación de protocolos como: I2C, CAN, SPI, etc. Utilizado para comprobar la formad de onda que viaja a través de bus así para analizar el impacto de la optocoplación en el bus de comunicaciones. Multímetro digital Fluke: Utilizado para la medición de magnitudes como: voltaje, intensidad, etc. Placa de prototipado: Estas placas proporcionan un lugar donde realizar pruebas de circuitos antes de realizar la implementación final. Estación soldadora JVC: Estación para soldar y desoldar utilizada en el laboratorio de investigación para la placa de prototipos y la PCB. Máquina de prototipado PCB LPKF: Máquina de prototipado que permite la impresión de placas PCB abaratando los costes de prototipado. Cuando se fabrica un PCB normalmente se piden pocas unidades para comprobar el funcionamiento y más tarde se hace el pedido completo, esto encarece el precio dado que las máquinas de fabricación de PCBs trabajan por volumen.
64
Capítulo 5
Desarrollo del proyecto
E
este capítulo se verá la implementación del proyecto así como los detalles de la solución propuesta. Este capítulo está organizado de modo que el lector pueda ver cómo se ha ido evolucionando el diseño dentro de cada parte del proyecto. N
5.1 Análisis del problema y desarrollo de la arquitectura El proyecto, como ya se ha comentado varias veces anteriormente, surge ante la necesidad de automatización de la empresa «Harinera Castellana». Esta Harinera forma parte del grupo de empresas «Fragasa» de la cual forma parte también «Automatinfo», la empresa en la cual realicé las prácticas de empresas. El proyecto de automatización y modernización de la «Harinera Castellana» (desde ahora se hablará de fábrica) se asignó a la empresa «Automatinfo». Actualmente gran parte de la fábrica ha sido automatizada, sin embargo hay muchas tareas repetitivas y tediosas que aun no han sido automatizadas. En este TFG, se automatizará todas las líneas de transporte de materia prima y la apertura de las llamadas raseras. Una rasera es una estructura metálica que se coloca en la boca de un silo (ver Figura 5.1) de tal forma que se permita o no el paso de determinada sustancia. Dependiendo del tipo de producto a elaborar, del tipo de silo, de la sustancia que contenga y de la situación que ocupe dentro del proceso de elaboración de la harina, será necesario un determinado caudal de materia prima. Esta cantidad ha sido estudiada por los laboratorios de la harinera de modo que no es competencia nuestra el análisis de dicho factor Actualmente, el modo de operación es completamente manual. El operario mira una pizarra donde viene especificada la configuración de la fábrica para un periodo temporal. Una vez ha comprobado la pizarra, el operario va rasera por rasera configurando su porcentaje de apertura. El porcentaje de apertura se realiza mediante unas chapas con un agujero en medio, en función de la cantidad de sustancia (grano, o lo que fuere) que contendrá dicho tipo de harina se elige el diámetro del agujero de la rasera. En la Figura 5.2 se puede ver un ejemplo de dicha rasera. El número de raseras que debe mover el operario es muy alto y además cada una de ellas tiene alguna peculiaridad. Por último, la fábrica solo cuenta con un ascensor el cual suele estar siempre ocupado por lo que el operario deberá subir hasta 6 plantas a pie 65
para realizar la configuración de cada una de las raseras. Como se puede observar esta operación es tediosa y para nada cómoda. Con el objetivo de simplificar la operación al operario, en este TFG, se propone automatizar el control de apertura y cierre de raseras de manera centralizada.. Para automatizar esta tarea se pueden utilizar PLCs y hardware discreto, tal y como se vio en la Sección 3.1, sin embargo el cliente («Harinera Castellana») puso una serie de requisitos que conducirán el diseño. El requisito más importante es que el diseño debe ser de bajo coste. La «Harinera Castellana» tiene experiencia con la automatización basada en PLCs y conoce el coste de automatizar una línea con dicha tecnología por lo que se deberán tomar otras decisiones si se busca abaratar los costes y que finalmente el cliente opte por realizar la inversión.
Figura 5.1: Foto de un silo
Figura 5.2: Rasera (no corresponde a la utilizada en la fábrica. Sin embargo, las características son las misma)
Tras la primera reunión con «Automatinfo», se llega a la conclusión de que se realizará un hardware ad hoc para el proyecto. 66
5.2 Organización del proyecto En esta sección se describirá con detalle la estructura del proyecto así como cada una de las partes que lo conforman.
5.2.1
Los 3 proyectos
La complejidad de un sistema embebido radica en la coexistencia de diferentes partes que deben trabajar de forma conjunta. En este caso, la solución propuesta será un sistema empotrado cuyo diseño contemplará no solamente el software de aplicación (funcional y de gestión del dispositivo), sino también el diseño y armado de la tarjeta (PCB) donde se implementará el hardware correspondiente, y el diseño del firmware de gestión de dicha PCB. Para ello dividiremos el proyecto en tres subproyectos que se detallan a continuación siguiendo una estructura bottom-up: Proyecto hardware: Este proyecto también ha sido nombrado durante el documento como proyecto hardware. En él, se planteará el diseño y fabricación de una PCB en forma de shield para Arduino, de modo que esta sea acoplada a cada placa controladora1 , añadiendo seguridad al diseño. Además de la seguridad extra de la que se dota al diseño con esta PCB también se añade una capa HMI tal y como se verá más adelante. Sin duda alguna, este proyecto ha sido el más complicado debido a la escasa formación impartida en materia de electrónica en el grado en Ingeniería Informática. Proyecto firmware: La placa de control requiere de una pieza de código que permita gestionar los recursos hardware. Esta pieza de código se llama normalmente firmware. En este proyecto se han aplicado muchas de las competencias adquiridas durante los estudios de grado en Ingeniería Informática. Estos estudios me han permitido aplicar nuevos paradigmas a lo que hasta ahora seguía líneas de diseño poco flexibles y modulares. Proyecto software: En el proyecto software se realizará la implementación de un sistema SCADA (ver Figura 5.3) basado en tecnologías web. De esta manera, se busca mostrar una implementación de referencia para la Industria 4.0. Mediante el sistema web, el operario podrá monitorizar en cualquier momento y lugar las operaciones que se estén realizando en la fábrica. Durante el desarrollo del proyecto, se irán identificando, por cada subproyecto, los requisitos así como las decisiones de diseño y problemas encontrados. Además, con el objetivo de identificar la metodología dentro del proceso de diseño, se indicará el incremento realizado de modo que se pueda ver cómo se ha adoptado la metodología en el desarrollo del proyecto. 1
La placa controladora consiste en un Arduino Mega
67
Figura 5.3: Sistema SCADA Web desarrollado por INDAS
5.2.2
Proyecto PCB
En este apartado se describirá el desarrollo de la PCB. Tal y como se ha comentado anteriormente, el desarrollo del PCB surge como una decisión de diseño tomada conjuntamente con «Automatinfo» con el objetivo de reducir los costes frente al diseño basado en un PLC. Se podría haber utilizado algún PLC basado en Arduino y soluciones modulares sin la creación de un PCB. Sin embargo, la calidad del diseño se reduciría en un caso y se encarecería en el otro. A continuación se irán detallando cada una de las iteraciones realizadas basándonos en los módulos en los que se divide el PCB. Etapa de inicio, Desarrollo de prototipo Una vez acordada la decisión de desarrollar una PCB, el primer paso, tal y como se especifica en la metodología, consiste en realizar un prototipo sencillo que permita ir probando cada una de las funcionalidades que se vayan añadiendo a nivel firmware y hardware así como permita al cliente comprobar la adecuación del diseño. Requisitos o Restricciones En esta primera iteración o etapa inicial se han tenido en cuenta los siguientes requisitos a la hora de tomar las decisiones. Bajo coste: El diseño deberá ser de bajo coste. Los costes de prototipado serán añadidos al coste final del proyecto por lo que se deberá ser cuidadoso a la hora de elegir los componentes a utilizar. 68
Modular: En la medida de lo posible, el prototipo deberá permitir añadir y eliminar módulos de manera que se puedan ir probando diferentes alternativas y en caso de que algún módulo llegara a estar defectuoso se pueda reemplazar el mismo. Basado en Arduino: Se plantea la utilización de Arduino como plataforma base debido a su bajo coste y amplio recorrido en el sector. Funcionalidades o características añadidas En esta primera etapa, se añaden funcionalidades, recordemos de la Sección 4.2 que en una iteración se puede implementar una funcionalidad o mejorar (evolucionar) una existente. Las funcionalidades que se añaden en esta primera etapa son aquellas que permiten al usuario tener una visión de lo que será el producto final, es decir: Incorporación del módulo de comunicaciones: Estudio e implementación del módulo de comunicaciones y tecnología a utilizar. Incorporación del módulo de potencia: Estudio e implementación del módulo de potencia y de la infraestructura necesaria para el despliegue de la fuerza motora. Módulo HMI: Elección del módulo HMI así como implementación básica de estos. Decisiones de diseño Basándonos en el requisito de que el prototipo sea de bajo coste, se encargaron los siguientes módulos por Internet a varias páginas españolas con precios competitivos: Módulo de comunicaciones RS-485: El módulo de comunicaciones RS-485 tiene un precio de unos 7$. El precio es muy competitivo y además cumple con el requisito del que sistema sea modular dado que como se puede observar en la Figura 5.7, el módulo tiene incorporado todos los componentes necesarios para su gestión de tal manera que ofrece una interfaz sencilla al exterior. El módulo de comunicaciones utiliza un integrado Max485 que se encarga de adaptar la comunicación serie al estándar RS485. Si se hubiera optado por la incorporación de dicho integrado, habría que haber soldado el integrado a la placa de desarrollo y en caso de que el mismo fallara, el tiempo de sustitución aumentaría no cumpliendo así ni con el requisito de modularidad ni con el de bajo coste. Del mismo modo, este módulo es muy popular en el mundo Arduino y no habrá ningún problema a la hora de realizar las pruebas con el mismo. La elección del bus 485 radica en las características eléctricas de dicho bus. El bus 485 ha sido diseñado y pensado para la industria[fb01]. El estándar 485 únicamente especifica las características eléctricas del bus, por lo que el protocolo y las capas superiores no quedan al alcance de dicho estándar. Entre las características más importantes de este estándar, se encuentra el hecho de que permite velocidades de más de 35Mbits/s y 100 kbit/s a distancias de un kilómetro doscientos metros. Además, el bus 485 utiliza un 69
par diferencial balanceado sobre un cable trenzado, que permite que sea más inmune al ruido eléctrico y electromagnético. Por último, el bus 485 se utiliza en numerosos estándares como Modbus[ct09] o Probibus[des04] por lo que la instalación se podría reutilizar en caso de que fuera necesario, por ejemplo si se quisiera incorporar PLCs. Módulos controladores de motores: En este caso, se decidió adquirir un módulo controlador de motores basado en el integrado L298. El integrado L298 es un puente en H (ver Figura 5.5) el cual puede manejar hasta 2 amperios por canal. En este caso, el L298 cuenta con dos canales. Siguiendo con los requisitos se utilizará una placa que contiene todas las protecciones necesarias para manejar el motor. En la Figura 5.4 se puede ver una imagen del módulo utilizado. La utilización del controlador de motores viene condicionada por el hecho de la utilización de un cilindro eléctrico. Como se ha explicado en la Sección 5.1 las raseras son unas estructuras de metal que permiten pasar el fluido del silo hacia la zona de descarga. Históricamente se ha utilizado hidráulica para estos casos, no obstante, debido al requisito de bajo coste y la potencia requerida se ha utilizado un cilindro eléctrico. Los gastos asociados a un sistema hidráulico radican en la infraestructura necesaria. Por un lado, se requiere de bombas de presión, tuberías para el transporte hidráulico, etc. En cambio, para un cilindro eléctrico solo se necesita una red eléctrica. La decisión tomada para la elección del cilindro ha sido la de un «Hiwin LAS3-1-1250-24GE» (ver Figura 5.6), este cilindro está acompañado de un indicador resistivo de posición que será muy útil para comprobar la posición del cilindro dentro del silo.
Figura 5.4: Módulo L298. Fuente: http://blog.codebender.cc/
Implementación El prototipo tal y como se puede ver en la Figura 5.7 se ha montado sobre una protoshield. Una protoshield es una PCB que está perforada con el objetivo de que el usuario pueda añadir 70
Figura 5.5: Puente en H. Fuente: http://letsmakerobots.com/
Figura 5.6: Cilindro Hiwin LAS3-1-1250-24GE
todas las conexiones que necesite de una manera sencilla. A continuación explicaremos la implementación de cada una de las funcionalidades desarrollada. Implementación del módulo de comunicaciones El módulo 485 se comanda mediante niveles de tensión Transistor Transistor Logic (TTL), es decir, se considerará un voltaje bajo de 0v a 0.8v y alto de 2.2v a 5v[ttl03]. Esta interfaz coincide con la ofrecida en los pines de salida del Arduino por lo que no supondrá ningún problema comandar dicho módulo. El módulo consta de los siguientes pines: Driver Input (DI): Este pin recibe los datos desde el Arduino que serán enviados por el bus 485. 71
Figura 5.7: Primera versión del prototipo
Receive Output (RO): En este pin es donde el «Max485» deposita los datos recibidos por el bus 485. Driver Enable (DE): El pin DE permite habilitar la emisión desde el Arduino de datos. Receive Enable (RE): Para habilitar la recepción de datos se debe habilitar este pin. Tal y como se puede observar en la Figura 5.8, los pines DE y RE se activan de forma complementaria por lo tanto se puede realizar un puente entre ambos pines y de este modo nos aseguramos que cuando uno esté activado el otro no lo esté. El conexionado es bastante sencillo, el pin DE y RE se conectan haciendo un puente a un 72
pin del Arduino Mega. Así, los pines DI y RO se conectan a uno de los puertos seriales del Arduino. Aquí tenemos dos opciones conectarlo a un puerto serial hardware o a un puerto serial virtual. A continuación se explicará las diferencias entre ambas implementaciones: Puerto serie hardware: El puerto serie hardware consiste en una unidad UART implementada en hardware, esto es, determinado número de transistores estarán configurados dentro del chip para realizar esta función. El Arduino Mega tiene varias unidades UART hardware por lo que en principio se podría conectar sin ningún problema a una de ellas (hay que tener en cuenta que la mayoría de los Arduinos solo tienen una y está ocupada). Cuando el Arduino recibe un dato genera una interrupción tal y como se verá más adelante. Esta interrupción avisa al microcrocontrolador y ejecuta una rutina. La carga por parte de microcontrolador reside en la gestión de esa interrupción. Puerto serie software: Debido a que el Arduino posee determinados pines que tienen asociadas interrupciones en el cambio de flanco es posible simular una unidad UART sencilla para la comunicación serial. En el caso de Arduino, existen diferentes pines que pueden ser utilizados para este propósito y pueden ser comprobados desde el siguiente enlace https://www.arduino.cc/en/Reference/SoftwareSerial. La carga del microcontrolador en este caso es mayor debido a que existe un número más alto de interrupciones que deberán ser manejadas por el mismo y por lo tanto aumentará el tiempo dedicado a cada comunicación. En el Listado 5.3 se puede ver como se implementa la unidad UART mediante este tipo de interrupciones. Como se puede observar y haciendo una búsqueda en la documentación, la interrupción PCINT se produce cuando alguno de los pines en ese banco cambia de nivel por lo que la sobrecarga es muy alta. En general se deberá utilizar el puerto hardware siempre que se pueda debido al uso intensivo de las interrupciones es por ello que se decide conectar el pin DI al Tx2 del Arduino y el RO al Rx2 del Arduino. Una vez conectado el módulo al Arduino se creará un programa de prueba para comprobar que el módulo funciona por sí mismo. Los programas utilizados para la comprobación de funcionamiento del módulo se muestran tanto en el Listado 5.1 como en el Listado 5.2. 1
void setup() {
2
Serial2.begin(9600);
3
pinMode(67,OUTPUT);
4
}
6
void loop() {
7
digitalWrite(67,HIGH);
8
serial.println("Hola"); delay(100);
9 10
}
73
Listado 5.1: Prueba de envío por módulo 485 1
void setup() {
2
Serial.begin(9600);
3
Serial2.begin(9600); pinMode(4,OUTPUT);
4 5
}
7
void loop() {
8
digitalWrite(4,LOW);
9
if(Serial2.available()){ Serial.print((char)Serial2.read());
10 }
11 12
}
Listado 5.2: Prueba de envío por módulo 485
Figura 5.8: Descripción de pines obtenido del datasheet
De esta manera ya tenemos comprobada la funcionalidad tanto hardware como software y podemos asegurar que este módulo se comporta según lo esperado.
Implementación del módulo de control de motores El siguiente módulo a implementar es el controlador de motores L298. Este controlador consiste, en un «puente en h» (ver Figura 5.5). Un «puente en h» se basa en una configuración de transistores que permite invertir la polaridad de la corriente continua. El módulo utilizado proporciona una interfaz que evita tener en cuenta los diferentes elementos de protección para circuitos de potencia. Sin embargo, como se trata de un trabajo con fines educativos se explicará brevemente tanto la interfaz que proporciona como las protecciones ofrecidas. En la Figura 5.9 se puede ver el datasheet del driver utilizado. Como se puede observar el módulo aporta unos diodos protectores de corrientes inversas así como unos led notificadores. También es importante tener en cuenta que en este módulo se incorpora un regulador de tensión lineal, el MC78M05 que alimentará la lógica, es decir el L298. Si se aporta una 74
Figura 5.9: Datasheet módulo de control de motores
corriente superior a 5v o, en caso de que sea necesario se podrá desactivar si se alimenta con una tensión de 5v por la entrada destinado al voltaje lógico. En cuanto a la interfaz que proporciona el módulo se puede ver en la Figura 5.11. Esta interfaz proporciona los pines y conectores siguientes: Borneros laterales: En los borneros laterales se puede conectar el motor a controlar, en nuestro caso el cilindro. En la Figura 5.11 no se aprecia pero al lado de cada bornero viene indicado a qué salida del L298 corresponde. Si una salida se activa (5v) entonces el bornero correspondiente a esa salida ofrece el voltaje indicado en el bornero inferior que en la Figura 5.11 aparece indicado como: «12v input from DC power source». En este caso el voltaje será de 24 voltios debido a que es el voltaje del cilindro. Bornero inferior: Consiste en un bornero con tres entradas. La primera entrada empezando por la izquierda se utiliza para indicar el voltaje de alimentación de la etapa de potencia, es decir, el voltaje que irá a cada uno de los borneros laterales. La entrada central es la tierra. Por último, la entrada de la derecha sirve como entrada o salida en función de si el jumper indicado en la Figura 5.11 está habilitado o no. Si está habilitado entonces este bornero será una salida y proporcionará 5 voltios por si se necesitara. Pines de conexión: Los pines de conexión permiten habilitar las diferentes salidas. Además, a cada extremo se proporciona un pin que permite que se utilice con una señal Pulse Width Modulation (PWM) de modo que regule la velocidad de los motores 75
1 2 3
#if defined(PCINT0_vect) ISR(PCINT0_vect) { SoftwareSerial::handle_interrupt();
4 5 6
}
8 9
#if defined(PCINT1_vect) ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
#endif
10
#endif
12 13 14
#if defined(PCINT2_vect) ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
16 17 18
#if defined(PCINT3_vect) ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
20
}
#endif
#endif
Listado 5.3: Interrupciones en SoftwareSerial
La conexión con el cilindro queda tal y como se puede ver en la Figura 5.10. En este punto puede surgir la dudad de qué hace ese jumper entre los pines 1-3 y 2-4. Tras probar en el banco de pruebas y observar la hoja de características del cilindro se comprueba que el consumo máximo puede superar los 2 amperios que permite un único canal. Si se alcanzara la máxima potencia entonces el L298 se quemaría, es por ello que se utilizan los dos canales de forma simultánea para comandar el cilindro. En cuanto a la conexión de los diferentes pines al Arduino no supone ninguna dificultad debido a que es una interfaz TTL y por lo tanto lo único que hay que hacer es conectar el pin de forma directa a una salida del Arduino. En el Listado 5.4 se puede ver el código utilizado para el testeo del L298. Como se puede observar el código es muy sencillo, únicamente hay que habilitar los pines de salida de modo que el motor avance o retroceda en función de en que sentido se otorgue la corriente. 1
int IN3 = 12;
2
int IN4 = 13;
4
void setup()
5
{
6
pinMode (IN2, OUTPUT);
7
pinMode (IN4, OUTPUT);
8
pinMode (IN1, OUTPUT);
9
pinMode (IN3, OUTPUT);
10
}
11
void loop()
12
{
76
Figura 5.10: Conexión del cilindro al controlador de motores.
Figura 5.11: L298
13
// Backward
14
digitalWrite (IN1, HIGH);
15
digitalWrite (IN3, HIGH);
16
digitalWrite (IN2, LOW);
17
digitalWrite (IN4, LOW);
18
delay(19000);
77
20
//STOP
21
digitalWrite (IN1, LOW);
22
digitalWrite (IN3, LOW);
23
digitalWrite (IN4, LOW);
24
digitalWrite (IN2, LOW);
25
delay(500);
26
//Forward
27
digitalWrite (IN2, HIGH);
28
digitalWrite (IN4, HIGH);
29
digitalWrite (IN1, LOW);
30
digitalWrite (IN3, LOW);
31
delay(19000);
33
//STOP
34
digitalWrite (IN1, LOW);
35
digitalWrite (IN3, LOW);
36
digitalWrite (IN2, LOW);
37
digitalWrite (IN4, LOW); delay(500);
38 39
}
Listado 5.4: Programa de prueba L298 Por otro lado, el cilindro proporciona un sensor resistivo el cual permite saber la posición del sensor en el silo. En la Figura 5.12 se puede ver la conexión de este tipo de sensores al Arduino. El código para el testeo de este sensor no se incluye debido a la simplicidad del mismo. En [enf16] se pueden ver códigos de referencia para este propósito.
Figura 5.12: Conexión de potenciometro a Arduino. Fuente: http://arduineando.matem.unam. mx/
78
Implementación del módulo HMI El módulo HMI es una parte común en los sistemas basados en PLC y en general en los sistemas de automatización. Con el objetivo de brindar al cliente una primera revisión de lo que será el módulo de comunicación se desarrollará una primera versión del módulo HMI. El módulo HMI elegido para la representación visual ha sido una pantalla Nokia 5110 (ver Figura 5.13).
Figura 5.13: LCD Nokia 5110 utilizada para el proyecto. Fuente: http://www.hobbytronics. co.uk/
La elección de esta pantalla se basa en las siguientes características: Dimensión: La dimensión de 84x48 es suficiente para los menús y pantallas que se diseñarán2 . Simplicidad: La utilización de esta pantalla no requiere muchas líneas de código. Además, este lcd es de uso común en Arduino por lo que se podrá encontrar suficiente documentación y ejemplos en línea. Comunicación: La comunicación se realiza mediante la interfaz I2C. Esta interfaz requiere de muy pocos cables y simplifica la labor de enrutado en la etapa de creación de la PCB. Disponibilidad: Es muy importante tener en cuenta la disponibilidad de los recursos de modo que si se requiere en algún momento reemplazar un lcd porque se ha dañado se pueda disponer de repuestos en un corto espacio de tiempo. Precio: El precio de un módulo LCD es de 7.20$ . Esto resulta muy económico si se compara con HMI real que puede llegar a valer 1113$. 2
No se debe confundir este sistema de representación con el software de gestión. Normalmente el operario comprobará el estado de las raseras desde el software de gestión
79
La implementación de este módulo es bastante sencilla, no obstante se tienen que tener en cuenta varios factores a la hora de realizar el conexionado. El lcd3 es un dispositivo pensado para trabajar a 3.3 voltios. Esto es importante debido a que el Arduino Mega trabaja a 5v. Para solucionar este inconveniente una opción consiste en realizar un divisor resistivo. El divisor resistivo aunque no es muy adecuado para manejar cargas, para realizar un cambio de nivel de tensión en unidades lógicas no es del todo desaconsejado. Como se puede observar en la Figura 5.14, se han utilizado diferentes resistencias para obtener el valor de 5 voltios. La manera más sencilla de calcular el valor de la resistencia es utilizar el mecanismo de prueba y error. Los dispositivos suelen aguantar un tiempo considerable trabajando a más voltaje del que deben (siempre y cuando la diferencia de potencial sea pequeña, como en este caso) por ello se empieza poniendo una resistencia de valor de 1kOhm y se comprueba cuál es la caída de potencial en la resistencia, de este modo sabemos cual es la resistencia del pin y podremos calcular el valor exacto. Los valores elegidos para este caso son: SCE: 1kOhm RST: 10kOhm D/C: 10kOhm DN: 10kOhm SCLK: 10kOhm Una vez conectado el LCD, se probó utilizando un software de testeo el cual se puede ver en el Listado 5.5. El test se pasó con éxito (ver Figura 5.15) por lo que este módulo se incorporó en el prototipo final. 1
#define SCLK_PIN A4
2
#define SDIN_PIN A3
3
#define DC_PIN A2
4
#define SCE_PIN A1
5
#define RESET_PIN A0
7
#define LED_PIN A5
9
PCD8544 lcd (SCLK_PIN, SDIN_PIN, DC_PIN, RESET_PIN, SCE_PIN);
11
void setup() {
12
lcd.begin();
13
pinMode(LED_PIN, OUTPUT);
15
}
3
En este documento se hablara indistintamente de lcd, LCD, o pantalla
80
Figura 5.14: Esquema de conexionado del LCD. Fuente: http://electronilab.co/
17
void loop() {
18
digitalWrite(LED_PIN,HIGH);
19
lcd.setCursor(0, 0);
20
lcd.print("Test");
21
lcd.setCursor(0, 1);
22
lcd.print("Passed");
23
lcd.setCursor(0, 2);
24
lcd.print("Constructor:");
25
lcd.setCursor(0, 3);
26
lcd.print("A4 A3 A2 A0 A1");
27
}
Listado 5.5: Prueba del LCD de nokia El siguiente módulo que se incorporará en esta iteración será el modulo infrarrojos, mediante este módulo se permite al usuario interactuar con el lcd facilitando el movimiento entre diferentes menús. El módulo infrarrojo utilizado es un equivalente del «AX-138HS». Este dispositivo tiene la apariencia de un led sin embargo dentro contiene lógica de control que permite dotar al dispositivo de las siguientes características: Fotodetector y preamplificador. 81
Figura 5.15: Prueba del LCD
Filtro para frecuencias PCM. Protegido para rechazar interferencias. Alta inmunidad frente a la luz ambiente. Protección frente a campos electromagnéticos. Compatible con 5 y 3.3 voltios. Compatible con lógica TTL y Complementary Metal-Oxide Semiconductor (CMOS). El conexionado de este módulo, al igual que el de los demás es muy sencillo. El circuito consta de una resistencia de pull-up utilizada en la salida. Además, se añade un capacitor de filtrado de 47uF entre tierra y alimentación. El conexionado puede ser consultado en la Figura 5.16. Tal y como con los demás módulos, el primer paso consiste en llevar el esquema a la realidad en alguna plataforma de prototipado, seguidamente se desarrolla un código de testeo y por último se incorpora al prototipo final en el caso de que todos los test hayan resultado exitosos. En la Figura 5.17 se puede ver el prototipo del esquema del módulo infrarrojo. El código utilizado para el testeo de este módulo es uno de los ejemplos proporcionados por la librería «IRremote» que es la que se ha utilizado para gestionar este módulo por lo que no se añadirá el código. En la Figura 5.18 se puede ver la salida obtenida al pulsar el botón 0 del mando infrarrojo. El mando puede ser cualquier mando infrarrojo soportado por la librería IRremote. 82
Figura 5.16: Esquema de conexión del módulo infrarrojo. Fuente: Datasheet AX-138HS
Figura 5.17: Impresión de salida obtenida del módulo infrarrojo
Figura 5.18: Montaje módulo infrarrojo
Integración de módulos El último paso de esta iteración consiste en integrar los módulos anteriormente probados dentro de una misma plataforma la cual será entregada al cliente junto al firmware como prototipo inicial. 83
Como ya se ha comentado anteriormente, la plataforma se basará en una shield de Arduino. Las Shield son unas placas que se conectan encima de la placa Arduino, adaptándose al estándar de pines Arduino. Para el prototipo inicial se utiliza una de las shield preparadas para prototipado de Sparkfun. Estas shield permiten comprobar rápidamente el resultado final de nuestro proyecto sin necesidad de imprimir una costosa PCB. Para la fase de prototipado este tipo de shields son muy recomendadas. En la Figura 5.19 se puede ver una shield de prototipado de Sparkfun. En este punto podría surgir la duda de por qué fabricar entonces una PCB si con el una shield de prototipado podría funcionar. Aunque el funcionamiento es posible, las placas de prototipado tienen altas impedancias en sus enrutados, son altamente vulnerables al ruido electromagnético y presentan muchos problemas de contacto. Como resultado del acoplamiento de todos los módulos descritos anteriormente se obtiene el prototipo mostrado en la Figura 5.20. Como se puede observar contiene todos los módulos principales. Como resultado de la iteración se genera un producto entregable al cliente que podrá testar y en consecuencia reportar el feedback necesario para futuras iteraciones.
Figura 5.19: Shield para prototipado de Sparkfun. Fuente: https://www.sparkfun.com
Bucle de iteración, Iteración 1: Alimentación Requisitos o Restricciones Para esta iteración, los requisitos o restricciones que entran en juego son los siguientes: Bajo coste: En la mayor parte de las iteraciones aparecerá este requisito debido a que es un requisito conductor del proyecto. Seguro: Tal y como se verá más adelante, se requerirá de una alimentación segura4 . Fiable: La fiabilidad es un requisito impuesto por la naturaleza del sistema. Se deberá tener en cuenta a la hora de elegir los componentes así como configurar sus parámetros. 4
En este caso seguro significa que sea estable y en la medida posible inmune al posible ruido de la línea
84
Figura 5.20: Prototipo final con el firmware resultado de la iteración inicial
Funcionalidades o características añadidas En esta iteración se añadirá todo el apartado de alimentación. Tal y como se describió en la Sección 3.6.1, las fuentes de alimentación son una parte primordial de los sistemas embebidos. Si la fuente de alimentación no está estabilizada el diseño puede que falle de forma esporádica. Como resultado de esta iteración se incorporará la alimentación al prototipo. Decisiones de diseño Una mala decisión de diseño a la hora de seleccionar una fuente de alimentación puede hacer que el sistema resulte inviable. En este apartado veremos las decisiones de diseño que se han tomado a la hora de diseñar el módulo de alimentación. La alimentación en el proyecto está dividida en dos partes: Alimentación de potencia: La alimentación de potencia se utiliza, como su nombre indica, para la parte de potencia del circuito. Para nuestro caso, se utiliza para el controlador de motores y para el cilindro. Además, tal y como se verá en la iteración de optoacoplamiento, el controlador del bus RS-485 se alimenta con esta fuente de alimentación. Alimentación lógica: Esta alimentación solo se utilizará para el control y la lógica del sistema, es decir, para aquellas partes que no estén comunicadas de forma directa con la parte de potencia. Separando las fuentes de alimentación conseguimos una reducción en cuanto a la emisión de ruido electromagnético así como diversos problemas que pudieran aparecer por un mal 85
funcionamiento de la etapa de potencia. El ruido eléctrico generado por los motores es un fenómeno muy estudiado. En libros como [sen05], se tratan numerosos filtros y teoría de fuentes de alimentación que permiten mitigar los problemas por ruido eléctrico. Para evitar que cualquier interferencia producida por ruido eléctrico en el bus de comunicaciones dañe la lógica de nuestro circuito, conectaremos el mismo a la fuente de alimentación de potencia. La fuente de alimentación elegida para la potencia se puede ver en el siguiente enlace http: //www.securame.com/fuente-de-alimentacion-transformador-24v-20a-p-683.html. Esta fuente de alimentación es de bajo coste y tiene una salida bastante estable por lo que en principio es una opción viable. Por otro lado, la fuente de alimentación para la parte lógica podría ser por ejemplo cualquiera de un smartphone moderno de buena calidad. Estos smartphones vienen con fuentes de alimentación bastante estables debido al hecho de que alimentan electrónica muy sensible. Otro problema que surge es la obtención de los voltajes adecuados. El control funciona a 5 voltios, esto está cubierto por la fuente de alimentación de la lógica dado que normalmente las fuentes de los smartphone van desde los 5v hasta los 12v. Esta tensión, tal y como veremos en la implementación es suficiente para el Arduino. Por otro lado, el motor utiliza un voltaje de 24 voltios que se obtiene directamente de la fuente de alimentación de potencia por lo que aquí no hay que hacer ningún tipo de conversión. Sin embargo, tanto los módulos controladores de motores así como el módulo de comunicación que estarán alimentados por la fuente de potencia trabajan en niveles TTL, es decir, de 0 a 5 voltios por lo que en este caso sí que habrá que hacer una adaptación de voltaje. Para realizar esta adaptación o en este caso reducción, existen dos alternativas: Reguladores lineales de tensión: Son dispositivos poco eficientes energéticamente pero bajo unas condiciones de temperatura adecuadas son bastante estables. Reguladores de conmutación: Este tipo de reguladores son más eficientes pero añaden más ruido al sistema por lo que habrá que tomar precauciones extras a la hora de utilizarlos. En este caso se ha optado por la utilización de los reguladores lineales de tensión dado que no generan tanto ruido y por lo tanto reducen el número de componentes necesarios en el PCB disminuyendo consecuentemente el coste total del proyecto. En la implementación de esta iteración se vera técnicamente cómo se abordan todas estas decisiones de diseño. Implementación Implementación de la alimentación Tal y como se comentó en las decisiones de diseño, en este proyecto se han separado las alimentaciones de tal modo que la parte de potencia y la parte de control no se alimenten de 86
un mismo lugar. El realizar esta separación, permite que no se presenten ruidos eléctricos en las líneas de control. En el caso de la fuente de alimentación de potencia la implementación es directa, únicamente habrá que conectar la salida de la fuente (24 voltios) al controlador de motores. En la Figura 5.11 se puede ver cómo el bornero inferior tiene una entrada para 12 voltios. Tal y como se comentó anteriormente, esta entrada no tiene porque ser de 12 voltios, también puede ser de 24 voltios o hasta 50 voltios según la hoja de datos del L298. Por otro lado, la tierra se conecta al bornero inferior de tierra. De este modo ya tenemos alimentada la potencia dado que el cilindro va directamente acoplado a los borneros laterales y obtiene la corriente de los 24 voltios. Como se puede ver, la implementación de esta parte es bastante sencilla, es importante tener en cuenta que la tierra del Arduino también tendrá que ir conectada a la tierra del L298 dado que de momento, los pines de habilitación se manejan desde el Arduino. El siguiente paso consiste en realizar la conversión de niveles de voltajes, para ello se utiliza un regulador de tensión. Una desventaja de estos reguladores de tensión son las temperaturas alcanzadas en el encapsulado. Esta temperatura es fácilmente cuantificable teniendo en cuenta los datos del datasheet. Para intentar disminuir esta temperatura y no hacer trabajar al regulador de tensión en los límites otorgados por el fabricante, se realizará una doble regulación primero descendiendo de 24 voltios a 12 con un regulador LM7812 y más tarde de 12 voltios a 5 voltios con un regulador LM7805. En la Figura 5.21 se puede ver el máximo voltaje permitido para la entrada del regulador. Hay que tener en cuenta que una caída alta de potencial supone una menor eficiencia por lo que se recomienda reducir tal y como se ha indicado anteriormente la diferencia de potencial.
Figura 5.21: Hoja de datos para la familia LM78XX
Siguiendo la hoja de datos del LM7812 la cual se puede revisar desde la Figura 5.21 se puede observar que el máximo voltaje de entrada está estipulado para 40 voltios por lo que en principio no debería haber problema en cuanto a la caída potencial. En la Figura 5.22 se puede observar las conexiones realizadas para los reguladores de tensión. Como se habrá podido observar la conexión es bastante sencilla, los 24 voltios se 87
Figura 5.22: Esquema de alimentación implementado.
aplican al regulador LM7812 que proporciona 12 voltios los cuales serán la entrada del regulador LM7805 que, finalmente otorgará 5 voltios al circuito. Los 5 voltios, de momento, solo alimentarán al módulo de comunicaciones, no obstante, en otras iteraciones se verá como la utilidad es mayor. La conexión con el módulo de comunicaciones es inmediata. Únicamente habrá que conectar la salida del LM7805 a VCC del Max485, y la tierra del LM7805 a la tierra del Max485. De este modo ya están alimentados tanto el motor como los controladores y el módulo de comunicaciones. El último elemento que queda por alimentar es el Arduino Mega. Para alimentar este controlador, se utilizará un cargador de smartphone o similar como el mostrado en la Figura 5.23. A la hora de alimentar el Arduino, es importante conocer cómo está diseñado. Para ello veremos brevemente la parte de alimentación del esquemático en este caso, del Arduino Mega. En la Figura 5.24 se puede ver el esquemático de la etapa de alimentación del Arduino. A la entrada de la alimentación externa posee un diodo de protección y un par de condensadores de filtrado conectados a la entrada del MC33269. Este integrado es un regulador lineal de voltaje Low-DropOut (LDO) con un voltaje recomendado de entrada no mayor a 20 voltios, dato que se deberá tener en cuenta a la hora de conectar una fuente de alimentación. A la salida del regulador tendremos un voltaje de 5 voltios estables. Por otro lado, en paralelo, se incorpora otro regulador para intentar compensar la carga entre ambos integrados de modo que no se demande más de lo necesario a cada uno. El Arduino también posee un circuito de protección para el caso en que se conecte tanto el USB como un voltaje externo. En la Figura 5.25, como el lector habrá podido inferir, si la mitad del voltaje de alimentación 88
Figura 5.23: Cargador genérico de smartphone
es igual o menor que 3.3 voltios entonces el Arduino habilita la compuerta de un mosfet permitiendo conectar los 5 voltios de alimentación con la alimentación USB. De aquí se infiere que el rango de entrada de la fuente de alimentación irá de 6,6 voltios + 0,7 voltios del diodo de entrada hasta un máximo de 20 voltios.
Figura 5.24: Esquema de alimentación del Arduino. Fuente: http://www.arduino.cc
Con esta conexión ya tenemos todo el conexionado realizado y el sistema de alimentación bien segmentado y listo. 89
Figura 5.25: Esquema de comparación de voltajes. Fuente: http://www.arduino.cc
Bucle de iteración, Iteración 2: Aislamiento Requisitos o Restricciones En esta iteración se realizarán una serie de mejoras que permitirán añadir seguridad y fiabilidad al sistema. Esta iteración intenta satisfacer los requisitos siguientes:
Seguridad: El sistema deberá ser resistente a fenómenos eléctricos no deseados como picos de tensión. Además, en caso de fallo el tiempo de reemplazo debe ser el menor posible para evitar grandes paradas de producción. Fiabilidad: El diseño debe ser fiable y robusto desde la primera etapa. Mejoras realizadas, evolución del diseño En esta iteración, las características a añadir consistirán en el desacoplamiento completo entre la parte de potencia y la parte de control. Para realizar este tipo de desacoplo entre control y potencia se pueden utilizar diferentes alternativas que serán estudiadas en la siguiente sección 90
Decisiones de diseño Tal y como se comentó en la Sección anterior, existen diversas maneras de asilar la potencia del control. A continuación se desarrollarán cada una de estas alternativas con el fin de argumentar el porqué se optó por una de ellas. Salidas basadas en relés: Los PLC utilizan este tipo de alternativa, cada una de las salidas de un PLC está comandada por un relé. La desventaja principal de este tipo de desacoplo reside en el hecho de que el relé es un dispositivo mecánico y como tal se degrada con el tiempo reduciendo así la vida útil del sistema. Además, los relés tienen otra desventaja que consiste en que por la propia naturaleza del relé se genera una corriente inversa cuando se deja de alimentar el mismo. Esto se debe a que el relé está formado por una bobina que se opone al cambio del corriente generando una corriente en el sentido contrario para compensar este cambio de corriente. Este fenómeno es peligroso para los microcontroladores, es por ello que normalmente se conecta un diodo en antiparalelo para evitar esta corriente inversa tal y como se puede ver en la Figura 5.26. Como resumen podemos concluir que las desventajas de este tipo de salida basada en relés son el ruido eléctrico y la vida útil. Salidas basadas en transistores: Otra forma de aislar las etapas de potencia de las etapas de control es mediante transistores. Los transistores son switch de estado sólido. Los transistores sustituyeron a los tubos de vacío y a los relés. La teoría de transistores es muy amplia y no es objeto de este documento el detallar la misma, sin embargo, si se desea, se puede consultar [pri09] donde se aborda detalladamente la teoría de circuitos basados en transistores. De forma sencilla, un circuito general con un transistor cuenta con una resistencia de base que polariza la unión emisor-base, por otro lado, se tiene otra resistencia de colector que determina la intensidad de colector y finalmente una carga que puede ser inductiva o no inductiva (ver Figura 5.27). En el caso de una carga inductiva se utiliza también un diodo en antiparalelo. Los transistores podrían utilizarse para el aislamiento, no obstante, estos dispositivos no proporcionan un aislamiento físico completo por lo que en función del tipo de problema que surgiera podría darse el caso de que el transistor pasara a estar en cortocircuito por lo que no es el modo más recomendado para aislar. Salidas basadas en optocopladores: Esta es, a día de hoy, la solución más utilizada para el desacople de la etapa de potencia y es la que se adoptará en este trabajo. Los optocopladores proporcionan un aislamiento físico, es decir, los dos circuitos no tienen ningún contacto físico y además el encapsulado se protege para que nunca ocurra este contacto. En la implementación de esta iteración se explicará con detalle como se ha abordado esta tarea. Resumiendo existen muchas formas de aislamiento, cada una con sus ventajas y desventajas. Los optocopladores nos permiten cumplir con los requisitos de la iteración dado que 91
Figura 5.26: Esquema con Diodo D1 en antiparalelo. Fuente: http://ovtoaster.com/
Figura 5.27: Esquema de transistores con carga inductiva y no inductiva.
proporcionan fiabilidad y seguridad. Si un optocoplador se quemara es muy sencillo reemplazarlo por otro nuevo abaratando así los costes de mantenimiento. Implementación Implementación del aislamiento de los controladores de motores Los optocopladores son dispositivos formados por un emisor de luz, normalmente un LED infrarrojo y normalmente también un fototransistor. También existen otros optocopladores que usan fototriac, transistores Field-Effect Transistor (FET) sensibles a la luz, etc[ele81]. En la Figura 5.28 se puede ver el esquema de un optocoplador común. 92
Figura 5.28: Representación de un optocoplador formado por un diodo led y un fototransistor.
Los parámetros más importantes de un optocoplador son los siguientes: V(BR)ECO : Voltaje de ruptura emisor colector. Esto quiere decir que si se aplica un voltaje mayor a este entre el emisor y el colector, el optocoplador se dañará. V(BR)CEO : Voltaje de ruptura colector emisor, es el máximo voltaje que se puede aplicar entre el colector y el emisor, si se excede este voltaje el optocoplador se dañará. Current Transfer Ratio (CTR): El CTR es la ratio de transferencia entre la corriente en el led y la corriente en el colector. Este factor es parecido a la β de un transistor pero con algunas diferencias. VF: Describe la caída de potencial en el diodo emisor de luz. Para utilizar un optocoplador lo primero que hay que tener en cuenta es como «hacer lucir» el led emisor de luz con la suficiente fuerza como para que el fototransistor pase a la región de corte. Para calcular esto debemos basarnos en las hojas de características. Tras observar estas hojas de datos se llega a la conclusión de que con 3mA será suficiente, además, la duración de los optocopladores aumentará considerablemente. Debido a que se comandarán entradas TTL, el consumo será prácticamente inexistente. En la Figura 5.29 se puede ver el esquema utilizado en la optoacoplación de los módulos de control. Como se puede observar en la parte derecha correspondiente a las salidas del Arduino, estas van conectadas al ánodo del led emisor, y el cátodo se conecta a la tierra del Arduino a través de una resistencia de 1,2 kohms. En el otro lado, el de potencia, el colector se conecta a los 5 voltios de potencia que provienen del regular LM7805. En el emisor conectamos la salida y se añade una resistencia del pull-down de tal manera que por defecto está a tierra y cuando entra en saturación pasa a estar a 5 voltios. Esta salida se conecta a cada uno de los pines de habilitación como puede verse en la Figura 5.11. Con esto queda aislado completamente el Arduino o la parte de control de la parte de potencia o los módulos controladores de motores. 93
Figura 5.29: Esquema implementado para la optoacoplación del módulo de motores.
Implementación del aislamiento del bus de campo El bus de campo puede ser una fuente de peligros si no se aísla correctamente. la mayoría de transceptores suelen incorporar algún tipo de aislamiento sin embargo, el «Max485» que es el transceptor utilizado en este caso, no contiene ningún tipo de aislamiento por lo que se deberá implementar de forma externa. El bus 485 está conformado por un par diferencial. Esto quiere decir que por una línea irá un nivel lógico y por la otra su negado. A nivel eléctrico esto conlleva a que por una línea vayan voltajes positivos y por otras negativos. Esto permite eliminar la mayoría de los ruidos, sin embargo, es complejo de aislar. Para aislar este tipo de comunicación, una solución bastante extendida es la implementada en este TFG. En la parte superior de la Figura 5.30 se observa el acoplamiento entre la salida RS485 y la entrada al puerto Rx de Arduino. La salida del RS-485 se conecta al cátodo para que la lógica no se vea invertida. Si en RS485OUT se activa un nivel lógico alto entonces la diferencia de potencial entre el ánodo y el cátodo es de 0 voltios. Esto provoca que la entrada del Arduino reciba 5 voltios debido a la resistencia de pull-up. En el otro caso, si el RS485OUT alcanza un nivel bajo entonces la diferencia de potencial será de 5 voltios polarizando el diodo led y 94
Figura 5.30: Esquema implementado para la optocoplación del módulo de comunicaciones.
entrando en saturación el fototransistor y llevando a 0 voltios la entrada del Arduino. Como se puede observar, aunque de una forma no demasiado simple, se puede volver a negar los niveles lógicos consiguiendo mantener intactas las comunicaciones. En la parte inferior el procedimiento seguido es el mismo con la diferencia de que ahora es el Arduino quien escribe y el módulo de comunicaciones quien lee. Otro punto muy importante que no se debemos pasar por alto es ver la forma de onda al realizar este optoacoplamiento. En un escenario ideal las transiciones desde que el led se enciende hasta que aparece 5 voltios a la salida del fototransistor debería ser inmediata, sin embargo esto no ocurre así, esto se debe a que los dispositivos no son ideales y tienen capacitancias e inductancias que no permiten cambios de estado tan rápidos. Para comprobar que la forma de onda se adecúa a nuestras necesidades se han realizado pruebas con un osciloscopio digital. En la Figura 5.32 se puede ver la forma de onda de entrada y de salida para el circuito implementado en protoboard de la Figura 5.31. Como se 95
puede comprobar el cambio de voltaje no es inmediato si no que pasa un tiempo hasta que este llega a su valor máximo, es decir, no es una onda cuadrada perfecta, sin embargo es más que suficiente para la transmisión a máxima velocidad.
Figura 5.31: Prototipo implementado para el aislamiento y pruebas con el osciloscopio.
(a) Retardo en flanco debido a el optoco- (b) Retardo en flanco debido a el optoplador coplador con menos resolución
Figura 5.32: Retardos debido a optocoplamiento
De esta manera ya tenemos aislado el módulo de comunicaciones de la lógica de control por lo que no hay peligro de acoplamiento. 96
Bucle de iteración, Iteración 2: Del prototipo al PCB Requisitos o Restricciones Los requisitos para esta iteración son los siguientes: Bajo coste: Al igual que en las demás iteraciones, en esta se necesita que el coste sea bajo para que el coste de todo el sistema sea bajo. Mantenible: Es importante que el diseño sea fácilmente mantenible para abaratar los costes en la fase de mantenimiento. Estandarizado: En la medida de lo posible se deberán utilizar componentes estandarizados dado que de esta manera se asegura la compatibilidad del diseño. Mejoras realizadas, evolución del diseño En esta iteración no se añadirá ninguna funcionalidad por el contrario se va a pasar del prototipo al diseño final, en este caso un PCB. En esta iteración únicamente se estudiarán las diferentes alternativas en cuanto a herramientas CAD para el diseño de circuitos electrónicos, además, se explicará el proceso de instalación así como la familiarización con la herramienta lo cual supuso un tiempo extra a la hora del diseñar el producto dado que hasta ahora no se tenía ninguna experiencia con la misma. Decisiones de diseño Existen numerosas herramientas CAD para el diseño electrónico, sin embargo, a la hora de tomarla decisión de qué herramienta utilizar se tuvieron en cuenta las siguientes: Eagle: Eagle proviene de «Easily Applicable Graphical Layout Editor»[mak14] es un editor de diagramas y de PCBs muy asentado en la industria, sobretodo en la comunidad maker de la que se habló en la Sección 3.2. Las ventajas más relevantes de este software es en primer lugar su gran documentación en línea. Gracias al apoyo de muchas empresas como Sparkfun a día de hoy se pueden encontrar todo tipo de librerías con componentes de la mayoría de las grandes empresas de desarrollo de componentes electrónicos. Por ejemplo, Eagle proporciona una librería con todos los componentes que tiene a la venta, de esta manera se simplifica muchísimo la labor de creación del PCB. Otra ventaja muy importante en este proyecto es que Arduino desarrolló sus placas con este software por lo que todos los ficheros fuentes están disponibles para ser modificados de manera sencilla desde Eagle. Además, la mayoría de los fabricantes de PCBs dan soporte al formato Eagle por lo que no será necesario exportar los gerbers como en otros software de edición. Entre las desventajas más importantes se destaca el hecho de que es de pago, aunque existe una versión gratuita con una serie de limitaciones que hacen que no sea posible realizar diseños de gran tamaño con dicha versión. Otra desventaja es la usabilidad dado que en muchos casos resulta complejo 97
realizar acciones sencillas como mover un componente de un esquema a otro. OrCad: Este software CAD fue uno de los primeros en aparecer en el mercado. Las ventajas principales de este software es la experiencia que tienen en el mercado así como la estabilidad con la que cuenta. OrCad no es solo un software de diseño electrónico, además de permitir la creación de esquemas eléctricos y PCBs, también cuenta con una pieza de software para la simulación de circuitos. Una de las virtudes de este programa se encuentra en la integración de herramientas de tal manera que el flujo de trabajo es muy fluido. La parte negativa de este software radica en el precio. Este precio incrementa considerablemente el precio de diseño final. Kicad: Sin duda alguna Kicad es uno de los software de desarrollo electrónicos que ha sufrido un cambio más grande en los últimos años. Actualmente la mayoría de usuarios de Eagle se están moviendo progresivamente a este software de código libre multiplataforma y gratuito. Una de las ventajas más relevantes de los últimos años es que el Conseil Européen pour la Recherche Nucléaire (CERN) está utilizándolo para sus diseños colaborando activamente en el desarrollo del software. Otra característica de este software es la simplicidad de uso, aunque al principio tenga una curva de aprendizaje un poco elevada. En cuanto a las librerías se pueden encontrar un sin fin de librerías ya realizadas así como otras librerías que han sido convertidas de Eagle a Kicad. Sin duda alguna este software está poco a poco convirtiéndose en un estándar y un referente en el software libre, incluso llegando a tener funcionalidades que otros programas como Eagle no poseen, como podría ser la renderización 3D de los modelos. Nosotros hemos optado por el uso de Kicad, esto supondrá una disminución considerable en el precio así como la liberación de licencias. Implementación En esta iteración, la implementación se basó en el aprendizaje de la herramienta y en la documentación sobre la misma. La parte más «complicada» a la hora de empezar a utilizar la herramienta está en la inserción de nuevas librerías debido a la multitud de formatos por los que ha ido pasando el software. Kicad está pasando por un proceso de estandarización en el cual los desarrolladores de librerías deberán seguir unas líneas base para desarrollar sus componentes, de este modo todos los componentes tendrán un formato uniforme. Además, con el objetivo de dar soporte a esta estandarización se han creado varios formatos de archivo produciéndose así una situación de desconcierto cuando te inicias en Kicad. Bucle de iteración, Iteración 3: Creación del esquemático Requisitos o Restricciones Al igual que en las demás iteraciones tenemos algunas restricciones o requisitos que debemos cumplir. En este caso los requisitos no vienen impuestos por el cliente ni por el proyecto 98
sino por una serie de buenas prácticas que hay que cumplir tanto en el diseño electrónico como en general en los proyectos. Modularidad: La modularidad en el diseño permite aumentar la trazabilidad así como reducir los tiempos en mantenimiento y por lo tanto también reducir el coste del mantenimiento. Seguridad: Este requisito impuesto por la naturaleza del proyecto deberá ser satisfecho en cada una de las etapas de diseño. En este caso la seguridad se aplicará mediante la aplicación de los llamados ERC. Además la seguridad también se ve involucrada en el proceso de diseño del propio esquema, aplicando en todo momento las recomendaciones del fabricante para cada uno de los dispositivos integrados utilizados. Como se puede observar los requisitos son pocos, sin embargo no hay que olvidar todos los requisitos impuestos por el cliente los cuales se pueden comprobar en el Anexo C Dichos requisitos no se citan para evitar la duplicidad en el documento, no obstante en cada iteración se tiene en cuenta un grupo de estos requisitos, es más, cada iteración surge como una respuesta de implementación y análisis de un requisito, tal y como se explicó en la Sección 4.2. Funcionalidades o características añadidas En esta iteración se realizará la creación del esquemático en la herramienta Kicad. El esquemático es una representación visual de las conexiones eléctricas del circuito. La creación de esquemáticos requiere de práctica dado que intervienen conceptos electrónicos y de electricidad bastante complejos. Para la realización de este esquemático y de todo el diseño en general, se ha consultado diferente bibliografía como [Kic10]. Al final de esta iteración se habrá realizado un esquemático modular con toda la funcionalidad necesaria para el diseño. Esta iteración servirá como punto de entrada para la creación del circuito impreso. Decisiones de diseño Las decisiones de diseño en este caso no son muy determinantes dado que la realización del esquemático solo consiste en la unificación de cada una de las partes anteriormente realizadas, sin embargo ha sido necesario la toma de algunas decisiones. La decisión de realizar un esquemático jerárquico aprovechando las capacidades de Kicad permitirá simplificar la labor de depuración del diseño. Otra decisión de diseño ha sido la de la modificación de una plantilla existente en los repositorios oficiales de Kicad para la creación de una shield para el Arduino Mega. Esto simplifica enormemente la labor de creación del PCB dado que no habrá que calcular las distancias entre pines entre otras cosas. 99
Implementación Como ya se ha comentado, para la creación del esquemático se va a utilizar el software de diseño Kicad (ver Anexo A). Kicad opta por una aproximación jerárquica para la organización de los diferentes esquemas involucrados en el diseño. En la Figura 5.33 se puede ver la primera hoja del esquema. En esta hoja se pueden ver los principales componentes de la placa. Por un lado tenemos cuatro hojas «hijas». A continuación se dará una breve descripción de cada una de las hojas: Sheet Power: En esta hoja encontraremos el módulo de alimentación de la placa. Sheet Communications: Aquí encontraremos todos los dispositivos y conexiones que componen el módulo de comunicaciones. Motor Outputs: En esta hoja se encuentra la parte de potencia del proyecto, es decir, los controladores de los motores. HMI Interface: Tanto el LCD como el módulo infrarrojo se encuentra encapsulado en esta hoja.
Figura 5.33: Hoja principal del proyecto
Además, como se puede observar en la Figura 5.33, en la parte derecha hay una serie de conectores, estos conectores corresponden a los pines del Arduino Mega. Kicad tiene diferentes plantillas que permiten generar estos pines de forma automática por lo que se agiliza el trabajo de forma significativa. Además, en la parte inferior se puede ver un cuadro azul con una serie de conectores. Estos conectores corresponden a conectores molex como los de la Figura 5.34 que se utilizarán para las entradas analógicas del potenciometro de los 100
cilindros. Como se puede observar hay 8 entradas. Esta decisión está tomada tras la reunión con la «Harinera Castellana» donde se decidió que esta cantidad era suficiente.
Figura 5.34: Conector molex utilizado
Si nos adentramos en la hoja «Sheet Power» encontraremos la alimentación de los cilindros así como la alimentación de los controladores de los motores y el módulo de comunicaciones. Como se puede ver en la Figura 5.35, en la parte izquierda tenemos un conector. Este conector se instanciará en el circuito impreso como un conector de tipo bornero. Por otro lado, en el centro se encuentran los reguladores de tensión tal y como se vio en la iteración 1. Por último, con el objetivo de permitir conectar otros dispositivos que pudieran ser necesarios, se ha añadido un bornero para permitir desde el exterior acceder a los 24, 12 y 5 voltios.
Figura 5.35: Hoja de alimentación
Un punto a resaltar en esta hoja es el símbolo nombrado PWR_FLAG. Este símbolo es exclusivo de Kicad y permite al programa saber que una determinada etiqueta es portadora de corriente, en este caso, la etiqueta +24V. Es necesario añadir esta etiqueta porque el origen de los 24 voltios es un conector y en la creación de ese conector, los desarrolladores no indicaron que ese pin portaría corriente. Esto es lógico dado que no siempre tiene que portar corriente, también se podría utilizar como una salida. Antes de pasar a la siguiente hoja, es importante tener en cuenta la tierra que se ha utilizado para los conversores. Como se puede ver en la Figura 5.35 la tierra en este caso se llama GNDPOWER, eso es debido al aislamiento del que ya se ha hablado anteriormente. 101
Una vez analizados todos los detalles importantes sobre la implementación del módulo de alimentación, la siguiente hoja que se analizará será la de comunicaciones. En esta hoja (ver Figura A.7), se pueden ver tres optocopladores y un módulo llamado RS-485. El módulo RS-485 no se encontraba en ninguna librería y se ha tenido que crear desde cero. El proceso de creación de dicho módulo está definido en el Anexo A. La forma de importar el componente al esquema es exactamente igual que otro componente, es decir, con la tecla «a». Es importante incluir la librería antes de buscar el componente. El módulo de comunicaciones queda explicado con la creación del módulo RS-485. El porqué de las conexiones realizadas en los optocopladores puede ser revisada en la iteración donde se implementa el aislamiento. Las hojas restantes del esquemático no hace falta que sean explicadas en este documento dado que cada componente ha sido explicado en iteraciones anteriores. Las características más relevantes de la creación del esquema han sido explicadas. Como resultado de la iteración se genera un esquemático con todas las conexiones listas para ser transferidas al PCB. Bucle de iteración, Iteración 4: Creación del PCB Requisitos o Restricciones Seguridad: Como siempre, la seguridad es un requisito heredado del proyecto y tendrá que ser tenido en cuenta a la hora de realizar esta iteración. Mantenimiento: En la medida de lo posible se utilizarán componentes reemplazables. Compatible con Arduino: Dado que se desarrollará como una plataforma «shield» deberá ser compatible con el pinout del Arduino Mega. Funcionalidades o características añadidas En esta iteración se creará una PCB a partir del esquemático. Mediante esta PCB se presentará al cliente uno de los subproyectos finalizados. El PCB permitirá mostrar si es posible una alternativa real basada en una «shield» para Arduino en el entorno industrial. Decisiones de diseño En esta iteración no se nombrarán aquí las decisiones de diseño dado que estas se explicarán durante el proceso de implementación debido al carácter técnico de muchas de ellas. 102
Implementación Del esquemático al PCB Una vez finalizado el esquemático, el siguiente paso antes de pasar a la realización del PCB es la de la comprobación de las conexiones. Para realizar este trabajo existe una herramienta llamada ERC. Kicad proporciona su propio módulo ERC. El módulo ERC es capaz de detectar conexiones mal realizadas. Por ejemplo, en un nudo donde 2 o más cables se unen puede darse el caso de que el software no detecte bien esta unión y no cree el nudo si no que haga pasar el cable «por encima» de este punto de unión. Si esto ocurre, el detector ERC será capaz de detectarlo. El módulo ERC también es capaz de realizar la comprobación semántica de los pines, esto es, tal y como se comentó en la iteración anterior, los pines pueden ser de entrada o de salida, aunque también pueden ser receptores de power o emisores de power. Si no conectamos un pin de salida de power a uno de entrada de power entonces el ERC nos avisará de que probablemente ese pin está mal conectado. El ERC también es capaz de detectar pines sin conectar o valores sin ser asignados. Esta herramienta es extremadamente útil y debe ser utilizada siempre que se vaya a generar un PCB desde un esquemático, por muy seguro que se esté de que el esquemático esta bien, es importante pasar el ERC. Para pasar el ERC hay que pulsar sobre el icono con un insecto en la barra superior de herramientas. Una vez se pulse sobre este icono aparecerá una ventana como la que se puede ver en la Figura 5.36. Aquí se pulsará sobre el botón «Run» o sobre la pestaña opciones en caso de que se quieran modificar las opciones de comprobación. Una vez generado el ERC, sobre el esquemático y sobre el cuadro de texto «Error list» aparecerán todos los errores encontrados por la herramienta. En el caso de este proyecto, muchos fallos son debidos al hecho de que Kicad no sabe que el diseño es sobre una shield Arduino y por lo tanto no detecta que todos los pines tiene conexiones ya realizadas físicamente por lo que se generarán este tipo de errores. En la Figura 5.37 se puede ver la salida tras pasar el ERC. Una vez solucionados los problemas encontrados por la herramienta ERC (se pueden ver dichos errores como flechas verdes en el esquemático). Ya estaríamos listos para realizar el netlist del esquemático. El netlist de un esquemático es un fichero, normalmente de texto donde se indican todas las conexiones realizadas en el esquemático, es decir, es una traducción de lo visual a lo escrito. Este paso se realiza para que los diferentes programas de diseño sean interoperables entre ellos y por ejemplo se pueda realizar el esquema con Eagle y se haga el PCB con Kicad. Antes de realizar el netlist, es recomendable realizar la asociación de componentes del esquemático a «footprint» o componentes de PCB. Para esta tarea tenemos la herramienta «Cvpcb». Esta herramienta muestra tres paneles. El panel de la izquierda representan las diferentes librerías de componentes incluidas en el proyecto. El panel central representa la 103
Figura 5.36: Ventana de diálogo ERC
asociación de componentes del esquemático a componentes del PCB. Por último, el panel de la derecha muestra los componentes dentro de la librería seleccionada. El proceso consistirá en buscar en base a los componentes que se vayan a instalar en la PCB el componente que lo representa en Kicad. Para realizar esta acción de un modo más rápido, Kicad ofrece la posibilidad de aplicar diferentes filtros. Una vez asociado cada componente con su componente PCB, tendremos un resultado como el de la Figura A.9. Una vez finalizado el proceso de asociación entre los componentes del esquemático y los footprints, el siguiente paso será la generación del netlist. Para ello hay que pulsar sobre el botón «Generate netlist» y utilizar los parámetros por defecto para el programa «Pcbnew». Resumiendo, hasta ahora hemos partido del esquemático generado en la iteración anterior, se ha realizado la asociación de componentes a footprint y generado el netlist. El siguiente paso ya consiste en la creación del PCB. Como este proyecto se ha creado a partir de la plantilla para shields Arduino que trae por 104
Figura 5.37: Resultados del ERC
defecto Kicad, una vez abierto el programa «Pcbnew», directamente aparece el PCB con los conectores estándar de Arduino, sin embargo no aparece ninguno de los componentes creados en nuestro esquema. Para traer al PCB todos los componentes del esquema deberemos importar el netlist desde el botón «Read netlist». En este momento aparecerá un cuadro de diálogo con diferentes opciones que nos permitirán configurar qué acción se debe seguir en cada caso, por ejemplo un caso podría ser que se cambie el footprint de un componente, permitiendo mantener el footprint anterior, actualizando el footprint, o borrando el componente. Una vez leído el netlist, aparecerán todos los componentes juntos. Para separarlos se puede utilizar la herramienta de la barra superior de herramientas llamada «Mode footprint». En este modo, tras dar botón derecho en cualquier parte de nuestro PCB, aparecerá la opción «Global Spread and Place» y finalmente la opción «Spread Out All Footprints» ahora ya estaremos en disposición de colocar los componentes dentro de nuestra placa. En el Anexo A se puede ver el significado y cómo se utilizan cada una de las capas que intervienen en el diseño de PCB. El siguiente paso consiste en la colocación de los footprints. 105
Este paso es muy importante en el resultado final del diseño. Los componentes se deben colocar de modo que resulte más sencillo el enrutado posterior. Para facilitarnos esta tarea, Kicad proporciona, al igual que la mayoría de software de diseño electrónico, una herramienta llamada Ratsnest. Esta herramienta permite indicar cuáles son las conexiones que todavía hay que hacerse y cuál es el camino óptimo para realizarla. Cuando se realice el proceso de colocación de los componentes se deberá tener en cuenta los ratsnest para que en la medida de lo posible, no se crucen las líneas. En la Figura 5.38 se puede ver como se muestran los ratsnest en Kicad. También se debe tener en cuenta que aunque es recomendable que los componentes se coloquen de modo que se simplifique el proceso de enrutado, hay algunas reglas que hay que seguir de cara al emplazamiento de componentes. Por ejemplo, si se dota al diseño de condensadores de desacoplo, estos deberán estar lo más cerca posible del pin al que vayan destinado, aunque esto complique el enrutado. Otro ejemplo donde se deberá tener en cuenta determinadas restricciones será entre componentes o vías de alta frecuencia las cuales deberán ser separadas para evitar corrientes inducidas. Todas estas cuestiones son restricciones de diseño electrónico y no del proyecto. Una vez conectados todos los componentes (ver Figura 5.38) se deberá proceder al enrutado. El enrutado consiste en unir las diferentes líneas señaladas por el ratsnest con cobre. Para realizar estas uniones se utiliza la herramienta «add tracks and vias» o el atajo «x». Existen numerosas recomendaciones a la hora de realizar las conexiones como que no se formen ángulos de 90o o que las líneas de alta frecuencia estén lo más separadas posibles, sin embargo, ese no es el objeto de este documento.
Figura 5.38: Proceso de emplazamiento de componentes finalizado
Por último, una vez finalizado el enrutado. Tal y como se puede observar en la Figura 5.39 106
el último paso consiste en realizar los planos de tierra y alimentación. Los planos de tierra permiten reducir la influencia del ruido inducido dado que este ruido se irá por aquellos caminos que presentan menor impedancia y al ser el plano un cable muy grande, este presentará menos resistencia que un cable fino. Por otro lado, si se está realizando una placa de dos caras, entonces se recomienda aplicar por un lado un plan de tierra y por el otro lado un plano de alimentación. De este modo será menos probable que los fenómenos radioeléctricos afecten a nuestra placa.
Figura 5.39: Proceso de enrutado completo
Para realizar el plano de tierra hay que crear un polígono con la herramienta «Add filled zones». Una vez seleccionada la herramienta se realizará un cuadro que cubra toda la zona de la PCB. Cuando se haya finalizado se realiza la misma acción pero con la otra capa, en este caso pondremos que se rellene con 5 voltios. Una vez finalizado habrá que pulsar botón derecho y «Fill or Refill all zones». Finalmente obtendremos algo como lo mostrado en la Figura 5.40. Con esto se finaliza el proceso de diseño, el siguiente paso consistirá en comprobar si no se ha cometido ningún tipo de error a la hora de enrutar o posicionar los componentes. De igual modo que existe una herramienta para comprobar los fallos cometidos en el esquemático, existe otra herramienta para comprobar los errores cometidos en el enrutado. Esta herramienta es el DRC. El DRC es una herramienta un poco más compleja que ERC dado que permite comprobar errores más complejos como por ejemplo la proximidad entre pistas de alta frecuencia, etc. Para que el DRC cumpla bien su cometido, debemos ayudarle indicándole una serie de parámetros que vienen definidos por el fabricante y hacen referencia a sus capacidades de 107
Figura 5.40: Proceso de creación de zonas de tierra
fabricación. En el Anexo A se puede ver una breve explicación del proceso de configuración de esta herramienta. Una vez que todos los errores marcados por el DRC están solucionados, estamos en disposición de generar el modelo 3D (ver Figura 5.41) de la placa, buscar proveedor y enviar los ficheros de diseño para la fabricación del PCB.
Figura 5.41: Placa final en 3D
108
Resumen Como resumen, este subproyecto empezó con el diseño de cada uno de los componentes que formarían parte del prototipo final. Esos módulos fueron incorporados dentro de una placa de prototipado y comprobados individualmente. Una vez que se aseguro que la funcionalidad del proyecto era la adecuada se continuó hacia la creación de un esquemático donde quedará reflejado cada uno de los módulos, así como sus conexiones internas. Una vez generado el esquemático y comprobado mediante las herramientas de ERC, se genera la representación textual de las conexiones así como se realiza la conversión de componentes de esquemático a componentes de PCB o footprints. Con el «netlist» se alimenta la entrada del programa de diseño de PCB, en nuestro caso «Pcbnew». Se importa y carga el «netlist» y se colocan los componentes de tal manera que se simplifique el posterior enrutado. Una vez colocados los componentes, se procede al enrutado de los mismos y a la generación de los planos de masa. Con todo enrutado se generan los ficheros de fabricación que serán mandados a la fábrica o a la máquina para ser fabricado.
109
5.2.3
Proyecto Firmware
Es importante remarcar el hecho de que el orden seguido durante el proyecto no ha sido el aquí mostrado. Algunas iteraciones del proyecto firmware no podían realizarse hasta que otras del proyecto PCB estuvieran finalizadas. Esta dependencia se debe a que el firmware necesita de una plataforma donde ser testado y sobre la que realizar el diseño. Por ejemplo, si no se tiene decidida la pantalla que se va a utilizar para el HMI, esa parte software deberá esperar debido a que en función de la pantalla elegida se podrán utilizar unas librerías u otras. A continuación, se dará una breve descripción de cada una de las iteraciones desarrolladas en este subproyecto. El subproyecto firmware consiste en la creación del software que será instalado en cada uno de los controladores y que permitirá que las capas superiores tengan acceso al hardware para implementar las funcionalidades requeridas. Etapa de inicio, Funcionalidad básica Requisitos o Restricciones TTM:
Es importante que esta primera versión del código sea funcional en un tiempo muy corto de forma que el cliente pueda comprobar cuál será la funcionalidad de la plataforma en un estadio temprano del ciclo de desarrollo. Simple: El primer código deberá ser simple de tal modo que sirva de base para las diversas variaciones que irá sufriendo durante el desarrollo el prototipo. Libre de fallos: Aunque no es la versión final y deberá estar sometido a muchas pruebas, el software deberá estar libre de fallos graves de modo que el cliente no perciba que está ante un prototipo débil. Funcionalidades o características añadidas En esta primera fase se implementarán todas las características que dan valor al cliente y que permiten que el prototipo sea usable con ciertas restricciones. Entre las funcionalidades añadidas se encuentran: Comunicaciones: Mediante un protocolo sencillo se diseña la funcionalidad de la capa de comunicaciones de modo que desde el ordenador de gestión se pueden enviar acciones a realizar al controlador. Control: El control de los cilindros así como su sensorización han sido implementadas en este primer prototipo por lo que el cliente puede tomar medidas de velocidad del cilindro y asegurar que cumple con sus requisitos en base a su criterio experto en el área. HMI: El módulo HMI ha sido implementado de manera modular de manera que el cliente pueda ver cómo será el aspecto del prototipo final. 110
Decisiones de diseño El requisito más importante en este caso radica en el TTM, es decir, se requiere que el prototipo esté lanzado para revisión en el menor tiempo posible. Además, el prototipo se utilizará para testar las funcionalidades básicas correspondientes a los módulos principales. Todas estas restricciones llevan consigo una serie de decisiones de diseño que deberán adaptarse a las condiciones actuales. Para poder obtener un diseño sencillo, rápido y sin fallos se ha optado por la creación de un sketch en Arduino que encapsule toda la funcionalidad inicial. Si bien se perderá en modularidad y eficiencia, compensaremos reduciendo considerablemente los tiempos de diseño. A continuación veremos la implementación de cada una de las funcionalidades dentro del sketch. Implementación Implementación del módulo de comunicaciones Para este primer prototipo se ha diseñado un sencillo protocolo de comunicación que permite realizar las operaciones básicas sobre los cilindros. El prototipo del protocolo consta de una trama con los siguientes campos: Esclavo: El esclavo está representado con un número de dos dígitos, es decir, desde 0 a 99, que permite direccionar cada uno de los esclavos dentro del bus de comunicaciones. Rasera: Este número de dos dígitos permite direccionar cada una de las raseras dentro de un esclavo. Posición: Posición expresada en un porcentaje de 0 a 100 % . Este campo será completado por la estación gestora en el caso de una petición de movimiento, o en el caso de una petición de solicitud de estado será el controlador quien complete este parámetro. Estado: Un número de un dígito que representará el estado del controlador en el caso de una petición de estado por parte de la estación gestora. Comando: Un único dígito que será utilizado para indicar el tipo de petición que se desea realizar. Este comando puede tomar los siguientes valores: • 1: Con el dígito 1 se indica que se desea solicitar el estado del controlador. En este caso será el controlador el encargado de completar los campos de posición y estado con los valores correspondientes. • 2: Envío de posición, mediante este valor se indica al controlador correspondiente que realice un cambio de posición al valor estipulado en el campo llamado posición. Es importante que se tenga en cuenta que este comando no modificará de forma inmediata la posición. Para que se modifique la posición es necesario que tras este comando se mande otro exactamente igual pero con el campo de parámetro con el valor 3 que confirmará que es una orden intencionada. 111
• 3: Tal y como se adelantó, mediante el valor 3 indicamos que se desea confirmar el cambio de posición. La principal carencia de este protocolo es la falta de métodos de seguridad. El único método de seguridad es la confirmación de envío de posición pero esto no es suficiente dado que este protocolo no tiene ni integridad ni autenticidad, no obstante para la primera versión es suficiente pues permite realizar las acciones básicas. Para utilizar el módulo 485 se debe tener en cuenta que el transceptor tiene dos modos de funcionamiento: Modo receptor: En este modo el transceptor se configura con entradas de alta impedancia y permite leer el valor de las líneas del bus. Para habilitar este modo hay que poner un valor de 0 voltios en el pin que tiene el puente entre RE DE. Modo emisor: En el modo emisor será el transceptor el encargado de controlar la línea. Para habilitar el modo emisor se debe habilitar el pin con el puente RE DE a un valor de 5 voltios. La arquitectura de red es muy sencilla y se basa en un bus simple tal y como se recomienda en el estándar ANSI/TIA/EIA-485. En la Figura 5.42 se puede ver cómo se forma un bus sencillo 485.
Figura 5.42: Bus 485
El bus, como se puede observar en la Figura 5.42 mantiene una configuración muy sencilla. Cada uno de los esclavos se conecta al bus. El estándar ANSI/TIA/EIA-485 define una unidad llamada unidad de carga de capacitancia. El bus puede tener un máximo de 32 unidades de carga. La mayoría de transceptores se miden como una unidad de carga, sin embargo, existen transceptores más caros que permiten reducir la carga que añaden al bus. Por ejemplo, existen trasceptores de 1/128 unidades de carga. Con este tipo de dispositivos se aumenta considerablemente el número de dispositivos que puede estar conectados al bus, no obstante lo más recomendable es añadir un repetidor a la línea. Los repetidores, además de reiniciar el número de unidades de carga, regenera la señal. Con reiniciar el número de unidades de carga nos referimos a que se vuelve a partir 112
de cero en ese segmento. Regenerar la señal no significa amplificar al señal. Es un error muy típico igualar el amplificador al regenerador cuando son dispositivos completamente diferentes. El amplificador únicamente aumenta el voltaje de la señal o la amplitud de la misma. Por otro lado, el repetidor regenera la señal, es decir, interpreta lógicamente el valor que está portando y vuelve a generar dicho valor regenerando así todas sus propiedades físicas. En la Figura 5.43 se puede ver un repetidor 485. Estos repetidores son muy comunes en el mercado debido al extenso uso en redes Profibus. En la Figura 5.44 se puede ver como afecta el filtrado realizado por un repetidor a la señal. En la Figura 5.44a se ve como la señal está distorsionada y con ruido y en la Figura 5.44b la señal filtrada y regenerada. Como se puede observar gran parte del ruido desaparece permitiendo así que la señal viaje durante más tiempo manteniendo sus propiedades y reduciendo el número de errores.
Figura 5.43: Repetidor 485
(a) Señal antes de ser filtrada y regene- (b) Señal después de ser filtrada y regerada nerada por el repetidor
Figura 5.44: Comparación de señales filtrada/no filtrada en un bus 485
Otro punto importante que debe ser estudiado a la hora de plantear el módulo de comunicaciones es comprobar las resistencias finalizadoras. Las resistencias finalizadoras son unas 113
resistencias que se conectan al inicio y fin del bus de comunicaciones y permiten reducir el «rebote» de la señal. Los módulos utilizados, tal y como se puede ver en la Figura 5.45 llevan incorporadas resistencias de terminación. Además de esta resistencia de terminación el bus contiene resistencias de «pull-up» y «pull-down» que permiten llevar a un nivel lógico estable a la línea cuando no hay ningún driver en el bus.
Figura 5.45: Esquema módulo 485
El protocolo de comunicaciones aunque sencillo cumple con su cometido. En el método de comunicaciones del código adjunto a este documento se puede ver la primera implementación de este módulo. Implementación de módulo de control El módulo de control es un módulo bastante sencillo debido a la simplicidad de la interfaz del módulo controlador de motores. Únicamente hay que ir habilitando los pines correspondientes al sentido de marcha. Es muy importante que se tenga en cuenta que existe un puente físico entre los pines 1-3 y los pines 2-4. Otro punto importante para evitar sobrecarga cuando se realice un cambio de sentido es realizar una parada antes de dicho cambio. Este punto no se tuvo en cuenta en la realización del primer prototipo y entre otras cosas provocó que uno de los controladores se quemara. Hay que pasar por el estado parado antes de continuar hacia el siguiente cambio de sentido. En este primer prototipo se ha implementado un mecanismo de seguridad que permite 114
comprobar que si existe un error no es posible avanzar. Este tipo de degradado permite asegurar que no se ocurra ninguna acción lesiva contra el individuo. Aunque para implementar una correcta parada de emergencia y degradados hay que estudiar cada caso concreto. Otro punto importante a tener en cuenta consiste en el cálculo de la posición en la cual se encuentra el cilindro. Para medir esta posición ya se comentó que el cilindro incorpora un sensor resistivo. Tal y como se puede observar en el Listado 5.6 en primer lugar se lee el valor analógico de la entrada. Una vez medido se calcula la posición real. Esta formula se puede obtener de la hoja de datos del cilindro. Se le resta 465 porque es el valor por defecto del cilindro. Una vez calculado se multiplica por el coeficiente 0.18 que es el numero de ohms dividido por cm. Esta posición real nos permite saber la distancia real del vástago del cilindro. 1 2 3 4
analog_r1 = analogRead(A1); pos_real_1 = (analog_r1-465)*0.18; aux_cp_1 = ofst100_rasera_1 - ofst0_rasera_1; aux1_cp_1 = 100.0 / aux_cp_1;
5 6 7 8 9 10
pos_pc_1 = (pos_real_1-ofst0_rasera_1)*aux1_cp_1; if (pos_pc_1 < 0) pos_pc_1 = 0;
11 12 13 14 15
}
if (pos_pc_1 > 100) pos_pc_1 =100; if (pos_pc_1 < 3){ rasera_1_cerrada =1; rasera_1_abierta =0; if (pos_real_1 > 10){ rasera_1_abierta =1; rasera_1_cerrada =0; }
Listado 5.6: Sensorización de posición Otro punto importante es el uso del offset. Mediante el offset se pueden definir las posiciones de inicio y de fin del vástago. Esto permitirá a la hora de realizar la instalación ajustar la posición del cilindro. En la Figura 5.46 se puede ver una representación de lo explicado.
Figura 5.46: Representación del offset
Como se puede observar el código hace uso de muchas variables globales, esto se debe a la falta de modularización y a las carencias del IDE para facilitar la labor de manejo de 115
archivos de modo que se pueda dividir el diseño en múltiples ficheros. El módulo de control también tiene en cuenta el modo en el cual está funcionando el controlador. El controlador básicamente tiene dos modos de uso: El modo manual en el cual el operario puede a través del mando dirigir el vástago a la posición que él desee de forma incremental o el modo automático en el cual se fija una posición deseada y el controlador automáticamente se mueve hasta dicha posición. En el Listado 5.7 se puede ver un extracto de código donde se realiza el movimiento del vástago en una dirección.
1
if (modo_marcha == 1 && pos_pedida_1 >0 && pos_pedida_1 < 100 && error_1==0 && rasera_1 !=0){ if (pos_pc_1 > (pos_pedida_1-2) || pos_pc_1 < (pos_pedida_1+2)){
3 4 5 6 7
digitalWrite(29, LOW); digitalWrite(25, LOW); } if (pos_pc_1 < (pos_pedida_1-2) && pos_real_1 < 99){ digitalWrite(25, LOW);
8 9 10 11 12 13 14 15
digitalWrite(29, HIGH); } if (pos_pc_1 > (pos_pedida_1+2) && pos_real_1 > 1){ digitalWrite(29, LOW); digitalWrite(25, HIGH); } }
Listado 5.7: Movimiento en un sentido
Como se puede observar en el Listado 5.7 el código está muy acoplado y poco parametrizado. Por ejemplo se puede ver los famosos números mágicos entre otras cosas, sin embargo, para una prueba funcional es suficiente. De este modo queda explicado el módulo de control, no obstante si se quiere ahondar más en los detalles se puede ver el método movimientos() del código adjuntado. Implementación de módulo HMI El módulo HMI es una parte muy valorada dentro de los sistemas basados en PLC y es por ello que se ha dotado a cada controlador de un pequeño módulo HMI. Mediante este módulo el operario podrá comprobar de un solo vistazo cual es el estado de cada uno de los controladores además de poder realizar diversas acciones sobre el mismo. El módulo HMI se compone de dos dispositivos principales. Por un lado tenemos la pantalla donde se representará la información al usuario. En este caso la pantalla escogida es una pantalla utilizada por los móviles Nokia 5110. En la Figura 5.13 se puede ver el aspecto de esta pantalla. El dispositivo cuenta con un controlador PCD8544[Ins99] el cual dispone de una librería para Arduino la cual puede ser descargada desde el siguiente enlace:https://github.com/carlosefr/pcd8544. Esta librería proporciona los métodos típicos para 116
escribir en el puerto serie, sin embargo, en este caso la escritura se realiza sobre la pantalla. Esta reutilización de los métodos se debe a la herencia que realiza la librería. La clase «PCD8544» deriva de la clase «Print» exactamente igual que la librería Serial. La elección de esta pantalla se justifica por el bajo coste de la misma así como la disponibilidad en cuanto a unidades se refiere. Esta pantalla tiene un coste aproximado de 5$ y se puede conseguir en multitud de lugares en Internet. Además, la pantalla incorpora retroiluminación por lo que se podrá utilizar en entornos con baja luminosidad. Otro dispositivo que interviene en el módulo HMI es el receptor y emisor infrarrojos. Mediante estos componentes el operario puede manipular el controlador, de modo que pueda hacer avanzar el cilindro, retroceder, moverse por los menús, cambiar valores en la EEPROM, etc. La elección de un sistema infrarrojo surgió de la necesidad de mantener un sistema ATmosphères EXplosives (ATEX). La harina en polvo es deflagrante por lo que los equipos deberán seguir la directiva ATEX 95. En la Figura 5.47 se puede ver el sistema infrarrojo escogido. A continuación detallaremos la implementación básica de estos módulos de cara a que el lector pueda tener un idea de como se puede realizar una implementación sencilla de un sistema HMI. Comenzaremos por describir la implementación del módulo infrarojos debido a que será este el que nos permita movernos por los menús y por lo tanto aparecerá en la explicación de la implementación de la pantalla. La implementación del módulo infrarrojos se basa en la librería IRremote. Esta librería se puede descargar desde el siguiente enlace: https://github.com/z3t0/Arduino-IRremote. Esta librería es la encargada, de que a partir de un tren de pulsos como el mostrado en la Figura 5.48, decodificar la trama y devolver el valor útil. Los conceptos básicos a la hora de entender cómo funciona los infrarrojos son los siguientes: Un emisor envía un código, ese código se convierte en binario y se modula sobre una señal portadora de tal manera que como resultado a la salida tenemos una onda que será aplicada sobre un transistor y llevada a un led infrarrojo. Por otro lado, en el receptor un demodulador obtiene el código binario conociendo la frecuencia y características de la onda portadora. Aunque muy resumido este es el proceso básico involucrado en la comunicación infrarroja. En el Listado 5.8 se puede ver el ejemplo que viene con la librería IRremote. Este código refleja las partes claves de la utilización de la librería.
117
(a) Módulo receptor infrarrojos
(b) Mando a distancia infrarrojos
Figura 5.47: Sistema infrarrojo utilizado
Figura 5.48: Tren de pulsos código NEC
En primer lugar hay que incorporar la librería mediante la directiva include. Más tarde, se crea un objeto IRrecv y una estructura decode_results. Mediante la función enableIRIn() se habilita la recepción infrarroja. Por otro lado, en loop() se decodifica si realmente se ha encontrado algo. Si no se ha encontrado nada (falta de luz infrarroja) devolverá un null y por lo tanto no entrará en el «if». Es muy importante llamar al método resume() para que el receptor vuelva a estar a la escucha. El siguiente paso consiste en identificar mediante los println() qué valor corresponde a cada tecla, para ello simplemente se va pulsando sobre cada tecla y se va comprobando el valor devuelto. De esta manera ya podremos crear bloques condicionales en función del tipo de valor que se reciba. En el Listado 5.9 se puede ver como se asigna a una variable global el número del mando que corresponde a cada valor de modo que durante el programa sea más sencillo tratar con dichos botones. Una vez que se tienen decodificados los valores y capturada la tecla pulsada únicamente queda utilizarlo en el programa como una variable normal. El siguiente módulo HMI al que nos referiremos será la pantalla. La pantalla, tal y como se comentó anteriormente está controlada por un driver PCD8544. Con el objetivo de simplificar el diseño se utilizará la librería libre PCD8544. Esta librería al heredar de la clase «Print» simplifica mucho su uso.
118
1
#include
3
const int RECV_PIN = 6;
5
IRrecv irrecv(RECV_PIN);
7
decode_results results;
9
void setup()
10 11 12 13 14
{
16 17 18 19 20 21
void loop() {
Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver irrecv.blink13(true); }
if (irrecv.decode(&results)) { if (results.decode_type == NEC) { Serial.print("NEC: "); } else if (results.decode_type == SONY) { Serial.print("SONY: "); } else if (results.decode_type == RC5) {
22 23 24 25 26 27 28 29 30 31 32
Serial.print("RC5: "); } else if (results.decode_type == RC6) { Serial.print("RC6: "); } else if (results.decode_type == UNKNOWN) { Serial.print("UNKNOWN: "); } Serial.println(results.value, HEX); irrecv.resume(); // Receive the next value } }
Listado 5.8: Ejemplo librería IRremote
La librería tiene una serie de métodos propios así como los heredados. A continuación se puede ver una descripción de los métodos más interesantes: begin: Este método acepta diferentes parámetros opcionales, el primer parámetro corresponde al ancho que por defecto está a 84 píxeles que es justo el tamaño del LCD utilizado. Como segundo parámetro está la altura de 48 píxeles que al igual que el ancho coincide con el LCD. Por último se puede elegir el tipo de chip, no obstante para nuestro caso esto no es importante. Mediante este método se inicializan todas las variables necesarias, reiniciando el LCD y seleccionando entre otras cosas el tipo de escala y el tipo de instrucciones utilizadas. Por último pone el cursor al inicio de la pantalla. stop: Finaliza la pantalla y libera memoria. clear: Limpia todo el contenido de la pantalla. clearLine(): Limpia todo el contenido de la línea actual. setInverse(): Permite configurar la opción blanco sobre negro. 119
1 2 3
if (irrecv.decode(&results)) {// Conta_ir=0;
//Serial.println(results.value,DEC); digitalWrite(51, HIGH); //Encendido de backlight if (results.value == 16738455) Tecla_ir = 0; //TECLA RECIBIDA 0 if (results.value == 16724175) Tecla_ir = 1; //TECLA RECIBIDA 1 if (results.value == 16718055) Tecla_ir = 2; //TECLA RECIBIDA 2
4 5 6 7 8 9
if (results.value == 16743045) Tecla_ir = 3; //TECLA RECIBIDA 3 if (results.value == 16716015) Tecla_ir = 4; //TECLA RECIBIDA 4 if (results.value == 16726215) Tecla_ir = 5; //TECLA RECIBIDA 5 if (results.value == 16734885) Tecla_ir = 6; //TECLA RECIBIDA 6
10 11 12 13 14 15
if (results.value == 16728765) Tecla_ir = 7; //TECLA RECIBIDA 7 if (results.value == 16730805) Tecla_ir = 8; //TECLA RECIBIDA 8 if (results.value == 16732845) Tecla_ir = 9; //TECLA RECIBIDA 9 if (results.value == 16736925) Tecla_ir = 10; //TECLA RECIBIDA MODE if (results.value == 16769055) Tecla_ir = 11; //TECLA RECIBIDA EQ
16 17 18 19 20 21 22 23 24 25 26
SI TENEMOS LECTURA EN LA INTERRUPCION DEL IR.
if (results.value == 16750695) Tecla_ir = 12; if (results.value == 16761405) Tecla_ir = 13; if (results.value == 16712455) Tecla_ir = 14;
//TECLA RECIBIDA BACK //TECLA RECIBIDA AVANCE
//TECLA RECIBIDA RETROCESO if (results.value == 4294967295) Mantengo_ir = 1; //PULSACION MANTENIDA irrecv.resume(); // UNA VEZ ANALIZADA LA PULSACION RECIBO EL SIGUIENTE VALOR. } else{ ++Conta_ir;// CONTADOR PARA TEMPORIZAR EL PULSADO CONTINUO digitalWrite(51, LOW); }
Listado 5.9: Decodificación de los valores leídos
setContrast(): Permite modificar el contraste hasta un nivel de 90. El nivel máximo 90 viene especificado en el datasheet. home(): Regresa al inicio de la línea actual. setCursor(): Esta función se utiliza mucho durante el código. Mediante esta función se indica el lugar justo donde se quiere mover el cursor. En este caso, el movimiento viene especificado por píxeles. El primer parámetro corresponde al ancho y el segundo al largo. write(): La función write es sin duda una de las funciones más importantes de esta librería. Aunque esta función no se utiliza de manera directa por el usuario final, es la encargada de aplicar el polimorfismo a la herencia de la clase «Print». Mediante esta función los métodos heredados de la clase «Print» pueden realizar su función. El método write únicamente calcula la posición requerida y envía los datos al LCD. Una vez que se tiene claro los diferentes métodos que proporciona la librería, ya se puede explicar brevemente el código para mostrar alguno de los menús creados. En este caso, para simplificar y no alargar el documento, se mostrará la codificación de la pantalla principal. En el Listado 5.10 se puede ver el código para dibujar la pantalla principal. Para facilitar la comprensión del código, se puede ver Figura 5.49.
120
1 2 3
if (pantalla_a == PANTALLA_PRINCIPAL){ lcd.setCursor(0, 0);// 6 LINEAS VERTICALES POR CADA CARACTER 14 CARACTERES POR LINEA lcd.print("GRUP0");
4 5 6 7 8 9
lcd.setCursor(36, 0);
10 11 12 13 14 15
if (modo_marcha == 2){
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
lcd.print(esclavo); if (modo_marcha == 1){ lcd.setCursor(60, 0); lcd.print("AUTO"); } lcd.setCursor(60, 0); lcd.print("MANU"); } lcd.setCursor(0, 1); lcd.print("No Pedido Real"); lcd.setCursor(0, 2); lcd.clearLine(); lcd.print(rasera_1); if (rasera_manu == 1){ lcd.setCursor(15, 2); lcd.clearLine(); lcd.print("X"); } if (error_1 >0){ lcd.setCursor(15, 2); lcd.clearLine(); lcd.print("E"); } lcd.setCursor(31, 2); lcd.print("
");
lcd.setCursor(31, 2); lcd.print(pos_pedida_1); lcd.setCursor(61, 2); lcd.print(pos_pc_1);
Listado 5.10: Ejemplo de codificación de la pantalla principal
En primer lugar se dibuja una línea con los encabezados de la tabla que se dibujará en pantalla. En este caso los encabezados serán: No (número de rasera ), Pedido (posición pedida), Real (posición leída por el sensor del cilindro). Además, antes de los encabezados se incorpora una línea con el modo de funcionamiento del controlador que puede ser: AUTO o MANU. Como se puede observar la parte más compleja de la pantalla reside en el calcular el siguiente lugar en el que posicionar el cursor pero, con un poco de orden es bastante sencillo de arreglar. Por último, de una manera poco modular pero eficiente se va comprobando el estado de cada una de las variables para representar cada valor en la pantalla. En esencia la mayor parte del código de representación es igual al mostrado en el Listado 5.10 pero con los diferentes menús. Otra parte importante a la hora de gestionar el HMI es la entrada del usuario. Como vimos en la captación de los valores infrarrojos, una vez se decodifica tenemos la tecla definida. Para realizar los movimientos entre menús lo único que hay que hacer es «preguntar» por dicha tecla al inicio del código de representación y 121
Figura 5.49: Pantalla principal del HMI
configurar la siguiente pantalla a configurar. Es importante tener en cuenta que el tiempo mínimo entre los cambios de menús será el tiempo de ciclo dado que la comprobación solo se hace a la hora de entrar en el código de representación. En el Listado 5.11 se puede ver dicho movimiento entre los diferentes menús. 1
if (pantalla_a == PANTALLA_MODOS && Tecla_ir == 1){ // Salto a pantalla CONFIGURACION si pulsan 1 en pantalla MODOS pantalla_a=PANTALLA_CONFIGURACION;
2 3 4 5
lcd.clear(); Tecla_ir = 99; }
Listado 5.11: Movimiento entre pantallas
Extendiendo lo explicado en este punto a las diferentes pantallas se consigue crear un sistema de menús como el mostrado en la Figura 5.50. Como se puede observar es muy sencillo realizar un sistema HMI funcional utilizando componentes de bajo coste. Actualmente, en los sistemas basados en PLCs no se dispone de sistemas HMI por cada controlador, por el contrario se inserta al bus otro PLC en forma de pantalla táctil que captura el tráfico de la línea e infiere el estado de cada uno de los controladores. Como resultado de esta fase de implementación se permite mostrar al cliente las bondades de este tipo de sistemas debido a lo visual del módulo añadido y el bajo coste de implementación del mismo.
122
(a) Menú de selección
(b) Pantalla principal
(c) Pantalla de estado de las raseras
Figura 5.50: Sistema HMI Bucle de iteración, Iteración 1: Del prototipo al código final Requisitos o Restricciones Modular: En este caso el requisito de que sea un diseño modular es indispensable para la trazabilidad del diseño y la depuración del mismo. Orientación a objetos: Una de las características de este subproyecto es la aplicación de la orientación a objetos al desarrollo de sistemas embebidos. Gestión de la configuración: Es muy importante que se documente la configuración 123
del entorno de desarrollo dado que en el periodo de mantenimiento es probable que se tengan que modificar diferentes partes del código para solucionar errores, además, se deberá mantener una lista de cambios de tal manera que el personal de mantenimiento pueda ver los diferentes cambios que se han realizado en el código. Para esta labor se puede utilizar cualquier gestor de versiones como: git, svn, mercurial. . . Documentación: La documentación deberá ser lo más detallada posible, además se deberá realizar de un modo estandarizado. Seguridad: El diseño final deberá ser robusto tanto a nivel hardware como a nivel software, es por ello que en esta fase se verá como tomar determinadas ventajas de la orientación a objetos para dotar al sistema de un plus de seguridad extra. Mejoras realizadas, evolución del diseño Esta iteración es probablemente la más grande en cuanto a líneas de código. En esta iteración se creará el «core» del firmware por lo que este punto será un poco más extenso de lo normal. Las mejoras realizadas consisten en: dotar de mecanismos de seguridad, escalabilidad y modularidad mediante la reescritura del código del prototipo básico, por otro lado, crear una documentación extensa y por último configurar un entorno de desarrollo profesional basado en Eclipse con el fin de eliminar la necesidad de trabajar con el IDE de Arduino el cual tiene muchas carencias para su uso profesional.. Decisiones de diseño Una de las decisiones de diseño que sin duda alguna han supuesto un punto y aparte en el diseño del proyecto ha sido la adopción de la orientación a objetos. La orientación a objetos en los sistemas embebidos no ha sido muy utilizada, sin embargo, dota al sistema de mucha robustez y de una mayor seguridad debido a las características inherentes de este paradigma. La orientación a objetos propone 3 características claves en su definición[mey97]: Encapsulación: La encapsulación es la propiedad que permite que el resto de objetos no conozca la estructura interna del objeto al que llaman. El objeto se puede ver como una caja negra donde el contenido de la caja está oculto (implementación) pero la interfaz de uso es pública (métodos). Existen varias definiciones de encapsulación, una orientada al lenguaje de programación y otra orientada a las bases de datos, no obstante no es objetivo de este documento el profundizar en teoría de orientación a objetos. Herencia: Es una propiedad de la orientación a objetos que permite la reutilización del código a través de la especialización y la generalización consecuentemente. Una clase que hereda de otra especializa su comportamiento heredando el comportamiento de la clase. 124
Polimorfismo: Propiedad que permite que una operación pueda ser aplicada a distintos tipos de objetos. Antes de explicar como se ha aplicado cada una de las propiedades al proyecto se detallará la organización y decisiones de diseño así como las propuestas planteadas a nivel de diseño en este proyecto. Uno de los objetivos de este proyecto es aplicar los conocimientos adquiridos en la carrera para la resolución de problemas inherentes a un sistema embebido. La orientación a objetos ha sido uno de los puntos más interesantes en la resolución de estos problemas. En el proyecto se propone la equiparación de un objeto real con un objeto virtual, de este modo, si en la realidad tenemos un cilindro, en el programa tendremos una clase «Cilindro». Si en la realidad tenemos un modulo de comunicaciones de campo, en el código tendremos una clase de comunicaciones de campo. Esto permite encapsular cada funcionalidad dentro de bloques de código bien acotados. Por otro lado, para proyectos donde trabajan más de una persona, se simplifica la división del trabajo dado que el diseñador del módulo de comunicaciones en hardware desarrollará la clase software para controlar dicho hardware (suponiendo equipo multidisciplinar). Una vez que se tiene el paradigma de un objeto físico un objeto virtual, se pueden aplicar las propiedades de la orientación a objetos para cumplir con los requisitos. Uno de los requisitos de esta fase es la de dotar al sistema de seguridad. En este sentido, uno de los fallos que se detectó en el código del prototipo inicial fue que existía un problema a la hora de mandar al cilindro ir hacia delante y hacia atrás de forma rápida. Esto, provocaba que el módulo controlador de motores se quemara. Tras analizar el código se observó que el problema radicaba en que una de las variables globales no volvía a su estado original y hacía que el sistema no se comportara como debía. Este fallo no ocurriría si el comportamiento hubiera sido encapsulado. La encapsulación aplicada a este ejemplo consistiría en que la clase «Cilindro», tuviera un método llamado avanzar() y otro método retroceder() dentro de los cuales se realizaran todas las comprobaciones necesarias como por ejemplo el pasar por el estado de parada para evitar sobreconsumos. Una vez aplicada la orientación a objetos y encapsulado el comportamiento, este fallo desapareció al igual que muchos otros. La orientación a objetos, sin lugar a dudas ha permitido que el proyecto sea mucho más seguro de lo que sería aplicando los métodos tradicionales dentro de los sistemas embebidos. Un problema que surge de la necesidad de realizar un sistema modular y aunque no de forma directa, sí de forma indirecta ante la necesidad de aplicar las técnicas de orientación a objetos es la falta de un buen IDE. El entorno de desarrollo del Arduino no cuenta con sistema de gestión de ficheros por lo que la compilación condicional o la organización del código se complican mucho. En este TFG con el objetivo de mostrar el hecho de que la plataforma 125
Arduino puede ser tratada si se desea como un microcontrolador AVR, se ha configurado el entorno Eclipse para permitir el desarrollo cómodo del programa para Arduino. En el Anexo B se puede consultar el proceso de configuración. Otra de las decisiones de diseño que se han tenido en cuenta a la hora de desarrollar el firmware ha sido la metodología del ciclo de «scan». En los sistemas tradicionales basados en PLC el ciclo de scan es un elemento bien conocido por todos los Ingenieros en automática. Como el programa deberá ser mantenido por estos ingenieros se ha decidido dotar al sistema de características del mundo de los PLC que además de simplificar el proceso de mantenimiento agregan utilidad al diseño. El ciclo de scan en los PLC mide el tiempo entre repeticiones de un mismo proceso, es decir, si el PLC realiza los procesos de medición, cálculo, control, es el tiempo desde el tiempo entre dos consecuciones de un mismo proceso. Por ejemplo, el tiempo desde que realiza una vez el proceso de cálculo y vuelve a realizarlo la siguiente vez. Con esta medida, se puede saber si la frecuencia del programa o su inversa, el tiempo de scan, permite adecuarse a los fenómenos a medir y controlar. Imaginemos que un proceso requiere que se mida una determinada cantidad y se procese cada milisegundo, sin embargo, el procesador tarda 4 milisegundos en completar «una vuelta» al programa, en este caso, será imposible realizar dicho control. La metodología del «ciclo de scan» es una metodología propuesta en este TFG. La metodología únicamente requiere que los objetos del sistema tengan un método llamado «scan». Este método será el encargado de llamar internamente a los procesos de configuración, actualización de máquinas de estado, etc. De este modo se crea un modelo homogéneo de objeto acoplable al diseño y cada diseñador únicamente deberá llamar a dicho método de scan que incorporará toda la lógica necesaria de ese objeto para el proyecto. Además de realizar un diseño homogéneo, el ciclo de scan simplifica las labores de medición de tiempos dado que por cada objeto podremos obtener el tiempo que supone dentro del sistema e identificar caminos críticos en el diseño. Durante la siguiente etapa se verá de una forma más clara como se ha implementado esta metodología en cada uno de los objetos así como las ventajas de la programación orientada a objetos en el diseño embebido. Implementación Implementación del módulo de control En este punto se verá la implementación del módulo de control. El modulo de control, como ya se ha comentado anteriormente, es el encargado de realizar los movimientos mediante el cilindro. Para ello se apoya en el circuito integrado L298. El módulo de comunicaciones ha sido encapsulado en la clase «Motor». Esta clase proporciona una serie de métodos públicos como forward(), backward(), stop() y update(). Que permiten al usuario realizar determinadas acciones sobre el cilindro. En el modo manual, el usuario podría requerir mover el cilindro de forma indefinida, para 126
ello, se hacen públicos los métodos runForward() y runBackward(). Por otro lado, si el controlador está en modo automático entonces los movimientos se realizarán hacia intervalos conocidos, por ejemplo el 70 %, para ello se dota a la clase de los métodos forward() y backward(). El método update() es igual que el método scan() explicado en la sección anterior. Mediante este método, el objeto motor actualiza su posición leyendo el sensor resistivo y comprueba si existe algún defecto mediante una serie de métodos auxiliares. Por otro lado, este método comprueba que el controlador está funcionando en modo automático y si es así comprueba que no se haya alcanzado la posición final para seguir moviendo el cilindro, en caso de que se haya alcanzado para. Este método también actualiza el estado de la rasera (más adelante se verá este objeto) a la que está asociada de modo que en todo momento se pueda monitorizar qué acción se está realizando. Una de las ventajas del encapsulamiento es que el usuario de esta clase no se deberá preocupar por realizar ningún tipo de comprobación a la hora de realizar los movimientos dado que internamente, cada método comprobará que el movimiento se realiza de manera segura. Por ejemplo, el método forward() que se utiliza para mover el cilindro en modo manual, se asegura que anteriormente no se estuviera moviendo el cilindro en otra posición para que no se generen sobretensiones. En el Listado 5.12 se puede ver como en el primer «if» se comprueba que el cilindro esté en alguna de las posiciones seguras para no generar ningún tipo de sobretensión. Si es así entonces se permite actualizar el valor requerido y cambiar la dirección pedida de tal manera que el método update() sepa que tiene que mover hacia delante el cilindro. Si por el contrario, no se estaba moviendo en la misma dirección el método automáticamente detiene el motor espera un tiempo configurable y mueve el motor en el sentido pedido. Con este pequeño cambio en el diseño, se solucionó el problema de las sobretensiones que se tenían en el primer prototipo. En cuanto al diseño, del mismo modo que en la realidad una rasera tiene asociada un cilindro que la mueve, en el código un cilindro pertenece a una rasera y una rasera tiene un cilindro por lo que mediante estas relaciones el cilindro puede saber y modificar el estado de la rasera a la que pertenece y la rasera puede realizar movimientos mediante su objeto motor asociado. Aunque el código es extenso y cuenta con más peculiaridades como la gestión de defectos etc, con el objetivo de simplificar el documento se adjunta el código a modo de documentación. Implementación del objeto Rasera El objeto Rasera, como su nombre indica, representa un objeto rasera. La rasera es la chapa metálica que debe ser motorizada. Cada rasera tiene una posición establecida dentro de la fábrica y está numerada. Además, una rasera debe moverse de acuerdo a unos porcentajes 127
1 2 3 4 5 6 7 8 9
void Motor::forward(int position) { if (this->current_direction == Motor::FORWARD || this->current_direction == Motor::IDLE_POSITION || this->current_direction == Motor::STOPPED) { //If we are moving in forward and in this moment //we receive a petition to increase the position //we continue and update the position this->required_position = position; this->current_direction = Motor::FORWARD; } else if (this->current_direction == Motor::BACKWARD) {
10 11 12 13 14 15 16 17 18 19
//If we are moving in forward and in this moment //we receive a petition to change the direction //first we need to stop this->stop(); delay(STOP_DELAY); this->current_direction = Motor::FORWARD; this->required_position = position; } }
Listado 5.12: Encapsulamiento del movimiento del motor.
fijados previamente por la «Harinera Castellana». En este proyecto, las raseras están manejadas por un controlador. Este controlador puede manejar hasta 8 raseras (en un principio debían manejar hasta 4). Por lo tanto, una rasera pertenece a un controlador y tiene un motor que la mueve. Con esta información se puede diseñar la clase «Rasera». Esta clase tendrá un objeto Motor asociado y un objeto Slavebox (se verá más adelante) al que pertenece. La clase «Rasera» permite, entre otras cosas aumentar el nivel de abstracción de modo que el usuario final utiliza funciones de alto nivel como el método automaticMove() para realizar un movimiento del cilindro de manera sencilla. El método scan() en este caso únicamente encapsula el método scan() del motor dado que es este quién realiza la mayor parte del trabajo físico. El objeto rasera como se puede observar es un objeto más orientado a la gestión. Mediante este objeto podremos acceder de forma sencilla a los valores almacenados en la EEPROM sin necesidad de realizar cálculos de posiciones. Por ejemplo, el método setGlobalNumber() permite de una manera muy sencilla que el usuario modifique el identificador global de esta rasera dentro de la fábrica. De este modo el usuario no debe preocuparse por almacenar dicho valor en la EEPROM ni de realizar las comprobaciones pertinentes. La gestión de los offset también se ha realizado en este objeto dado que es realmente la rasera quién tiene ese offset de instalación. Mediante el método setOffsetX() donde X puede ser 0 o 100 el usuario guarda el valor indicado en la EEPROM. Es importante tener en cuenta que en ningún caso el programador que utilice este objeto estará en contacto con la EEPROM de modo que se eviten posibles fallos en la codificación o cálculo de la posición donde se debe guardar dicho dato. La explicación de la implementación del objeto Rasera ha sido resumida debido al carácter 128
del propio objeto, cuyo diseño fue pensado con el objetivo de simplificar y aumentar la semántica del código así como de mantener la metodología de «un objeto real es un objeto virtual en el código». Si el lector desea consultar más en detalle el código puede revisar al código adjunto al proyecto. Implementación del objeto Screen El objeto Screen, como el lector habrá podido imaginar, equivale a la pantalla nokia del HMI. La clase «Screen» es una clase base para que los diferentes Screen del programa hereden de la misma. La clase «Screen» define varios métodos entre ellos el método scan() ya conocido y el método turn_led() que permite gestionar el parpadeo del backlight de la pantalla. La clase «Screen» será base para cada una de las pantallas que se quieran crear. Por poner un ejemplo, en el Listado 5.13 se puede ver la implementación de la pantalla general mediante la orientación a objetos. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
ScreenGeneral::ScreenGeneral(PCD8544 *display, SlaveBox *slave) : Screen(display, slave) { this->hard_display = display; this->slave = slave; this->multiplicator = 0; } void ScreenGeneral::drawScreen() { Rasera * rasera_aux; this->hard_display->setCursor(0, 0); this->hard_display->print("GRUP0"); this->hard_display->setCursor(36, 0); this->hard_display->print(this->slave->getSlaveNumber()); if (this->slave->getMode() == SlaveBox::AUTOMATIC) { this->hard_display->setCursor(60, 0); this->hard_display->print("AUTO"); } if (this->slave->getMode() == SlaveBox::MANUAL) { this->hard_display->setCursor(60, 0); this->hard_display->print("MANU"); } this->hard_display->setCursor(0, 1); this->hard_display->print("No Pedido Real"); this->hard_display->setCursor(0, 2); this->hard_display->clearLine(); rasera_aux = (this->slave->getRaseras()[multiplicator * 4 + 0]); this->hard_display->print(rasera_aux->getGlobalNumber()); if (rasera_aux->getMode() == Rasera::MANUAL) { this->hard_display->setCursor(15, 2); this->hard_display->clearLine(); this->hard_display->print("X"); } if (rasera_aux->getDefect() > 0) { this->hard_display->setCursor(15, 2); this->hard_display->clearLine(); this->hard_display->print("E"); } this->hard_display->setCursor(31, 2);
129
this->hard_display->print(" "); this->hard_display->setCursor(31, 2); this->hard_display->print(rasera_aux->getMotor()->getRequiredPosition());
38 39 40 41 42 43 44 45 46 47 48 49
this->hard_display->setCursor(61, 2); this->hard_display->print(rasera_aux->getCurrentPosition()); this->hard_display->setCursor(0, 3); this->hard_display->clearLine(); } void ScreenGeneral::checkMoves(decode_results *results) { Rasera * aux = NULL; aux = this->slave->getCurrentManualRasera(); if (aux != NULL) { switch (results->value) { case REMOTE_KEY_FORWARD:
50 51 52 53 54 55
aux->manualMove(Motor::FORWARD); break; case REMOTE_KEY_BACKWARD: aux->manualMove(Motor::BACKWARD); break;
56 57 58 59 60 61 62 63 64 65 66 67
case REMOTE_KEY_PLAYSTOP: aux->manualMove(Motor::STOPPED); break; } } } void ScreenGeneral::scan(decode_results *results) { Screen::scan(results); this->drawScreen(); this->checkMoves(results); if (results->value == REMOTE_KEY_POWER && this->slave->getHoldKey() == 1) { delay(1000);
68 69 70 71 72 73
asm("jmp 0x0000"); } else if (results->value == REMOTE_KEY_MUTE && this->slave->getHoldKey() == 1) { if (this->slave->getMode() == SlaveBox::AUTOMATIC) { this->slave->setMode(SlaveBox::MANUAL); } else {
74 75 76 77 78 79
this->slave->setMode(SlaveBox::AUTOMATIC); } } else if (results->value == REMOTE_KEY_EQ && this->slave->getHoldKey() == 1) { this->slave->setDefects(0); } else if (results->value == REMOTE_KEY_MODE) { this->hard_display->clear();
80 81 82 83 84 85
ScreenMenu *menu = new ScreenMenu(this->hard_display, this->slave); this->slave->setCurrentScreen(menu); delete this; } else if (results->value == REMOTE_KEY_UD) { if (multiplicator == 1) {
86 87 88 89 90 91 92 93 94
multiplicator = 0; this->hard_display->clear(); } else { multiplicator = 1; this->hard_display->clear(); } } }
130
Listado 5.13: Uso de la herencia en sistemas embebidos Como se puede observar, la pantalla ScreenGeneral hereda de Screen. Al heredar debe implementar aquellos métodos abstractos puros como es el caso del método drawScreen() el cual debe dibujar en la pantalla los datos que se desean mostrar. Por otro lado, el método scan() también se implementa llamando en primer lugar al método scan() del padre el cual se encargará de gestionar el backlight y luego escribirá los datos en pantalla. En este caso, comprobará si el usuario está en modo manual y está pulsando a los botones para mover el motor y, por último, comprobará las diferentes acciones posibles dentro de una pantalla, como podrían ser: moverse entre menús, interactuar con esa pantalla, etc. El método de utilización de la pantalla es sencillo. El objeto Slavebox (será explicado más adelante) tiene un atributo llamado current_screen(). Este atributo es de tipo Screen lo que quiere decir que cuando se haga el set de este parámetro se realizará un upcasting hacia el objeto genérico Screen. Cuando en el método scan() del objeto Slavebox se llame al método scan() del Screen, entonces, se aplicará el polimorfismo y comprobará qué método debe llamar en función del tipo de Screen esté asignada. Es decir, se presenta una interfaz común y se maneja de un único modo pero el programa es capaz en tiempo de ejecución de llamar al método correspondiente en función del tipo de pantalla que esté configurada. En el Listado 5.14 se puede ver como efectivamente se invoca el método scan() del objeto current_screen el cual es de tipo Screen y no de un tipo especializado. 1
void SlaveBox::scan(decode_results *results) {
3
//FieldCommunication scan
4
fc->scan();
6 7 8 9
//Scan of each Rasera for (int i = 0; i < NUMBER_OF_RASERAS_FOR_BOX; i++) {
11 12 13 14 15
this->defect |= raseras[i]->scan(); } //Scan of current screen if (this->current_screen) { this->current_screen->scan(results); } }
Listado 5.14: Polimorfismo
En cuanto al diseño de este objeto se tomó la decisión de plasmar el sistema de representación HMI como dos objetos. Por un lado está el objeto screen el cual representa el contenido de la pantalla y por otro lado está el objeto hard_screen que representa el hardware de la pantalla. Esto se realizó así para que cada Screen tuviera acceso al hardware que permite es131
cribir el contenido en pantalla. Además, un controlador (Slavebox) tiene una current_screen o pantalla actual que se irá modificando en función de las acciones del usuario. Aunque la implementación de cada uno de los Screen tiene sus peculiaridades y podría ser explicadas con detalle, con el objetivo de reducir la longitud del documento y simplificar la tarea de lectura, la implementación de estos objetos no se explicará en este documento. Implementación del objeto RemoteController El objetivo de este punto consiste en explicar la implementación de la representación virtual del controlador infrarrojo. Este controlador consiste en un emisor infrarrojo con una serie de botones que son enviados como un tren de pulsos hacia el receptor. La librería utilizada para la gestión de este controlador es IRremote. Esta librería permite decodificar un gran conjunto de protocolos infrarrojos. La clase «RemoteController» es una representación de este objeto físico en el programa, sin embargo, debido a diferentes problemas que aparecen a la hora de encapsular la funcionalidad de la librería IRremote, no se pudo realizar una implementación pura del objeto en la clase «RemoteController». Esta clase cuenta con una serie de definiciones que permite mapear cada uno de los códigos infrarrojos a su correspondiente tecla. Además contiene el método scan() donde se debería aplicar el código mostrado en el Listado 5.9. Sin embargo, como ya se ha comentado no se ha podido realizar dado que la librería IRremote fallaba al encapsular su funcionamiento. Por otro lado, la clase proporciona una serie de métodos estáticos que pueden ser utilizados para simplificar el uso de los infrarrojos. Un ejemplo de esto podría ser el método getRealNumber() el cual devuelve el número asociado a una de las teclas numericas. Las decisiones de diseño a la hora de crear esta clase eran las misma que las de otros objetos, se buscaba simplificar la iteración con objetos heterogéneos de una manera estándar. Implementación del objeto FieldCommunication Sin duda alguna la comunicación entre dispositivos es una parte primordial en el diseño de este tipo de sistemas. Históricamente, a este tipo de comunicaciones se les llamaba comunicaciones sobre el bus de campo. Existen diversos protocolos de comunicación en buses de campo, por ejemplo el protocolo Modbus, Profibus o Profinet. El objeto FieldCommunication busca representar mediante un objeto de alto nivel la comunicación de campo. El método principal de este objeto es, como es fácilmente deducible, el método scan(). Este método es el encargado de, al igual que con los demás objetos, actualizar las variables internas y actuar según la lógica interna del objeto. En el caso del objeto FieldCommunication, el método de scan() simplemente llama a la actualización de la máquina de estados que, como suele ser normal en este tipo de aplicaciones, realiza la tarea de gestión del protocolo de comunicación. 132
La implementación de una máquina de estados para la gestión de protocolos es una tarea muy estudiada en el mundo de los sistemas embebidos debido a la importancia que esta supone para el diseño final. La máquina de estados debe ser capaz de poder gestionar todas las situaciones posibles que se puedan dar en la ejecución de la misma. Por poner un ejemplo, en una primera aproximación no se tuvo en cuenta la recuperación tras un error en la decodificación de alguno de los datos y la máquina se quedaba «atascada» en uno de los «case» del «switch» que normalmente manejan la lógica del cambio de estado. Con el objetivo de realizar una implementación robusta[mac92] se realizó un diagrama de transición de tal manera que quedara reflejado cada uno de los estados por los que va pasando la máquina de estados así como las acciones a realizar en cada caso.
Figura 5.51: Diagrama de estados de la máquina de estados
La codificación de la máquina de estados puede ser revisada en el Listado 5.15. A continuación se explicará con detalle la implementación de la máquina de estados. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
void FieldCommunication::state_machine() { static uint8_t current_byte = 0; /**< Byte read **/ switch (current_state) { case WAITING: /**< Any packet **/ if ((current_byte = Serial.read() == START_BYTE)) { _DEBUG_(SerialDebugger.printer->println("\r\nByte start alcanzado")); current_state = DECODING_HEADER; } else { /** * Caution here, with a lot of traffic we will have problems... * Blocks until buffer equals to zero */ while (Serial.available() != 0) { _DEBUG_(SerialDebugger.printer->println("Limpiando buffer")); current_byte = Serial.read(); if (current_byte == START_BYTE) { current_state = DECODING_HEADER; break; } }
133
21 22 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 40 41 42 43 44
} break; case DECODING_HEADER: _DEBUG_(SerialDebugger.printer->print("\r\nDecoding header: ")); _DEBUG_(SerialDebugger.printer->println(Serial.available())); if (Serial.available() >= HEADER_SIZE - 1) { //Create header and decode it Header::unmarshalling(this, this->last_packet_received); _DEBUG_(SerialDebugger.printer->println("Unmarshalling header completado")); if (this->getLastPacketReceived()->getHeader()->getBoxNumber() == this->getSlave()->getSlaveNumber()) { current_state = DECODING_PAYLOAD; } else { current_state = WAITING; } } break; case DECODING_PAYLOAD: switch (this->last_packet_received->getHeader()->getCommand()) { case COMMAND_CHECK_STATE: { _DEBUG_(SerialDebugger.printer->println("Entry command check state")); PayloadCheckState * payload = NULL; payload = PayloadCheckState::unmarshalling(this, this->last_packet_received);
45 46 47 48 49 50 51 52 53 54 55 56
if (payload) { this->last_packet_received->setPayload(payload); this->current_state = WAITING_DO_ACTION; } else { //this->state = STATE_MACHINE_WAITING; } } break; case COMMAND_SEND_POSITION: { _DEBUG_(SerialDebugger.printer->println("Entry command send position")); PayloadSendPosition * payload = NULL; payload = PayloadSendPosition::unmarshalling(this, this->last_packet_received);
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
if (payload) { _DEBUG_(SerialDebugger.printer->println("Send position decoded")); this->last_packet_received->setPayload(payload); this->current_state = WAITING_DO_ACTION; } else { //this->state = STATE_MACHINE_WAITING; } } break; case COMMAND_REBOOT_SYSTEM: { _DEBUG_(SerialDebugger.printer->println("Entry command reboot")); PayloadRebootSystem * payload = NULL; payload = PayloadRebootSystem::unmarshalling(this, this->last_packet_received); if (payload) { _DEBUG_(SerialDebugger.printer->println("Entry reboot decode")); this->last_packet_received->setPayload(payload); this->current_state = WAITING_DO_ACTION; } else {
134
//this->state = STATE_MACHINE_WAITING;
79 80 81 82 83 84
} break; } case COMMAND_MODIFY_VALUE: { _DEBUG_(SerialDebugger.printer->println("Entry command modify"));
85 86 87 88 89 90
PayloadModifyValue * payload = NULL; payload = PayloadModifyValue::unmarshalling(this, this->last_packet_received);
91 92 93 94 95 96
} else {
if (payload) { this->last_packet_received->setPayload(payload); this->current_state = WAITING_DO_ACTION; //this->state = STATE_MACHINE_WAITING; } } break; case COMMAND_CHECK_VALUE: { _DEBUG_(SerialDebugger.printer->println("Entry check value"));
97 98 99 100 101 102
PayloadCheckValue * payload = NULL; payload = PayloadCheckValue::unmarshalling(this, this->last_packet_received); if (payload) { _DEBUG_(SerialDebugger.printer->println("Check value decoded")); this->last_packet_received->setPayload(payload);
103 104 105 106 107 108
this->current_state = WAITING_DO_ACTION; } else { //this->state = STATE_MACHINE_WAITING; } break; }
109 110 111 112 113 114
default: _DEBUG_(SerialDebugger.printer->println("Problems")); break; } break; case WAITING_DO_ACTION: this->last_packet_received->getPayload()->setSlave(this->slave);
116 117 118 119 120 121 122
this->last_packet_received->getPayload()->do_action(this, this->last_packet_received); this->current_state = WAITING; } }
Listado 5.15: Implementación de la máquina de estados de comunicaciones Antes de hablar de la implementación de la máquina de estados, se debe hablar del protocolo de comunicaciones establecido debido a que es este el que ha condicionado las decisiones de diseño de este módulo. El protocolo de comunicaciones ha sido implementado desde cero por lo que no guarda ninguna similitud con el protocolo implementado en el prototipo inicial. Junto a este documento se adjunta un fichero llamado sintaxis.ods que contiene la hoja de cálculo con la especificación del protocolo. El protocolo de comunicaciones básicamente consta de dos grandes partes: 135
1. Header o cabecera: Este objeto está formado por diferentes campos que permiten al receptor conocer diferentes datos sobre la acción que desea realizar el emisor. Los campos son el byte de start, el emisor del mensaje pudiendo ser este el máster (M) o la respuesta del slave (S), el número de esclavo que permite identificar a los módulos de control si el mensaje está destinado a él. Por otro lado, el campo llamado rasera number, permite identificar a qué rasera va destinada la acción identificándose el modo broadcast con el número de rasera 99. El último campo es el encargado de definir el comando que se desea realizar y es importante de cara a la decodificación del payload dado que el receptor leerá este campo y preparará los bufferes en función del payload. 2. Payload: Los campos de la parte payload dependen del tipo de comando que se quiera enviar. Para este proyecto se han definido los siguientes payload: a) Check state: Permite comprobar el estado de una o varias raseras (broadcast) dentro de un controlador. El master enviará un mensaje con el campo comando al valor 00. Una vez recibido el mensaje, el slave responderá con el estado tanto del cilindro (posición) como los defectos de esa rasera. b) Send position: Este payload permite al emisor modificar el estado de la rasera de modo que automáticamente el controlador de motores mueva el motor hacia la posición indicada. Del mismo modo que check state, send position permite la actuación en modo broadcast. c) Reboot system: Mediante este comando se puede reiniciar el sistema por si en algún momento fuera necesario. d) Modify EEPROM Value: Este payload permite modificar algún valor dentro de un controlador. Los valores de la EEPROM son los offset así como los números que identifican cada rasera en la fábrica. e) Check EEPROM Value: Permite verificar el valor almacenado en una posición de la EEPROM. La implementación del protocolo en sí mismo (no la máquina de estados) se verá en otro punto. Como se puede observar en el Listado 5.15, el objeto FieldCommunication tiene un atributo llamado current_state como el nombre indica, current_state mantiene el estado en el cual se encuentra la máquina de estados. Al iniciarse el sistema, la máquina de estados se encuentra en el estado WAITING. En este estado se lee constantemente el bus en busca del byte de inicio. Si se encuentra dicho byte entonces se pasa al estado DECODING_HEADER. El estado DECODING_HEADER se encarga de comprobar que en el buffer de recepción hay los suficientes bytes para completar una cabecera, si es así entonces se procede a decodificarla. Para decodificarla se usa el método unmarshalling() de la clase «Header» el cual se encargará de modificar el paquete actual (atributo de la clase «Fieldcommunication») con el nuevo «Header». Una vez decodificado el «Header» se comprueba si el mensaje está dirigido 136
a este esclavo o a otro. Si está dirigido a otro esclavo entonces se vuelve al estado WAITING donde se irá eliminando todos los bytes hasta que se vuelva a alcanzar el byte de inicio. En caso de que el mensaje esté dirigido hacia el esclavo que está realizando la decodificación se procede hacia el siguiente estado, es decir, hacia el estado DECODING_PAYLOAD. El estado DECODING_PAYLOAD al igual que el estado DECODING_HEADER se encarga de decodificar el payload que corresponda. La implementación de la máquina de estados ha sido una de las partes más costosas de la programación del firmware. En esta programación se deben tener en cuenta muchos supuestos que pueden ocurrir y siempre tener un camino de «reinicio» de la máquina de estados. Uno de los fallos que ocurrían era que podía darse el caso en que un byte del payload se perdiera, en ese caso la máquina se quedaba constantemente en el estado de DECODING_PAYLOAD. Para solucionar este problema se optó por establecer un tiempo de espera tras el cual la máquina volvía a un estado conocido. Otro fallo que se detectó en la fase de la implementación del software de gestión (como se verá más adelante) era la imposibilidad de asegurar que un mensaje había llegado, para ello se añadió una etapa de ack. Esta mejora se verá más adelante. Por último se estudió la necesidad de un mecanismo de seguridad. Aunque los sistemas de gestión no son sistemas con requerimientos de confidencialidad (normalmente, aunque existen casos en los que sí es necesario) sí requieren en muchos casos de integridad y autenticidad. Dotar a un protocolo de integridad asegura que los mensajes, cuando viajen por el medio no serán manipulados y en caso de que exista alguna modificación, bien por fenómenos eléctricos o bien por medios no lícitos, el sistema de seguridad será capaz de detectarlo. Por otro lado, dotar al protocolo de un modo de asegurar la autenticidad, permite al protocolo detectar si el emisor del mensaje es un emisor autorizado. Si el protocolo no tiene este tipo de mecanismo entonces un posible atacante podría en cualquier momento «escuchar» el bus (no va encriptado, no es confidencial) e inferir el protocolo. Una vez que sabe cual es el protocolo podría mandar mensajes arbitrarios moviendo, en nuestro caso, las raseras a la posición que deseara. Para solucionar esto se ha estudiado la implementación de un protocolo HMAC [BCK96] que explicaremos a continuación. Aunque el protocolo ha sido estudiado no ha sido implementado hasta ahora por razones de facilidad a la hora de depurar el protocolo dado que el hash se manda en binario, no obstante, la arquitectura del software permite adaptar la fase de seguridad sin ningún tipo de problema. El mecanismo de seguridad utilizado es uno de los muchos basados en el sistema keyedHash Message Authentication Code (HMAC). En criptografía un sistema HMAC que involucra por un lado una función hash y por otro lado una clave criptográfica. Como se puede observar, un sistema HMAC involucra dos bloques. Un hash es un resumen del payload o carga útil. El resumen se realiza mediante operaciones matemáticas. Existen diversos algoritmos de cálculo de resúmenes hash como: MD5, SHA-1, SHA-256, etc. 137
La función HMAC se puede definir tal y como se muestra en la Ecuación 5.1. La función HMAC se sostiene en la función hash (H) que se aplica sobre la clave criptográfica (K) con tantos ceros como sea necesario para llenar el tamaño de bloque concatenado con la función hash aplicada sobre la clave criptográfica sobre una operación xor con el relleno interior concatenado con el mensaje. Como se puede ver la función es bastante compleja, sin embargo, gracias a las librerías ya implementadas no es necesario tener en cuenta todos estos conceptos, únicamente tener una visión general de qué está ocurriendo (ver Figura 5.52).
HM AC(K, m) = H (K ⊕ opad) || H (K ⊕ ipad) || m
(5.1)
Para la implementación del mecanismo de seguridad HMAC se ha utilizado la librería Cryptosuite la cual se puede descargar desde el siguiente enlace http://spaniakos.github.io/ Cryptosuite/. En el Listado 5.16 se puede ver un ejemplo de utilización de esta librería. 1
#include "sha256.h"
3 4
uint8_t hmacKey1[]={
5
};
7 8 9
void printHash(uint8_t* hash) {
0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0 x0b
10 11 12 13 14 16 17 18
int i; for (i=0; i>4]); Serial.print("0123456789abcdef"[hash[i]&0xf]); } Serial.println(); } void setup() { uint8_t* hash; uint32_t a; Serial.begin(9600);
20
// HMAC tests
22 23 24 25 26 27 28 29 30 32 33
Serial.println("Test: RFC4231 4.2"); Serial.println("Expect:b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); Serial.print("Result:"); Sha256.initHmac(hmacKey1,20); Sha256.print("Hi There"); printHash(Sha256.resultHmac()); Serial.println(); } void loop() { }
138
Listado 5.16: Utilización de la librería CryptoSuite. Fuente:
http://spaniakos.github.io/
Cryptosuite/
Mediante la implementación de este mecanismo de seguridad solo los emisores autorizados podrán mandar mensajes sobre el bus, además, se podrá comprobar si el mensaje es íntegro, es decir, si no ha sido modificado en el trayecto. Como se ha podido ver, el objeto FieldCommunication es el encargado de gestionar las comunicaciones, aunque la complejidad interna es alta, de cara al exterior únicamente hay que implementar el método scan al scan global. Si el programa hubiera sido creado con vistas a un diseño genérico, se habría implementado funciones callback de modo que el usuario pudiera definir sus propios manejadores de eventos, no obstante ese no es el objetivo del proyecto.
Figura 5.52: Proceso HMAC
Implementación del protocolo En este punto veremos como se instancia el protocolo explicado en la implementación del objeto FieldCommunication. Como ya se ha comentado, el protocolo diseñado consta de dos grandes partes, por un lado tenemos la cabecera y por otro lado tenemos el payload. La cabecera tiene un tamaño fijo, sin embargo, el payload depende del tipo de comando que se indique en el campo «comando» de la cabecera. Para gestionar el protocolo se ha creado un objeto llamado «Packet» el cual contiene un objeto «Header» y un objeto «Payload». Como se puede observar, esto es una representación programática de lo que se ha explicado en el punto anterior sobre el protocolo. 139
El objeto «Header» es una única estructura de datos (en este caso en forma de clase) la cual agrupa el conjunto de bytes recibidos como una entidad. Además, la clase «Header» proporciona dos métodos muy interesantes de cara a la gestión de las comunicaciones. Por un lado, tenemos el método marshalling el cual realiza la conversión de un tipo Header a un array de bytes listos para ser enviados por el bus 485. Al igual que está implementado el método marshalling está implementado el método unmarshalling que devuelve un objeto Header a partir de un conjunto de bytes obtenidos del bus 485 en este caso. Además del objeto Header, también se ha implementado el objeto genérico Payload. Este objeto únicamente proporciona una base sobre la que heredar para especializar el tipo de payload que se desee. En el Listado 5.17 se puede ver la definición del objeto. En esta definición se pueden apreciar el método virtual do_action(), este método deberá ser definido por cada uno de los payload que hereden de esta clase base. El objetivo de hacer este método virtual es que se pueda aplicar el polimorfismo de tal manera que en la clase «Header» se tiene referencia a un Payload genérico pero cuando se invoque al método do_action() en tiempo de ejecución se llamará al método correspondiente al payload actual. De este modo se simplifica la labor de diseño de nuevos payload. 1 2
#ifndef PAYLOAD_H_ #define PAYLOAD_H_
4 5 6
#include
8
class FieldCommunication;
9
class Packet;
11 12 13 14 15 16 17 18
#include "Packet.h" #include "FieldCommunication.h"
/** * @brief Generic payload, this payload is the base class to specific payloads. */ class Payload { private: SlaveBox *slave; public: Payload(); /** * @brief This method must be override in each specific payload.
20 21 22 23 24 25 26
* @param fc FieldCommunication that has the Serial Device. * @param packet Packet owner of this device * @return True or False */ virtual bool do_action(FieldCommunication *fc, Packet* packet) = 0; virtual ~Payload();
27 28 29 30
};
32
#endif /* PAYLOAD_H_ */
SlaveBox * getSlave(); void setSlave(SlaveBox* slave);
140
Listado 5.17: Definición de la clase Payload A modo de ejemplo de diseño de uno de los múltiples payload implementados se verá la implementación del payload encargado de mover los cilindros a una determinada posición, este payload está representado por el objeto «PayloadSendPosition». Este objeto además de implementar el método do_action(), también implementa un método unmarshalling() que aunque no se hereda de la clase base se implementa en la mayoría de los payload implementados. En el método do_action() el objeto manda un mensaje (invocación de método) al objeto rasera que determine la cabecera para realizar el movimiento. Este modo de diseñar el protocolo simplifica mucho la labor de gestión de las comunicaciones, además añade un extra de escalabilidad al sistema. El diseño de este componente ha requerido de muchas horas de diseño debido a las diferentes implicaciones que tiene el realizar el diseño de una manera u otra en los sistemas embebidos. Con este diseño se ha conseguido reducir el número de líneas de código con respecto al prototipo inicial, además se ha simplificado la labor de depuración debido a la encapsulación de los datos en diferentes clases. Implementación del objeto Slavebox
Figura 5.53: Caja con un controlador
El objeto Slavebox debe su nombre al diseño físico de cada uno de los controladores (ver Figura 5.53). Un Slavebox representa cada uno de los esclavos (controladores) que están suscritos al bus. Cada Slavebox controla un conjunto de raseras y posee un módulo de gestión 141
de comunicaciones y un módulo HMI. El objeto Slavebox contiene un objeto de cada módulo anteriormente citados y varios objetos de tipo Rasera en función del número de raseras que controle dicho Slavebox. 1
class SlaveBox {
3 4 5
public: /** * Mode of this slavebox */ enum mode_t {
6 7 8 9 10 12 13 14 15
AUTOMATIC, /**< Automatic mode, this slave is in the bus */ MANUAL /**< Manual, this slave is not in the bus */ }; private: Rasera **raseras; /**< Raseras attached to this slave */ Screen *current_screen; /**< Current screen that is displayed in the hardware display */ Rasera * current_manual_rasera; /**< If the mode is manual this variable has the current rasera that is in manual mode. Only one Rasera can be in manual mode */ uint8_t number_of_raseras; /**< Number of raseras of this slave */ defect_t defect; /**< Defects of this slave */
16 17 18 19 20 21 22 24
FieldCommunication *fc; /**< Module to communicate within the bus */ uint8_t slave_number; /**< Slave number of this slave *7 */ mode_t mode; /**< Mode of this slave (AUTOMATIC, MANUAL) */ uint8_t hold_key; /**< If a key is been holding, this variable save the situation */ long last_key; /**< Last key pressed before holding */ public:
26
SlaveBox();
28
/** * @brief Constructor for a Slavebox
29 30 31 32 33 34
* * @param raseras Raseras attached to this slave. * @param number_of_raseras Number of Raseras attached to this slave. * @param motors Motors controlled by this slave. * @param lcd_phy LCD attached to this controller.
35 36 37
*/ SlaveBox(Rasera ** raseras, uint8_t number_of_raseras, Motor ** motors, PCD8544 * lcd_phy);
39 40
/** * @brief Scan cycle.
41 42 43
* @param results Results of RemoteController */ void scan(decode_results * results);
Listado 5.18: Definición de la clase Slavebox
En el Listado 5.18 se puede ver la definición de este objeto. Como se puede observar todos los módulos explicados anteriormente se encuentran como atributo de este objeto. Además, este objeto tiene un método scan() el cual invoca a los métodos scan() de cada uno 142
de sus módulos, tal y como se puede observar en el Listado 5.195 . De este modo a nivel conceptual tenemos un esclavo con un conjunto de módulos de diferente tipo. Todos estos módulos proporcionan un método scan() los cuales son invocados por el esclavo, si en algún momento se quiere medir el tiempo que consume cada uno de los módulos se puede comparar el tiempo a la entrada y salida de dicho método scan() o si se quiere detectar qué modulo da algún tipo de fallo se puede comentar la línea donde se invoca su ciclo de scan(). Como se puede observar las metodologías seguidas simplifican mucho el código con respecto al código mostrado en el prototipo inicial. 1 2 3
void SlaveBox::scan(decode_results *results) { //Counts the number of times that the same key is pressed static uint8_t holding_count = 0;
5 6 7 8 9
//In the first scan we need to initiate some modules if (first) { this->getCurrentScreen()->getHardDisplay()->begin(); first = false; } //RemoteController has a specific key to represent holding if (results->value == REMOTE_KEY_HOLDING) {
11 12 13 14 15 16
if (holding_count > 4) { this->hold_key = 1; //Set the key that was pressed before holding results->value = last_key; holding_count = 0;
17 18 19 20 21 22
} else { holding_count++; } } else { this->hold_key = 0; holding_count = 0; this->last_key = results->value;
23 24 25
}
27 28
//FieldCommunication scan
30 31 32 33
//Scan of each Rasera for (int i = 0; i < NUMBER_OF_RASERAS_FOR_BOX; i++) {
37 38 39 40
//Scan of current screen if (this->current_screen) { this->current_screen->scan(results);
42
fc->scan();
this->defect |= raseras[i]->scan(); }
} } 5
El código correspondiente a la gestión de los infrarrojos está en este método por problemas con la implementación de la librería IRremote
143
Listado 5.19: Método scan del objeto Slavebox
Bucle de iteración, Iteración 2: De 4 a 8 raseras Requisitos o Restricciones En este caso no se aplica ningún requisito extra dado que esta iteración únicamente consiste en la adaptación de uno de los módulos ya implementados. Mejoras realizadas, evolución del diseño Después de la reunión llevada a cabo con la empresa «Harinera Castellana», se llegó a la conclusión de la necesidad de expandir el objetivo hasta un mínimo de 8 raseras por controlador. Es importante dar soporte a 8 raseras debido a la reducción del coste que supone ampliar el soporte. En teoría, ampliando al doble el número de raseras soportadas por cada controlador, se reducirá a la mitad el número de «Slavebox» y por lo tanto el coste del proyecto. Decisiones de diseño Para aumentar el número de raseras soportadas se deberá reprogramar algunos bloques de código de módulo HMI dado que actualmente únicamente muestra la información para 4 raseras. Además, se deberán modificar algunas partes del código para que se adapte completamente a esta nueva configuración. Es importante resaltar que debido a la modularidad del programa así como la parametrización del mismo, ha sido muy sencilla la adaptación dado que por ejemplo, para adaptar la mayoría de los bucles del programa únicamente se ha tenido que modificar una variable que indicaba el número de raseras que contenía un esclavo. En este punto surge la duda ante la eterna duda sobre qué es recomendable en el diseño embebido, ahorrar memoria reduciendo la mantenibilidad o mejorar la mantenibilidad reduciendo la memoria y en ciertos aspectos el rendimiento. En este caso se ha visto como un buen diseño ha permitido realizar este cambio de forma ágil y barata. Los costes de mano de obra suponen gran parte de un proyecto y en este caso, gracias a las decisiones de diseño tomadas se ha reducido el coste asociado a dicha mano de obra. Implementación La implementación se ha centrado sobretodo en la adaptación del bloque HMI. Si observamos la Figura 5.49, se puede ver cómo únicamente se muestra la información para 4 raseras y aparentemente no aparece en ningún lugar la opción de «pasar a la siguiente página». Esta ha sido la decisión adoptada, hacer un sistema basado en páginas de modo que en todos los lugares donde se requiera mostrar la información para más de 4 raseras se mostrará una flecha que indicará al usuario que puede pasar a la siguiente página. 144
Para conseguir este comportamiento se deben modificar la mayoría de las clases «Screen» y derivados de «Screen» de modo que añadan un atributo multiplicado el cual multiplicará por 2 el identificador local de la rasera de modo que en la «siguiente página» aparecerán las raseras desde la posición local 4 a la 7. En la Figura 5.50 se puede ver el resultado tras implementar el sistema de páginas propuesto en este punto. Resumen Con esta iteración se finaliza la etapa de implementación y diseño del subproyecto firmware. En este subproyecto hemos partido de una especificación funcional, un documento de requisitos y se ha propuesto un prototipo. Este prototipo, una vez mostrado al cliente ha permitido que el mismo pueda aportar una realimentación al proyecto. Un ejemplo de esta retroalimentación ha sido la modificación del número de raseras a controlar por cada uno de los controladores. Con el prototipo generado, el siguiente paso ha consistido en evolucionar el diseño. Para evolucionar el diseño se ha tenido que rediseñar la mayor parte del código debido al carácter no modular del primer código. Las decisiones de diseño que han conducido este subproyecto han sido la aplicación de la orientación a objetos en los sistemas embebidos intentando equiparar en todo momento el hecho de que un objeto físico es un objeto virtual el cual tienen unas propiedades y unos comportamientos asociados. Por otro lado, se ha propuesto una metodología novedosa para intentar simplificar la labor de mantenimiento por parte de los ingenieros de automática así como con el objetivo de dotar al sistema de características de los sistemas basados en PLC los cuales se ha demostrado que ayudan a dar estabilidad al diseño. Por último es importante hacer notar la dificultad que supone programar un sistema embebido de estas características donde cualquier pequeño fallo puede suponer grandes perdidas para la empresa. Por poner un ejemplo, el uso de memoria virtual puede acarrear que cada «x» tiempo se vaya reduciendo la capacidad de memoria disponible y finalmente el controlador deje de funcionar. Para conseguir evitar la mayoría de los fallos se debe partir de un conjunto de buenas prácticas tanto en el diseño como en la implementación. También es importante el adaptar patrones de diseño y en general metodologías del software basado en computadores de uso genérico a sistemas embebidos de tal manera que se llegue a un acuerdo entre rendimiento y mantenibilidad. Sin duda alguna hoy en día cada vez se dispone de microcontroladores con mayor capacidad de cómputo y sobre todo de memoria. Esto esta favoreciendo la delegación de tareas que históricamente se realizaban de forma electrónica o mecánica por métodos software. Los ingenierios informáticos por tanto tenemos aquí un gran nicho de mercado en el cual podemos aportar la experiencia en arquitectura y diseño del software reduciendo así los costes asociados al proyecto y aumentando la fiabilidad de estos sistemas.
145
5.2.4
Proyecto Software, Sistema de gestión
Durante este documento se ha ido siguiendo el diseño de un sistema embebido, este sistema busca modernizar una harinera simplificando la labor de los operarios y automatizando tareas repetitivas. El problema se ha dividido en diferentes partes de modo que el lector vea de forma detallada la implementación de cada una de ellas. En primer lugar se ha visto como se diseña e implementa la plataforma hardware que sostiene el firmware de control. En segundo lugar se ha detallado el proceso de diseño del sistema firmware que irá integrado en la plataforma hardware. Por último, en esta sección se verá la parte de más alto nivel del proyecto, el software de gestión. El software de gestión es el encargado de dotar al operario de la capacidad de modificar los procesos así como de conocer el estado de cada uno de dichos procesos productivos. En la «Industria 4.0» este software de gestión ha evolucionado hasta sistemas completamente inteligentes que permiten conocer en cualquier momento dónde se están produciendo las perdidas y porqué, entre otras cosas. En esta sección veremos cómo crear un software de gestión multiplataforma que sirva como base para futuros diseños y que demuestre la integración de servicios implementada. Etapa de inicio, Elección de plataforma Requisitos o Restricciones Aunque implícitamente hay muchos requisitos en este subproyecto, otros muchos no han sido definidos de manera formal. En el Anexo C se han especificado alguno de estos requisitos no obstante muchos otros se comentaron durante la reunión. Seguridad: Como siempre la seguridad es un requisito primordial en estos sistemas y para que se pueda alcanzar debe ser tenida en cuenta en cada una de las fases de diseño. Disponibilidad: El software de gestión deberá, estar disponible siempre que se requiera. Tiempo real: Las acciones que se realicen en el sistema deberán efectuarse de forma eficiente y asegurarse que se completan en un tiempo establecido. Si esto no ocurre se mandará un aviso al operario para que realice dicha acción de forma manual. Bajo coste: El bajo coste asociado al proyecto también afecta al software de gestión. En este caso este requisito afectará significativamente a la capacidad de elección de soluciones ya implementadas y reutilizables. Trazable: Todas las acciones realizadas mediante el sistema de gestión deberán ser trazables de modo que el jefe de producción pueda ver en todo momento quién a hecho qué.
146
Funcionalidades o características añadidas En esta primera etapa se ha realizado en primer lugar un breve estudio del estado arte, de modo que se tenga una visión global de lo que hasta ahora se ha realizado en el ámbito del software de gestión. Seguidamente se han estudiado las posibilidades de adopción de soluciones ya implementadas y tal y como se verá, ante la imposibilidad de adoptar alguna de estas plataformas, se ha realizado un estudio de las tecnologías de desarrollo software que permiten la implementación de dichos sistemas de gestión. Por último, como entregable de esta primera iteración se ha realizado una pequeña versión que muestra las posibilidades de este tipo de software de gestión al cliente de modo que él pueda aportar su experiencia y valoración sobre la propuesta planteada. Decisiones de diseño En los últimos años, con la aparición de la denominada «Industria 4.0» han surgido numerosas empresas ofreciendo soluciones para la automatización de los procesos productivos en todos los niveles. Empresas como «Odoo» o «Mesbook» están ofreciendo soluciones alternativas y de «bajo coste» sobre los sistemas que están instaurados actualmente. Antes de realizar una implementación se han estudiado diferentes alternativas existentes. A continuación se describirán los aspectos clave de cada una de estas soluciones: Groov: Groov es una solución basada principalmente en dotar al sistema de movilidad mediante las llamadas webapps. Groov además de una arquitectura software provee de hardware. El hardware permite monitorizar el bus para conocer el estado de la fábrica. Además, permite la inserción de tráfico mediante los protocolos más comunes como Modbus. Groov permite dos tipos de sistemas, uno basado en un servidor instalado en un ordenador de propósito general y el otro basado en un elemento hardware llamado GroovBox. En la Tabla 5.1 se muestra un cuadro comparativo entre las dos soluciones. Por otro lado, en la Figura 5.54 se puede ver un ejemplo del tipo de interfaz que se consigue mediante la tecnología Groov. Esta tecnología se puede adquirir desde los 995$ hasta los 1595$ en función del tipo de licencia requerida. Ignition: Ignition es un software de control basado en los tradicionales sistema SCADA pero según la compañía reinventando este tipo de sistemas. Según afirma la compañía, Ignition unifica tanto el sistema HMI como el sistema SCADA y MES en un único producto, el llamada New Scada. Las ventajas ofrecidas por Ignition son: • Basado en la web: Basado en tecnologías del lado del servidor y bases de datos centralizadas, permite la instalación de clientes en minutos. • Licencias ilimitadas: Las licencias están basadas en el servidor por lo que el número de clientes no afecta al precio de la licencia. • Seguridad y estabilidad: Ignition mantienen conexiones cifradas por SSL por lo que se asegura la privacidad de las conexiones. 147
• Control en tiempo real: Mediante la plataforma se permite el control integral del sistema en tiempo real. • Escalable: Con un sistema basado en orientación a objetos y un software para la creación de Software Development Kit (SDK)s se simplifica la labor de expandir el diseño. En la Figura 5.55 se puede ver alguna captura de aplicación del software Ignition. El precio de una solución basada en Ignition parte de los 1500ehasta los 22000e. AggreGate SCADA/HMI: AggreGate es un sistema para la visualización y control de procesos y flujos de producción. Es multiusuario y permite el control distribuido. Al igual que las demás plataformas, Aggregate se basa en la adquisición de datos y representación en forma gráfica. El sistema está compuesto por un conjunto de drivers que permiten controlar diferentes PLCs y diferentes protocolos como Modbus o SNMP. Por otro lado, Aggregate trae un sistema de creación de interfaces HMI que simplifica el proceso de diseño de frontends. En la Figura 5.56 se puede ver unas capturas del ecosistema Aggregate. El precio de este sistema depende del tipo de licencia solicitada y debe ser presupuestado por lo que no se puede dar una cifra.
(a) Ejemplo de aplicación groov
(b) Ejemplo de responsive design en groov
Figura 5.54: Groov
Como queda reflejado, existen muchas soluciones en el mercado que afirmar solucionar el ámbito de los sistemas de gestión. Las herramientas estudiadas son herramientas muy bien desarrolladas y con un alto grado de madurez, sin embargo estas herramientas ofrecen más de lo que se necesita para este proyecto. Teniendo en cuenta las tendencias aparentemente observadas en los sistemas estudiados, se intentará realizar un diseño que sea capaz de competir con los sistemas ya diseñados 148
ofreciendo el valor añadido del bajo coste con la misma fiabilidad y prestaciones. Del mismo modo, esta última parte del proyecto está enfocada de forma directa al problema propuesto y no se ha diseñado como una solución genérica (como sí lo hacen los otros sistemas). El software de gestión propuesto está basado en una interfaz web de tal manera que no se necesita software específico ni fuertes dependencias que compliquen el despliegue del sistema. Existen numerosas tecnologías que permiten crear este tipo de software de un modo sencillo, entre ellas se ha estudiado: Django, Flask, Tornado, JSP, AngularJS. Sin embargo al final se ha optado por Flask. Flask es un microframework que permite crear aplicaciones web con muy pocas líneas de código. Flask está basado en Wekzeug y Jinja 2 y está licenciado bajo BSD. En el Listado 5.20 se puede ver un ejemplo mínimo de una aplicación web basada en Flask. Como se habrá podido observar, Flask está basado en python lo cual permite que el sistema sea multiplataforma, es decir, el servidor podrá estar en un pc con windows o en un pc con GNU/Linux. En este caso se escogerá este último para reducir aun más los costes. En esta primera iteración veremos cómo realizar una primera aplicación de modo que el cliente pueda ver cómo será el sistema y el concepto de software basado en el navegador. Partiendo del ejemplo mostrado en el Listado 5.20 y de la instalación de Flask ya realizada6 , probaremos en primer lugar a lanzar un servidor de desarrollo para comprobar que todo funciona correctamente. Para iniciar el servidor de pruebas únicamente hay que utilizar el comando mostrado a continuación: # python fichero.py
En este momento se creará un servidor web en la dirección por defecto: http://localhost: 5000/ si se accede a dicha dirección desde un navegador web, se podrá ver el texto «Hello World!». A continuación pasaremos a explicar cada una de las partes del Listado 5.20. Todas las aplicaciones Flask deben incorporar la primera línea donde se importa la clase «Flask». La clase «Flask» es la clase principal del framework. Siguiendo con el orden natural del código, en la segunda línea se instancia un objeto de la clase «Flask» con un parámetro llamado «__name__» Este parámetro permite identificar de forma única una aplicación Flask teniendo en cuenta que entre ficheros el identificador «__name__» será distinto. En este caso «app» identificará a la aplicación en todo nuestro proyecto. En las siguientes líneas se puede ver cómo se define un método llamado hello el cual tiene un decorador justo encima. Los decoradores en Flask permiten añadir determinadas funcionalidades a los métodos que le siguen. Por ejemplo, el decorador route() permite definir una ruta que llevará a la invocación de este método. En este caso, la ruta «/» será la que invoque al método hello. Un método etiquetado con el decorador route() debe retornar algún tipo de dato que pueda ser convertido a una respuesta HTTP. En este caso se retorna simple texto plano. Por último, la línea con 6
El proceso de instalación se puede ver desde el siguiente enlace: http://flask.pocoo.org/
149
el condicional únicamente permite lanzar el servidor de desarrollo cuando se llame a este fichero desde la línea de comandos.
Figura 5.55: Ignition
150
Figura 5.56: Aggregate
1 2
from flask import Flask app = Flask(__name__)
4
@app.route("/")
5 6
def hello():
8 9
if __name__ == "__main__":
return "Hello World!"
app.run()
Listado 5.20: Ejemplo mínimo de aplicación Flask Ahora que se tiene claro cómo funciona de forma resumida un programa en Flask se realizará la primera prueba funcional en la cual cuando el usuario pulse un botón automáticamente se encenderá el led 13 del Arduino. De este modo sabremos que la comunicación con el Arduino a funcionado correctamente. Para conectar Flask con el Arduino hay que tener en cuenta que realmente no «hablamos» con Arduino si no que simplemente escribirmos en un bus que a su vez lee Arduino. Para escribir en el bus deberemos tener un medio físico que lo permita. En este caso, para realizar la conversión de Universal Serial Bus (USB) a serie se utilizará el dispositivo mostrado en la Figura 5.57. Este dispositivo lleva incorporado un conversor FTDI el cual realiza toda la labor de conversión. Es importante tener en cuenta que para estas primeras pruebas se realizarán sobre el bus serie del Arduino y no sobre el bus 485 debido a cuestiones de simplicidad física. No obstante el proceso es exactamente el mismo. Para manejar los dispositivos seriales mediante python se ha creado la librería pySerial. Esta librería simplifica el tratar con este tipo de dispositivo dando una interfaz semejante a 151
Figura 5.57: Conversor FTDI
la que tendríamos al abrir un fichero de texto, es decir, tendremos métodos como open(), read() y write(). La librería pySerial puede ser descargada desde el siguiente enlace: https: //pypi.python.org/pypi/pyserial. Una vez tengamos la librería podemos proceder al código del lado del servidor. En primer lugar copiaremos lo indispensable de toda aplicación Flask y añadiremos un método que nos permitirá ver un formulario web. En este caso vamos a dejar el código original y añadiremos únicamente la nueva funcionalidad, de esta manera tendremos dos métodos que probar. Para crear estructuras web, en Flask se utiliza el motor de renderizado Jinja 2. Jinja 2 permite añadir una serie de construcciones sintácticas al código html de tal forma que este se comporte de forma dinámica. En la página web de Jinja se puede ahondar en los conceptos subyacentes7 . Flask proporciona un método llamado render_template() que permite renderizar un html codificado con Jinja. En el Listado 5.21 se puede ver el código html utilizado para este primer ejemplo. Como se puede observar es código html básico pero debajo de la etiqueta h1 se puede observar una etiqueta h2, esta etiqueta contiene unas llaves las cuales indican que dentro se encuentra código Jinja 2, en este caso únicamente se indica a Jinja que busque una variable llamada my_string y la incorpore al código html. Por otro lado, en el lado del servidor, tenemos el código del ejemplo anterior pero con la diferencia de que en este caso, hemos modificado la ruta que nos lleva a dicho método. En este caso, para acceder al método que muestra «Hello World!» hay que introducir la url: http://localhost:5000/anterior. Sin embargo, la vista que más nos interesa es la vista del formulario. En primer lugar tenemos el método llamado formulario el cual utiliza el método render_template() para renderizar el código html explicado anteriormente. Es importante que el lector tenga en cuenta que los templates (así se les llama dentro de Flask) deberán estar en el directorio «templa7
http://jinja.pocoo.org/docs/dev/
152
tes» debido que es aquí donde Flask busca por defecto. El lector habrá podido observar que además del nombre del template, también se añade un valor, «my_string», este valor corresponde al valor que se puso en el código Jinja dentro del template, es decir, así enviamos variables o datos a Jinja para representarlo en html. Por último no se ha incorporado el código de Arduino para no alargar demasiado este documento, sin embargo el código para realizar esta funcionalidad es trivial por lo que no debería ser ningún problema. 1 2 3 4 5 6 7 8 9 10 11
Type on/off Personal string {{ my_string }}
Listado 5.21: Formulario básico html
1 2
from flask import Flask from flask import request from flask import render_template
3 4
import serial
6
app = Flask(__name__)
9 10 11
@app.route("/anterior")
13 14
@app.route(’/’)
def hello(): return "Hello World!"
15
def formulario(): return render_template("formulario.html", my_string="Hola")
17 18
@app.route(’/’, methods=[’POST’]) def formulario_post():
20 21 22 23 24 25 26 28 29
text = request.form[’text’] conexion_serie = serial.Serial("puerto") if text == "on": conexion_serie.write("on".encode()) else: conexion_serie.write("off".encode()) conexion_serie.close() if __name__ == ’__main__’: app.run()
Listado 5.22: Backend del formulario básico 153
Tras realizar estas primeras pruebas se ha decidido utilizar Flask para realizar el sistema SCADA. Las ventajas que nos aporta son: Basado en tecnologías web: No necesita de grandes especificaciones, únicamente un ordenador con un navegador web y soporte para flask. Modular: Flask proporciona un conjunto de herramientas básicas para crear servicios web muy sencillos, si se quieren utilizar herramientas más complejas como por ejemplo un ORM se pueden instalar plugins de terceros. Sencillo: La sencillez reducirá los tiempos de desarrollo. Multiplataforma: Desde cualquier navegador, móvil o desde un ordenador se podrá acceder al sistema. Libre: Se volverán a reducir los costes del producto debido al carácter libre de esta herramienta Implementación Implementación de modelos y primeros mockups Del mismo modo que en el firmware, en este primer paso se identificarán los posibles modelos o clases que serán claves a la hora de realizar nuestro diseño. Tras un proceso de análisis se llegó a la conclusión de que las clases a definir serían: Rasera: Esta clase representa una rasera la cual tiene un identificador global dentro de la fábrica así como un número de esclavo que identifica el esclavo que controla dicha rasera y un identificador de proceso, que identifica el proceso al que pertenece esta rasera. Proceso: La fábrica está organizada por procesos, por un lado está el proceso de lavado, por otro lado está el proceso de secado, etc. Para realizar el sistema SCADA se han identificado los diferentes procesos de modo que el operario pueda tener diferentes desplegables donde ver el estado de cada uno de los procesos. Configuración: Un proceso puede tener diferentes configuraciones pre-establecidas de modo que el operario establezca una configuración para la fábrica y en los siguientes casos no tenga que volver a configurar uno a uno cada uno de los cilindros. Únicamente deberá seleccionar el proceso y la configuración y automáticamente todos los cilindros se irán moviendo. Usuario: El usuario representará al operario que utilice el sistema, en este caso el usuario estará identificado por un Documento Nacional de Identidad (DNI), un correo electrónico y una contraseña. Solo los usuarios autorizados podrán acceder al sistema. Mensaje de log: El cliente especificó en el documento de especificación de requisitos la necesidad de mantener un Log por proceso de tal modo que siempre se tenga una 154
trazabilidad sobre los cambios realizados en la fábrica. Esclavo: Tal y como se ha visto anteriormente, un esclavo es cada uno de los controladores de una o varias raseras. Esta clase «esclavo» permite agrupar y gestionar las comunicaciones de un modo más cómodo. Identificar las clases en una fase temprana del diseño nos permite ser más concretos a la hora de realizar los diseños posteriores. Paralelamente a la identificación de los modelos, se realizan unos mockups que ayudarán al cliente a decidir si ese diseño se adecua a lo que él busca. En este caso los mockups se han realizado en papel debido a que simplificaban la labor de edición a la hora de la reunión. Una vez el cliente aprueba este diseño se procede al diseño final en este caso en html. Como resultado de esta primera fase de implementación tenemos el diseño de la aplicación y los modelos identificados. En la fase de implementación se realizará la implementación del sistema básico de gestión de usuarios. Implmentación del sistema de gestión de usuarios Aunque puede que el orden no sea el más correcto, se empezó por la implementación del sistema de usuarios debido a la baja experiencia con Flask. La creación de un sistema de usuarios es una tarea básica en todos los sistemas web y que involucra muchos componentes del sistema por lo que empezar por esta tarea ayudará a la familiarización con el framework mediante diferentes tutoriales. Un sistema de gestión de usuarios implica persistencia de cara a los datos de dichos usuarios, es por ello que en primer lugar se debe investigar sobre como dotar de persistencia a una aplicación web basada en Flask. Flask, como ya se ha comentado, es un microframework y la mayor parte de las utilidades extras como por ejemplo la persistencia las proporciona a través de los llamados plugins. En este caso, un plugin que resuelve muy bien el problema de la persistencia es Flask-SqlAlchemy. Flask-SqlAlchemy es una adaptación de SqlAlchemy para Flask. SqlAlchemy es un ORM bastante maduro. Con este ORM podremos realizar todas las acciones requeridas para este sistema por lo que se trabajará con él. El primer paso para instalar este plugin es descargarlo mediante el gestor de paquetes «pip», seguidamente únicamente tendremos que importar el módulo y ya estaremos listos para empezar. SqlAlchemy soporta numerosos sistemas gestores de bases de datos, sin embargo, en este caso utilizaremos sqlite dado que para la carga que tendrá el sistema es suficiente. La mayoría de los plugins en Flask requieren de una configuración inicial, dicha configuración se realiza en el fichero «config.py» aunque no es necesario que se realice en este fichero. En el Listado 5.23 se puede ver la configuración final de la aplicación. En este caso, nos interesan las líneas que empiezan por SQLALCHEMY. La configuración básica requiere que la variable SQLALCHEMY_DATABASE_URI sea una uri bien formada para cada uno de 155
los conectores con los sistemas gestores de bases de datos, en este caso se hace referencia a la base de datos app.db. 1 2
import os
5 6
#SQLALCHEMY_ECHO = True WTF_CSRF_ENABLED = True SECRET_KEY = ’secret_key’
7 8 9
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = ’sqlite:///’ + os.path.join(basedir, ’app.db’) SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, ’db_repository’)
Listado 5.23: Fichero de configuración para Flask Una vez configurada la variable que determina la dirección de la base de datos, se debe registrar el plugin dentro de la aplicación Flask. Esto, se realiza en el fichero «__init__.py». Este fichero es el encargado de indicar a python que el directorio donde se encuentra es un módulo. Este fichero se carga cuando se realiza alguna acción como un import sobre dicho directorio. En el Listado 5.24 se puede ver el código correspondiente a este fichero. 1 2
from flask import Flask
4 5
app = Flask(__name__, static_url_path=’’) app.config.from_object(’config’)
7
db = SQLAlchemy(app)
9
from app import models, routes
from flask.ext.sqlalchemy import SQLAlchemy
Listado 5.24: Fichero «__init__.py» De este fichero debemos fijarnos en las primeras líneas que nos recordarán al ejemplo inicial. En las dos primer líneas importamos tanto la clase base «Flask» como el módulo «SQLAlchemy». Seguidamente se instancia una aplicación Flask y se configura mediante el metodo config() indicando el fichero donde se almacena dicha configuración. Por último, se instancia el plugin dentro de la aplicación y al final del código se importan los modelos y las rutas8 . Una vez que se tiene instanciado el plugin para la gestión de la persistencia, ya se puede empezar a crear las primeras tablas. Gracias a los ORM, en los últimos años cada vez se ha utilizado menos el lenguaje SQL. Esto no quiere decir que los sistemas ORM vayan a reemplazar las consultas puras SQL, simplemente que en muchas aplicaciones se ha conseguido evitar el uso de SQL a solo un par de consultas en casos estrictamente necesario agilizando el proceso de codificación. 8
Más adelante se verá qué hace esta última línea
156
Para crear un modelo «convertible» por el ORM debemos, en primer lugar, importar la clase base «db» que se encuentra dentro del paquete «app», que es la carpeta que contiene el fichero «__init.py__». Una vez importado, se creará una clase, en nuestro caso la clase «User», con cada uno de sus atributos (se traducirán a columnas). En el Listado 5.25 se puede ver un ejemplo para la clase «User». 1 2
from flask.ext.sqlalchemy import SQLAlchemy from werkzeug import generate_password_hash, check_password_hash
3
from app import db
5 6 7 8
class User(db.Model): dni = db.Column(db.Text, unique=True, primary_key=True) email = db.Column(db.String(150), unique=True) firstname = db.Column(db.String(100))
9 10 11
lastname = db.Column(db.String(100))
13 14
def __init__(self, dni, email, firstname, lastname, pwdhash):
15 16 17 18 19 21 22 24 25 26
pwdhash = db.Column(db.String(54)) log_messages = db.relationship(’LogMessage’, backref=’user’, lazy=’dynamic’)
"""User constructor """ self.dni = dni self.email = email self.firstname = firstname self.lastname = lastname if pwdhash != None: self.set_password(pwdhash) def set_password(self, password): """Generate hash password from plain password
27
""" self.pwdhash = generate_password_hash(password)
29 30
def check_password_hash(self, password): return check_password_hash(self.pwdhash, password)
Listado 5.25: Fichero «models.py», modelo User Como se puede observar, además de importar esta clase, también se importan otros métodos del paquete werkzeug los cuales son útiles para la gestión de las contraseñas cifradas. Un usuario tiene un dni, email, nombre, apellidos, hash, y un conjunto de mensajes que no serán explicados todavía. Las columnas se definen como propiedades de tipo Column de la clase y esta clase debe derivar de la clase «db.Model». Existen diversos tipos de datos que pueden ser consultados en la documentación oficial. Por último, se añaden dos métodos que nos permitirán comprobar que la clave insertada es la correcta y por otro lado nos permitirá cifrar dicha contraseña de tal manera que en la base de datos se guarden los datos encriptados. Para generar la tabla SQL a partir de este modelo debemos acceder a una sesión interactiva de python y cargar el fichero «__init__.py». Una vez cargado el fichero automáticamente 157
se configurará la base de datos y estaremos en disposición de utilizar el objeto db que fue instanciado en el fichero de inicialización. El objeto db tiene un método llamado create_all() que permite crear todos los implementados, en este caso el modelo «User». Una vez invocado dicho método si accedemos a la base de datos podremos comprobar que efectivamente se ha creado una tabla «User» con los campos especificados. El siguiente paso ahora que tenemos implementados el modelo de usuario será el de crear unos formularios para registrarse y acceder al sistema. Empezaremos por explicar el proceso de creación de un formulario de registro y los otros se darán por explicado debido a que el proceso es prácticamente el mismo. En primer lugar, para organizar la aplicación se creará un fichero llamado «routes.py» el cual contendrá todos los métodos «callback» de nuestro servicio web. El fichero routes se irá completando a lo largo del proyecto con todos los servicios a cada una de las url que inserta el usuario. En primer lugar daremos soporte para la acción de registrar, tal y como dijimos anteriormente. En el Listado 5.26 se puede ver la implementación de este método. 1 2
@app.route("/signup", methods=[’GET’, ’POST’]) def signup():
4
form = SignupForm()
6 7 8
if request.method == ’GET’: return render_template(’signup.html’, form=form)
9 10 11 12 13 14 15 16
else: if form.validate() == False: return render_template(’signup.html’, form=form) else: newuser = User(form.dni.data.lower(), form.email.data.lower(), form.firstname.data.lower(), form.lastname.data.title(), form.password.data)
18 19
db.session.add(newuser)
21 22
session[’email’] = newuser.email
24
return redirect(url_for(’index’))
db.session.commit()
g.user = newuser
Listado 5.26: Fichero «routes.py», ruta de registro A continuación se pasará a describir el Listado 5.26. En primer lugar se crea una variable u objeto llamado form. Esto, como veremos más adelante es un formulario que se crea a partir de un plugin para Flask. Seguidamente se comprueba que tipo de petición ha realizado el cliente. Si la petición es de tipo GET, entonces el usuario ha ingresado a la página por medio del navegador. No desde un formulario. Si el usuario accede desde el navegador entonces 158
renderizamos un template y le mandamos a Jinja 2 el formulario anteriormente creado. Si por el contrario accedemos por POST, entonces creamos un nuevo usuario con los datos obtenidos del formulario, añadimos el usuario a la base de datos y guardamos los cambios. Por último este usuario se añade a la sesión del servidor y se redirige mediante el método redirect() a la ruta que tenga asignada el método index. En el Listado 5.26 ha entrado en juego los formularios. Flask no tiene un soporte nativo para la creación de formularios, sin embargo tiene un plugin llamado WTF-Forms que permite simplificar la labor de gestión de formularios. En el Listado 5.27 se puede ver la implementación de un formulario mediante WTF-Forms. 1
class SignupForm(Form):
3
dni = TextField("Dni", [validators.Required("Debe ingresar un DNI")])
4 5 6 7 8
email = TextField("Email", [validators.Required("Debe ingresar un email"), validators.Email("Debe ingresar un email \ correcto")]) firstname = TextField("Nombre", [validators.Required("Debe ingresar el \ nombre real")])
9 10 11 12
lastname = TextField("Apellidos", [validators.Required("Debe ingresar los \
14
submit = SubmitField("Registrar")
16 17
def __init__(self, *args, **kwargs): Form.__init__(self, *args, **kwargs)
19 20
def validate(self):
21
apellidos")]) password = PasswordField("Contrasenia", [validators.Required("Debe ingresar \ una contrasenia")])
if not Form.validate(self): return False
23
user = User.query.filter_by(email=self.email.data.lower()).first()
25 26
if user:
27
self.email.errors.append("Este email ya esta en uso") return False
29
user = None
31
user = User.query.filter_by(dni=self.dni.data.lower()).first()
33 34 35
if user:
37
return True
self.dni.errors.append("Este DNI ya ha sido registrado") return False
Listado 5.27: Fichero «routes.py», ruta de registro En el Listado 5.27 se puede ver cómo el modo de crear un formulario es muy similar al modo de crear un modelo. En primer lugar, se hereda de la clase «Form». Una vez here159
dada de dicha clase únicamente tenemos que definir como atributos de clase cada uno de los campos que se renderizarán como parte del formulario. Por ejemplo, el campo dni es un campo de tipo texto que tiene una etiqueta con el texto «dni» y además tiene asignado un validador el cual será comprobado en el proceso validate(). Además de los métodos de validación normales (validator), también se pueden añadir nuestros propios métodos de validación como el que se muestra en el código donde se comprueba que no se existe un usuario con ese mismo dni o email. WTF-Forms simplifica mucho la labor de creación, validación y renderización de formularios. Una vez que se ha entendido este componente podemos volver al Listado 5.26 aquí se puede comprobar cómo se valida el formulario con el método valida definido en el código del formulario. El último componente que queda por explicar es el template. En el Listado 5.28 se puede revisar el código html implementado. Este código nos servirá para aprender la mayoría de conceptos de Jinja 2. En primer lugar vemos un bloque nuevo llamado «extends». Este tipo de construcción permite copiar y pegar un código que se toma como base para varios templates de modo que no sea necesario reescribir el mismo código multiples veces. En este caso en el fichero «base.html» se incluye el header. Siguiendo las líneas de código del template, en la siguiente línea se define un bloque de contenido mediante la palabra «block» esto permite que en los templates genéricos como por ejemplo el template base se incluyan bloques según su nombre, es decir, podemos agrupar partes html para luego pegarlas donde mejor nos convenga. Los errores que se generan por los validators se almacenan en una lista dentro del formulario y del atributo determinado. Por ejemplo, los errores para el nombre están dentro de form.firstname.errors. Para recorrer una lista con Jinja 2 se utiliza el bloque de código que se puede ver más abajo de la definición del bloque div. Por último, wtf-forms proporciona dos atributos dentro de cada uno de los atributos generados en el clase del formulario. Por un lado tenemos la etiqueta que se accede por atributo.label y el propio control del formulario que se accede mediante el nombre del control sin nada más. En el Listado 5.28 se puede leer el código donde se instancia lo explicado. Por otra parte, un punto importante dentro de los formularios wtf-forms es el hecho de que proporcionan protección contra Cross-Site Request Forgery (CSRF) [hac08] mediante la etiqueta form.hidden_tag(). 1
{ % extends "base.html" %}
3 4 5 6
{ % block content %}
7 8 9
{ % for message in form.firstname.errors %} × {{ message }}
160
10 11 12 13 14 15
{ % endfor %} {{ form.hidden_tag() }}
16 17 18 19
21
22 23 24 26 27 28 29
{{ form.dni.label }} {{ form.dni(class="form-control") }}
{{ form.firstname.label }} {{ form.firstname(class="form-control") }} {{ form.lastname.label }} {{ form.lastname(class="form-control") }}
31 32 33
34
36 37 38 39
40 41 42 43 44 45
{{ form.email.label }} {{ form.email(class="form-control") }}
{{ form.password.label }} {{ form.password(class="form-control") }} {{ form.submit(class="btn btn-primary") }} { % endblock %}
Listado 5.28: Template para la renderización del formulario Como resultado de todo este código, se tendrá un sistema como el de la Figura 5.58 pero sin estilo. La aplicación del estilo se explicará más adelante. Como resultado de esta fase de implementación se tiene un sistema de usuarios como el mostrado en la Figura 5.58 el cual es completamente funcional y permite discernir entre usuarios autorizados y no autorizados. En esta fase solo se ha mostrado el proceso de creación del formulario de registro, no obstante los demás formularios comparten la mayoría de características por lo que no se incluirán en el documento.
161
Figura 5.58: Sistema de registro realizado con Flask
Implementación del sistema de gestión de raseras y procesos En esta fase de la implementación se cubrirá todo el proceso de creación del módulo para gestionar las raseras y los procesos de la fábrica. Antes de empezar a implementar es importante que el lector tenga claro qué es un proceso y qué es una rasera dentro de la aplicación. Tal y como se nombró anteriormente, la harinera está dividida en varios procesos productivos. Cada proceso tiene una finalidad concreta. Por ejemplo, el proceso de lavado tiene la finalidad de limpiar el trigo de piedras y otras sustancias que se hayan podido añadir en el proceso de carga. En algunos de estos procesos hay silos los cuales están controlados por las raseras que estamos automatizando, luego una rasera pertenece a un proceso y un proceso puede tener muchas raseras. Como el lector habrá podido observar estamos ante una relación «uno a muchos», esta relación se le debe indicar al ORM. En el Listado 5.29 se puede ver un extracto del código donde entra en juego esta relación. 1 2 3 4 5
class Process(db.Model): process_id = db.Column(db.Integer, unique=True, primary_key=True) process_name = db.Column(db.Text)
7 8
class Rasera(db.Model): global_number = db.Column(db.Integer, primary_key=True)
raseras = db.relationship(’Rasera’, backref=’process’, lazy=’dynamic’) log_messages = db.relationship(’LogMessage’, backref="process", lazy=’dynamic’)
162
9 10 11 12
slave_id = db.Column(db.Integer, db.ForeignKey(’slave.global_number’), primary_key=True) process_id = db.Column(db.Integer, db.ForeignKey(’process.process_id’)) request_position = db.Column(db.Integer)
Listado 5.29: Extracto de código donde se pueden ver relaciones Empezaremos por la clase «Process». En esta clase se pueden ver diferentes atributos, sin embargo el que más nos importa en este caso es el atributo raseras. Este atributo es de tipo db.relationship(). En este caso la relación hace referencia a la clase «Rasera» (primer argumento) y además de añadir este atributo a la clase «Process», añadirá otro atributo mediante el parámetro backref con el nombre process. Por último, el parámetro lazy indica que tipo de atributo se quiere generar. Si se pone dynamic entonces raseras será una consulta SQL lista para ser ejecutada, es decir, en el momento de la creación del objeto Proccess únicamente se creará la consulta, no se ejecutará la misma. Por otro lado, se puede ver como en el caso de la clase «Rasera» crea un atributo llamado process_id el cual es de tipo db.Column() pero en este caso se indica que es una clave ajena mediante el parámetro db.ForeignKey(). De esta sencila forma ya tenemos creados los modelos y estamos listos para crear los formularios que permitan al usuario añadir raseras y procesos a la aplicación. El permitir al usuario, en este caso al operario, añadir raseras y procesos a la aplicación permite que el despliegue se realice de forma escalonada. Tal y como se hizo en la fase anterior, en esta fase se crearán los formularios mediante el uso de WTF-Forms. En el Listado 5.30 se pueden ver el código utilizado para este tipo de formulario. 1 2 3 4 5 6
class RaseraForm(NoCsrfForm): global_number = IntegerField("Numero global", validators=[validators.Required("Debes\ ingresar un numero global")]) process_id = IntegerField("Proceso", validators=[validators.required("Debes ingresar\ un proceso")]) slave_id = IntegerField("Esclavo", validators=[validators.required("Debes ingresar un esclavo") ])
8 9 10
class GlobalRaseraForm(Form):
12 13 14 15 16
class ProcessForm(Form): process_id = IntegerField("Numero global del proceso",
17
raseras = FieldList(FormField(RaseraForm, default=lambda: Rasera(1,1,1))) submit = SubmitField("Enviar")
[validators.Required("Debes ingresar\ un numero de proceso")]) raseras = FieldList(FormField(RaseraForm, default=lambda: Rasera(1,1,1))) submit = SubmitField("Enviar")
Listado 5.30: Extracto de código con los formularios para la creación y eliminación de raseras y procesos
163
Como el lector podrá comprobar existen dos formularios, por un lado el formulario RaseraForm el cual contiene todos los controles para cada uno de los atributos del modelo Rasera. Por otro lado, está el formulario GlobalRaseraForm. Este formulario es el encargado de coger un formulario y utilizarlo como parte de su propio formulario, es decir, es un formulario que contiene dentro formularios. Para realizar este tipo de construcción debemos crear un atributo de tipo FieldList(). WTF-Forms obliga a que al menos haya un subformulario, por eso se añade al constructor un FormField() con una rasera genérica. En el caso del formulario ProcessForm ocurre exactamente lo mismo. Si el lector vuelve a revisar el Listado 5.29 podrá observar que efectivamente un proceso tiene, entre otras cosas un identificador de proceso y un atributo llamado raseras el cual es una lista con todas las raseras que pertenecen a este proceso. Es por ello que en este formulario, el atributo raseras (el nombre no es casual, debe coincidir) es de tipo FieldList() dado que instanciará un formulario RaseraForm por cada una de las raseras que existan dentro de la lista de raseras del objeto Process. El proceso es un poco complejo sin embargo una vez se razona con calma se ve que efectivamente la organización es bastante lógica. Del mismo modo a como se ha hecho con otros formularios, en este caso debemos crear el manejador de rutas para acceder a este formulario y añadir la lógica de negocio. En el Listado 5.31 se puede ver cómo se instancian los formularios creados anteriormente. En primer lugar debemos fijarnos en los decoradores app.route. Estos decoradores tienen una característica que los anteriores no tenían como por ejemplo que se pueden agrupar varias rutas para un mismo método. Además, podemos observar que mediante el parámetro methods se puede indicar que tipo de métodos HyperText Transfer Protocol (HTTP) permitirá esta ruta. En este caso se permiten tanto los métodos POST como GET. El método POST será el utilizado por el formulario para mandar su respuesta y el método GET será el utilizado por el navegador para acceder al formulario (aunque también se podrían mandar los datos del formulario por GET). Además, se puede observar como la ruta tiene un parámetro llamado process. Al ir entre símbolos angulares Flask sabrá que es un parámetro y lo pasará como parámetro a la función, es por ello que la función tiene un parámetro con el mismo nombre. Cuando se accede a list_raseras pueden ocurrir dos cosas, si el proceso del cual se quieren recibir raseras no existen Flask nos redirigirá al método list_process donde podremos consultar que procesos existen e incluso añadir nuevos procesos. Por otro lado, si existe el proceso indicado en la url, entonces se deberá consultar todas las raseras. Como se puede observar, a la hora de crear el formulario, se pasa un parámetro llamado obj que le servirá a WTF-Forms para rellenar el formulario con los datos del objeto pasado. Por último, si se pulsa al botón enviar y se validan los datos, se rellena el objeto process_query mediante el método populate_obj y se envían los cambios a la base de datos. Como se puede observar el uso de WTF-Forms simplifica muchísimo la labor de verificación y mantenimiento de los formularios dado que él mismo se encarga de gestionar la modificación de los objetos a los 164
que hace referencia. 1 2 3 4 5 6 7 8
@app.route("/list_raseras") @app.route("/list_raseras/", methods=[’GET’, ’POST’]) def list_raseras(process=-1): process_query = Process.query.filter_by(process_id=int(process)).first() if process_query is None: flash("El proceso con id %s no existe en la base de datos" % (process), "error") return redirect(url_for(’list_process’))
10 11 12 13 14
raseras = process_query.raseras.all()
15
por defecto (no utilizar)")
17
form = ProcessForm(obj=process_query)
19 20
if form.validate_on_submit(): form.populate_obj(process_query)
21 22 24
if len(raseras) == 0: process_query.raseras = [Rasera(global_number=-1, slave=-1, process_id=-1)] flash("El proceso no contiene ninguna rasera, se ha generado una rasera\
db.session.commit() flash("Cambios realizados") return render_template(’list_raseras_process.html’, form=form)
Listado 5.31: Lógica de negocio para la gestión de procesos y raseras Finalmente, como en los demás formularios, la última parte consiste en ver la parte correspondiente al template (Ver Listado 5.32). Al igual que en los demás template, se extiende del template base, además se crea un bloque de contenido que contiene (valga la redundancia) un formulario. El lector podrá observar como el modo de acceder a los controles es exactamente el mismo que el de otros formularios. La diferencia principal radica en el bucle «for» de Jinja que recorre cada una de las raseras dentro de la propiedad form.raseras. Esto nos devuelve otro objeto formulario el cual contiene todos los atributos definidos para el formulario hijo. En la Figura 5.59 se puede ver el aspecto final de este formulario, la visualización del estado final ayudará a entender el código explicado anteriormente. Como se puede observar, el formulario tiene datos ya ingresados, estos datos los «rellena» de forma automática WTF-Forms cuando se crea el formulario con el parámetro obj. Además, el formulario tiene la capacidad de ser dinámico, es decir, crecer o reducirse según se desee. Para esto ha sido necesario la intervención de código javascript. En el Listado 5.33 se puede ver un extracto de código donde se gestiona este formulario. Este código no será explicado para no alargar de forma innecesaria el documento pero a modo de resumen lo único que hace es copiar elemento a elemento cambiando los identificadores. En la Figura 5.59 se han resaltado algunos aspectos de la imagen. En la parte superior se ha resaltado la Uniform Resource Locator (URL) la cual contiene el número de proceso que será pasado como parámetro a la función. También se puede ver cómo el formulario se rellena con el número de proceso correspondiente al 165
número ingresado en la URL. 1 2
{ % extends ’base.html’ %}
3 4 5 6 7 8
10 11 12 13 14 15 16
{ % block content %} {{ form.process_id.label }} {{ form.process_id(class="form-control") }}
Aniadir rasera
18 19 20
Numero global |
21 22 23 24 25 26
Esclavo | Numero de proceso | |
{ % for rasera in form.raseras %} {{ rasera.global_number(class="form-control") }} | {{ rasera.slave_id(class="form-control") }} |
27 28 29 30 31 32
{{ rasera.process_id(class="form-control") }} | Eliminar
33 34 35 36 37 38 39 40 41 42 44 45 46 47
|
{ % endfor %}
{{ form.hidden_tag() }} {{ form.submit(class="btn btn-primary") }} { % endblock %}
Listado 5.32: Template para la renderización de formularios anidados
1 2 3
$(function() { $("div[data-toggle=fieldset]").each(function() { var $this = $(this);
166
//Add new entry
5 6 7 8 9
$this.find("button[data-toggle=fieldset-add-row]").click(function() { var target = $($(this).data("target")) console.log(target); var oldrow = target.find("[data-toggle=fieldset-entry]:last"); var row = oldrow.clone(true, true);
10 11 12 13 14 15
console.log(row.find(":input")[0]); var elem_id = row.find(":input")[0].id; var elem_num = parseInt(elem_id.replace(/.*-(\d{1,4})-.*/m, ’$1’)) + 1; row.attr(’data-id’, elem_num); row.find(":input").each(function() {
16 17
console.log(this);
18 19 20
$(this).attr(’name’, id).attr(’id’, id).val(’’).removeAttr("checked");
var id = $(this).attr(’id’).replace(’-’ + (elem_num - 1) + ’-’, ’-’ + (elem_num) + ’ -’); }); oldrow.after(row); }); //End add new entry
21
//Remove row
23 24 25 26 27 28 29 30 31
$this.find("button[data-toggle=fieldset-remove-row]").click(function() { if($this.find("[data-toggle=fieldset-entry]").length > 1) { var thisRow = $(this).closest("[data-toggle=fieldset-entry]"); thisRow.remove(); } }); //End remove row }); });
Listado 5.33: Código javascript para la creación de nuevas filas en el formulario
Figura 5.59: Captura del formulario web para añadir raseras
Como resultado de esta fase de implementación se ha explicado como desarrollar formularios avanzados en Flask. Esta tarea requirió de bastante tiempo hasta que se pudo asimilar todos los conceptos necesarios. En la Figura 5.60 se puede ver un conjunto de imágenes con los diferentes formularios para el control de raseras y procesos creados. No se han explicado todos debido a la duplicidad de conceptos.
167
(a) Formularios de gestión de esclavos, permite la creación, modificación y eliminación de esclavos
(b) Formulario de gestión de procesos, permite la creación, modificación y eliminación de procesos
(c) Formulario de gestión de raseras, permite la creación y eliminación de raseras
Figura 5.60: Formularios de gestión implementados
Implementación de la comunicación con los esclavos La comunicación con los esclavos es la parte clave del sistema de gestión, si este falla entonces fallará el sistema completo dado que el operario no podrá gestionar el bus. El primer paso para establecer el módulo de comunicaciones ha sido la de crear una clase llamada «Arduino» que nos ayudará a realizar determinadas operaciones como escribir o leer del bus. En el Listado 5.34 se puede ver el código correspondiente a la definición de dicha clase. 1 2 3 4 5 6 7
class Arduino: def __init__(self, port, baudrate, lock): try: self.arduino = serial.Serial(port, baudrate=baudrate) self.lock = lock except ValueError as ve: print("Error creating arduino object: {}".format(ve))
168
8 9 11 13 14 15 16 17 19 20 21 22 23 25 26 27 28 29 30 31
except serial.SerialException as se: print("Error creating arduino object: {}".format(se)) self.is_connected = self.arduino.is_open def connect(self): self.lock.acquire() if self.is_connected == False: self.arduino.open() self.lock.release() def disconnect(self): self.lock.acquire() if self.is_connected == True: self.arduino.close() self.lock.release() def receive_data(self, size): data = 0 try: self.lock.acquire() data = self.arduino.read(size) except: pass
32 33
finally:
35
return data
37 38 39 40 41 42 43 44 45 46 47
self.lock.release()
def send_data(self, data): data = data.encode() try: self.lock.acquire() a = self.arduino.write(data) self.arduino.flush() except serial.SerialTimeoutException as te: print("Error writing {}".format(te)) finally: print("Release") self.lock.release()
Listado 5.34: Código para la definición de la clase Arduino La clase tiene dos atributos principales, un objeto pySerial y un semáforo que será utilizado para manejar la concurrencia tal y como se verá más adelante. Además de los atributos, la clase proporciona una serie de métodos que son de mucha utilidad a la hora de encapsular el comportamiento de este componente de cara a la aplicación de gestión. El método connect() y disconnect() se explican por sí solos, sin embargo los métodos receive_data() y send_data() involucran algún concepto que serán revisados a continuación. En primer lugar, el método receive_data() permite leer del bus el número de datos que se indique en el parámetro size. Es importante tener en cuenta que estamos en un entorno concurrente (como se verá más adelante) por lo que antes de acceder al bus se debe comprobar que no haya otro proceso accediendo al mismo. Para ello se utiliza el método acquire() del 169
semáforo que comprobará que dicho semáforo no ha sido obtenido todavía. Por otro lado, hay que tener en cuenta que la lectura es bloqueante por lo que el hilo o proceso se mantendrá bloqueado hasta que se lea el número de bytes indicados. El método send_data() por su parte realiza el mismo procedimiento con la diferencia que en este caso se utiliza el método flush(), esto es debido a que pySerial por defecto no envía tras realizar la operación write(), espera hasta que hay suficientes datos como para hacer una transferencia grande (buffering). Una vez que está definida la clase, el siguiente paso consiste únicamente en crear diferentes métodos en el fichero «routes.py». En este punto únicamente se verá la implementación de un método auxiliar de tal modo que el lector pueda comprender cuáles son los conceptos que subyacen sobre esa acción. En este caso veremos la acción de conectar a la fábrica lo cual es muy sencillo. En primer lugar creamos el método dentro del fichero «routes.py», luego se creará un enlace en el template y cuando se pulse sobre dicho enlace se llamará al método definido. En el Listado 5.35 se puede ver el código del método de conexión. Como se puede observar, en primer lugar se comprueba si el objeto arduino, el cual es un objeto global, existe y si está conectado, si ocurre eso entonces se muestra un mensaje avisando al usuario de lo ocurrido. Para avisar al usuario se utiliza el sistema flash que permitirá pasar a Jinja 2 una serie de mensajes que solo se muestran la primera vez que se recargue la página, por lo que para mensajes temporales como este es muy adecuado. Si no está conectado entonces se procede a crear el objeto en el puerto correspondiente al módulo conectado al ordenador y con el semáforo global. Si existe algún fallo en el proceso se le notificará al usuario. Como el lector habrá podido observar el procedimiento es muy sencillo si se mantiene la funcionalidad bien modularizada. 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 19
@app.route("/connect") def connect(): global arduino if arduino is not None and arduino.is_connected: flash("La fabrica ya esta conectada") else: try: arduino = Arduino("/dev/ttyACM0", 115200, arduino_lock) arduino.connect() except: flash("Error al abrir la fabrica, esto puede ser debido a un\ cambio de puerto serie", ’error’) if arduino is None: flash("Error al conectar a la fabrica", ’error’) else: flash("Arduino conectado") return redirect(url_for(’index’))
Listado 5.35: Código para conectarse al bus de comunicaciones
170
El siguiente paso ahora que sabemos cómo conectar y desconectar la fábrica, consiste en mandar mensajes del protocolo bien construidos. Para simplificar la labor de gestionar este protocolo, se ha creado una pequeña librería que permite mandar mensajes únicamente llamando a unos métodos sencillos. En el Listado 5.36 se puede ver un extracto de la librería diseñada. 1 2
def parse_header(string_data): byte_start = string_data[0]
3 4 5 6
initiator = string_data[1] box_number = string_data[2:4]
8
data = {’start’: byte_start, ’initiator’: initiator, ’slave’: box_number, ’rasera’: rasera_number, ’command’: command_number}
9 11 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 42 43 44 45 46 47 48 49
rasera_number = string_data[4:6] command_number = string_data[6:8]
return data def generate_header(initiator, slave, rasera, command, broadcast=False): if not broadcast: return (str(start) + str(initiators[initiator]) + str(slave).zfill(2) + str(rasera).zfill(2) + str(commands[command])) else: return (str(start) + str(initiators[initiator]) + str(slave).zfill(2) + str(99).zfill(2) + str(commands[command])) def parse_payload_send_position(string_data, broadcast=False): payload_string = string_data[8:] rasera_info = {} if broadcast == False: position = payload_string[0:3] rasera_info = {’position’: position} else: while True: rasera_number = payload_string[0:2] position = payload_string[2:5] payload_string = payload_string[5:] rasera_info[str(rasera_number)] = {’position’: position} if(len(payload_string) == 0): break payload = {"payload":rasera_info} return payload def send_position(controller, slave, rasera, position, broadcast=False): header = None payload = None packet = None if not broadcast: header = generate_header(initiator=’master’, slave=slave, rasera=rasera, command="send_position") payload = generate_payload_send_position(position, rasera=rasera, broadcast=False) else: header = generate_header(initiator=’master’, slave=slave, rasera=99, command="send_position")
171
50 51 52 53
payload = generate_payload_send_position(position, rasera=rasera, broadcast=True) packet = header+payload return packet
Listado 5.36: Librería para gestionar el protocolo de comunicaciones Por ejemplo, mediante el método send_position() se podría enviar una trama con el payload correspondiente para mandar mover el cilindro de una o varias raseras a una posición dada. Ahora que ya está creada la librería y tenemos conexión con el esclavo, únicamente tenemos que proporcionar una interfaz para enviar dichos comandos. La creación de dicha interface se verá en la siguiente fase de implementación. Implementación de la interfaz para enviar posiciones La última fase de implementación de esta iteración consistirá en implementar la pantalla principal que le servirá al operario para manejar y monitorizar (esto se implementará en la segunda iteración) los procesos productivos. En la Figura 5.61 se puede ver el aspecto final de esta pantalla de control. La parte que a nosotros nos interesa para esta fase de implementación es la parte de envío de posiciones identificado en la figura como «control».
Figura 5.61: Página principal de la aplicación web
El lector probablemente ya tenga una idea de cómo realizar este apartado de la web sin embargo, varía bastante con respecto a los otros formularios realizados. En primer lugar, no 172
se ha implementado como un formulario si no como una tabla. Además las llamadas se hacen de forma asíncrona y no de forma síncrona como es el caso de los formularios. Para empezar, describiremos el método implementado en el fichero «routes.py» que gestiona las peticiones de cambio de posición. En el Listado 5.37 se puede ver el código mencionado. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
@app.route("/send-position", methods=[’GET’,’POST’]) def send_position(): rasera = Rasera.query.get(int(request.args.get("rasera"))) position = int(request.args.get("position")) is_ok = False; u = User.query.filter_by(email=session[’email’]).first() l = LogMessage("Movimiento rasera {} a la posicion {}".format(rasera.global_number, position), datetime.utcnow(), rasera.process_id, u.dni) db.session.add(l) while is_ok is False: frame = rasera.update_position(position) arduino.send_data(frame) data = arduino.receive_data(11) db.session.add(rasera) db.session.commit() print("Datos recibidos "+ data.decode()) status, ack = protocol.parse_ack("send_position", data.decode() ,frame, False) is_ok = status return "true" \end{position}
Listado 5.37: Método para gestionar la petición de cambio de posición Como se puede observar, en el Listado 5.37, lo primero que se realiza es hacer una consulta a la base de datos para obtener todos los datos de la rasera. Una vez se obtiene la rasera se entra en un bucle while que finalizará cuando el envío se haya realizado de forma satisfactoria. Dentro del bucle se genera el frame mediante un método auxiliar incorporado dentro del objeto Rasera para más tarde enviarlo desde el método send_data() del objeto arduino. Seguidamente se espera la respuesta y se comprueba el resultado de ack. Si todo ha salido bien entonces se sale del bucle, de lo contrario se vuelve a intentar de nuevo. La manera en que se ha diseñado la invocación de este método y de muchos otros ha sido mediante ajax [aja08]. Mediante una llamada asíncrona ajax, el usuario no tiene que volver a hacer una petición al servidor para recargar toda la página web, por el contrario únicamente carga la parte de la web necesaria o realiza una llamada a un método como ocurre ahora. Para conseguir realizar esta llamada mediante ajax, el primer paso consiste en asociar el click del botón «enviar» que se encuentra al lado de cada «slider» con un manejador que sea capaz de generar esta llamada. En el Listado 5.38 se puede ver el código que realiza esta acción. Hay muchas maneras de realizar esto, sin embargo se ha optado por esta concreta. 1
$(’.btn-send-position’).on("click", send_position);
Listado 5.38: Código para capturar el click de un elemento
173
Como se puede observar en el Listado 5.38 se busca todos los elementos que tengan la clase HTML «btn-send-position» y se les aplica un método callback cuando se haga click sobre ellos. En este caso la función encargada de gestionar esta pulsación es send_position(). En el Listado 5.39 se puede ver la implementación de esta función. En primer lugar se elimina la acción por defecto aunque en este caso no tiene ninguna acción predefinida. Seguidamente se captura el botón exacto, dentro de la clase que ha generado este evento. Una vez que tenemos los datos sobre dicho botón se obtiene la posición y la rasera asociada a ese botón. Con todos los datos calculados, se procede a realizar la llamada ajax. Para realizar las llamadas ajax se ha utilizado jQuery, esto se debe a que jQuery simplifica mucho determinadas acciones dentro de javascript como en este caso la invocación ajax [jq13]. La función ajax recibe un parámetro con pares clave-valor. En el parámetro url deberemos indicar la url que ingresamos en el fichero «routes.py». También se indica el tipo de petición y los datos que se enviarán. Por último debemos proporcionar un callback para el caso en que todo salga bien, es decir, para el caso success. En este caso mandaremos un aviso visual al operario de modo que este pueda saber que todo ha salido bien. 1 2 3 4 5 6
function send_position(event){ event.preventDefault(); id = event.target.id; res = id.split("-"); rasera_a = res[1]; idfader = "#fader-".concat(rasera_a); position = $(’#fader-’.concat(rasera_a)).val();
7 8 9 10 11 12
id_row = "#row-table-action-rasera-".concat(rasera_a) $.ajax({ url: ’send-position’, type: ’GET’, data: {’rasera’:rasera_a, ’position’:position}, success : function (response){
13 14 15 16 17 18
if(response == "true"){ $(id_row).addClass("success"); $(id_row).removeClass("danger"); id_position = "#position-".concat(rasera_a); $(id_position).text(position); }else{
19 20 21 22 23 24 25 26 27
$(id_row).removeClass("sucess"); $(id_row).addClass("danger"); id_position = "#position-".concat(rasera_a); $(id_position).text("error"); } } }); }
Listado 5.39: Función para realizar la petición ajax Con esto damos por finalizada la primera iteración, el cliente podrá ahora comprobar la funcionalidad de la aplicación gestionando procesos, raseras y esclavos y además podrá comprobar cómo se realizan peticiones a los esclavos. 174
Bucle de iteración, Iteración 1: Monitorización Requisitos o Restricciones En este caso no se describirá ningún requisito dado que no existe ningún requisito más que los definidos en la etapa de inicio. Decisiones de diseño La monitorización es un proceso muy importante a la hora de hacer un sistema de gestión. En función del prototipo, del tipo de medio físico, o incluso las condiciones ambientales, la monitorización estará sujeta a un tiempo más o menos reestrictivo. En esta iteración se tratará de implementar el sistema de monitorización de los diferentes procesos implementados. Para realizar esto existen varias maneras de proceder, a continuación se verán cada una de ellas: Polling controlado del lado del servidor: Mediante el polling controlado, el servidor comprueba las respuestas a peticiones de estado del bus. Cuando existe un número determinado de respuestas entonces el servidor envía esos datos al cliente. Este método reduce el número de datos y la sobrecarga sobre la red, sin embargo añade incertidumbre en el tiempo entre mensajes además de la carga añadida al servidor. Polling controlado del lado del cliente: En este modo, el cliente configura un temporizador tras el cual mandará una petición al servidor para enviar un determinado número de peticiones de estado el cual devolverá dichas respuestas al cliente. Este método ha sido muy utilizado desde la aparición de las llamadas asíncronas mediante ajax. Eventos del lado del servidor: El servidor lanza un hilo o proceso el cual se suscribe a un determinado evento, este evento podría ser la liberación de un semáforo. Una vez ocurre ese evento, el servidor manda un mensaje a cada uno de los clientes que se han suscrito a ese stream de datos. Este método no está soportado por todos los navegadores, el nombre técnico de este método de operación es «server-sent events» o SSE. En este caso se ha optado por la opción del polling del lado del cliente dado que los requisitos temporales no son muy estrictos y se simplifica el proceso de desarrollo además de aumentar la compatibilidad dado que todos los navegadores soportan esta tecnología. Implementación Implementación del proceso de monitorización En la Figura 5.61 veíamos como era la pantalla principal que vería el operario, en este caso se procederá a implementar la parte de monitorización que era la parte que no se había explicado en el apartado anterior. Una vez creado el template con la forma básica en el que se van a representar los da175
tos, en forma de tabla, se procederá a la creación del servicio web que de soporte a estas peticiones. En el Listado 5.40 se puede ver el código que da soporte a las peticiones de refresco de datos de la aplicación web. Como se puede observar el código es muy sencillo. En primer lugar se hace una consulta a la base de datos para conocer todos los atributos del proceso del cual se quiere obtener actualizaciones. Una vez se tiene se genera una lista de frames para cada uno de los slave y seguidamente se realizan los envíos tras lo cual se recolectan los datos recibidos y se devuelven al cliente web. Para obtener los paquetes para cada uno de los slaves se hace uso de la librería creada en la iteración anterior y de un método auxiliar de la clase «Process». 1 2 3 4 5 6
@app.route("/status-process/", methods=[’GET’, ’POST’]) def status_process(): process = request.args.get("process") process = Process.query.get(int(process)) list_of_frames = process.get_status_of_slaves() frame = 0
7 8 9 10
for frame in list_of_frames: arduino.send_data(frame)
12
return Response(response = json.dumps(frame), mimetype="application/json")
data = arduino.receive_data(72).decode() frame = protocol.parse_check_state(data)
Listado 5.40: Función para realizar la petición ajax Del lado del cliente únicamente hay que añadir una llamada ajax y realizar un parser del código json devuelto por el servidor. La parte más compleja de la monitorización no radica en la comunicación con los diferentes esclavos ni en las llamadas ajax, lo más complejo está en la necesidad de un servidor multicliente. Las llamadas ajax se hacen de modo asíncrono mandando un mensaje al servidor. Si esa llamada tarda tiempo en ser procesada (como es el caso debido al bus de comunicaciones) entonces el usuario experimentará que el servidor no responde pudiendo llegar a causar situaciones que hagan que el sistema sea poco usable. En este momento surge la necesidad de utilizar un servidor multicliente. Existen muchas alternativas a la hora de utilizar servidores multicliente, a continuación se mostrará alguna de estas alternativas: Apache: Apache puede generar un pool de procesos de modo que cada petición es atendida por un proceso. Para que Apache funcione con las aplicaciones Flask se necesita de un mod llamado mod_wsgi, sin embargo no se ahondará en este concepto en este documento. Nginx: Nginx tiene un modo de funcionar completamente diferente a Apache. En Nginx se maneja el flujo de peticiones en lo que se llama un modelo basado en eventos asíncronos. Nginx está siendo utilizado de forma extendida estos últimos años sin 176
embargo para este proyecto añade una complejidad innecesaria debido a la poca carga del sistema.
Gunicorn: Gunicorn es un servidor wsgi HTTP creado para funcionar en unix. Gunicorn se puede configurar para funcionar en modo evenlet o greenlet que son vertientes modificadas del concepto de hilo. Gunicorn ha mostrado en muchas aplicaciones cierta inestabilidad por lo que no se utilizará en este diseño. El lector podría pensar que la opción más clara es Apache, sin embargo Apache basa su modelo en un pool de procesos. Los procesos tienen su propio espacio de memora y sus variables son completamente diferentes entre sí, es decir, el proceso que atienda al cliente «a» tendrá variables diferentes de las del cliente «b» que ha sido atendido por otro proceso. Es por ello que por ejemplo, el objeto Arduino el cual es global no se encontraría siempre en el mismo estado pues aunque el cliente es el mismo, el proceso no lo es. Una de las maneras de solucionar esta situación es mediante la aplicación de un modelo sin estado. En los últimos años los servicios Representational State Transfer (REST) han ido ganando terreno a los antiguos modelos basado en el almacenamiento del estado en el servidor. En este caso, aplicar un modelo REST es bastante sencillo si no fuera porque tenemos un recurso físico que obligatoriamente tiene que ser compartido. Para solucionar este hecho, es decir, aislar el objeto Arduino de los diferentes procesos, existen varias alternativas. La primera y más inmediata sería la de no mantener activo el Arduino sin embargo esto generaría muchas conexiones y desconexiones por cada una de las peticiones que haría el cliente. El generar estas conexiones y desconexiones del bus puede no ser beneficioso sin embargo podría ser una posible opción. La siguiente opción consiste en aislar el objeto en un proceso que siempre estará activo e independiente del pool de procesos del servidor. De este modo las peticiones se harán hacia el proceso que tiene el objeto Arduino y este será el encargado de gestionar las comunicaciones. Esta aproximación se probó mediante algunos prototipos y aunque funcionó aumentaba mucho la complejidad del diseño por lo que se decidió dejar como trabajo futuro. La opción adoptada para este TFG ha sido la de utilizar el servidor de desarrollo pero con gestión de hilos. Los hilos comparten espacio de memoria por lo que la concurrencia se manejará por medio de semáforos[con14] tal y como se ha visto a lo largo del TFG. El servidor de producción es lo bastante potente para aguantar la carga que tendrá este sistema debido a que no habrá demasiados usuarios activos a la vez. Como resultado de esta «pequeña» iteración el cliente tiene una versión funcional del prototipo de tal manera que podrá testar los posibles fallos que aparecieran. 177
Bucle de iteración, Iteración 2: Aplicación de estilos Requisitos o Restricciones La única restricción que se deberá cumplir para esta iteración, además de las involucradas en las otras iteraciones del proyecto software, será la de realizar una interfaz responsive, de tal manera que se adapte a los diferentes tipo de pantallas. Además el diseño deberá ser usable de modo que el operario tarde poco tiempo en adaptarse a esta nueva filosofía de sistema de gestión. Mejoras realizadas, evolución del diseño En esta iteración se implementará un conjunto de hojas de estilos a la interfaz web de modo que el sistema de gestión se adapte a las diferentes pantallas de los dispositivos desde los que se pudiera llegar a acceder. Decisiones de diseño A día de hoy la mayoría de páginas web están utilizando Bootstrap con o sin modificar para diseñar su apartado estético. Bootstrap es un framework para la aplicación de estilos web responsive. La creación de un sitio web responsive, es decir, que se adapte a todo tipo de pantalla, requiere de muchas horas de diseño y depuración. Ante la negativa de los grandes navegadores de cumplir con la normativa para la aplicación de estilos, surgió la necesidad de un framework que permitiera a los diseñadores adaptarse a los diferentes navegadores y a los diferentes dispositivos desde los cuales se estaban accediendo a sus webs. Con la aparición de Bootstrap los tiempos de diseño se redujeron drásticamente y se incrementó notablemente la usabilidad e interoperabilidad. En esta interfaz web se utilizará Bootstrap como plantilla y framework para la aplicación de estilos dado que es un framework de software libre con una madurez muy alta [boo13]. Implementación Aplicación del estilos Esta iteración solo cuenta de una fase de implementación dado que la aplicación de estilos una vez se conoce el framework es una tarea bastante sencilla y que involucra muy pocas líneas de código, cosa que si se hiciera con un estilo propio no sería así. El primer paso para incorporar Bootstrap a nuestra aplicación web es la de descargar la última versión o por consiguiente obtener los enlaces al Content Delivery Network (CDN) de Boostrap. En este caso se optará por la opción de descargar la última versión e instalarla en nuestra aplicación web. La descarga permite que el servidor no esté conectado a Internet y por lo tanto que se reduzca la probabilidad de sufrir ataques de seguridad externos. Una vez descargado desde la página oficial, se deberá copiar los ficheros «.css» a la carpeta «static/css» y los ficheros acabados en «.js» a la carpeta «static/js». Es muy importante descargar 178
la última versión de jQuery dado que algunas funcionalidades de Bootstrap requieren de este plugin. Una vez descargados todos los ficheros, el siguiente paso consistirá en incluirlos en nuestro template base. Como el lector habrá podido observar, durante todos los ejemplos de templates, siempre se ha incorporado un fichero «base.html». Este fichero contiene, entre otras cosas, las instrucciones necesarias para cargar Bootstrap y jQuery a nuestra aplicación web. En el Listado 5.41 se puede observar un extracto del template «base.html» 1
2 3 4 5 6 7
9
Raseras 1.0
11 12
14 15 16
18 19
21 22
Listado 5.41: Head del template «base.html» Una vez incluido Bootstrap en el «head», lo único que resta es añadir cada uno de sus estilos a los formularios, tablas y controles. Debido a la longitud del documento así como la existencia en Internet de documentación sobre la aplicación de dichos estilos, en esta sección únicamente se mostrarán algunas imágenes donde se muestra la aplicación web completa. En la Figura 5.62 se puede ver la pantalla de acceso en formato móvil y formato escritorio. Esta página es bastante común en los sitios web dado que es uno de los estilos base de Bootstrap. La página que el operario visualiza nada más acceder, se puede ver en la Figura 5.63. Esta pantalla muestra todos los procesos que han sido registrados en la aplicación, si el operario pincha sobre uno de ellos pasará a la portada. La portada se puede ver en la Figura 5.64, esta portada será el lugar de trabajo principal del operario, desde ella podrá monitorizar, desde las tablas, cada uno de los silos. Además, en el centro se puede ver un dibujo. Este dibujo representa una línea de transporte en un sistema SCADA. Como trabajo futuro se añadirá soporte a la visualización gráfica de los procesos. Para añadir este soporte se han diseñados varios prototipos utilizando la librería snap la cual puede ser descargada desde el siguiente enlace: http://snapsvg.io/. Por otro lado, en la Figura 5.65 se puede observar co179
mo vería el operario la pantalla de configuración de procesos y por último en la Figura 5.66 como vería la pantalla de configuración de raseras. Tal y como el lector habrá podido observar, la aplicación de los estilos de Bootstrap permite crear un sitio web muy atractivo y usable. Aunque en esta fase no se ha explicado como aplicar cada uno de los estilos este proceso mediante el framework de Bootstrap se simplifica al añadir unas determinadas clases a los elementos HTML. Como resultado de esta iteración, el cliente recibe la aplicación de gestión completamente funcional y usable. El siguiente paso consistirá en la solución de los posibles fallos que se vayan descubriendo como resultado del uso por parte del cliente.
180
Características
Groov Box
Groov Server
Groov Build (sdk) Groov View (frontend) Groov Admin (configurador groov Box) Creador de interfaces Requiere plugins externos Interfaz web Diseño responsive HTTPS Certificado oficial Librería Drag and Drop Gestión de usuarios Jerarquía de páginas Gestor de logs Notificaciones de email y texto Hardware industrial
Sí Sí Sí
Sí Sí Sí
Sí No Sí Sí Sí Sí Sí Sí Si Sí Sí Sí
Dos interfaces de red
Sí
Notificaciones de email y texto Direccionamiento
Sí IPV4
Sí No Sí Sí Sí Sí Sí Sí Sí Sí Sí Depende del tipo de computador Depende del tipo de computador Sí IPV4/IPV6
Cuadro 5.1: Tabla comparativa de tecnologías groov. Fuente: http://groov.com/
181
(a) Formato escritorio
(b) Formato móvil 182
Figura 5.62: Pantalla de login
(a) Formato escritorio
(b) Formato móvil
Figura 5.63: Pantalla de inicio
183
(a) Formato escritorio
(b) Formato móvil
Figura 5.64: Pantalla de monitorización
184
(a) Formato escritorio
(b) Formato móvil
Figura 5.65: Pantalla desde donde se pueden gestionar los procesos
(a) Formato escritorio
(b) Formato móvil
Figura 5.66: Pantalla desde donde se pueden gestionar las raseras por cada proceso
185
Capítulo 6
Resultados
E
este capítulo se resumirán los resultados obtenidos en cada uno de los subproyectos en los que se divide el actual documento. El sistema no ha sido desplegado todavía en la Harinera debido a que para las fechas planteadas la Harinera se encontraba aplicando otra actualización de sus procesos productivos por lo que el sistema se desplegará más adelante en una de las líneas y se comprobará su funcionamiento en el entorno final. N
6.1 Proyecto hardware La plataforma hardware ha funcionado como se esperaba a falta de ser mandado a producir a una fábrica de PCB. El precio de cada una de las placas, para el caso de la fábrica «Eurocircuits», ronda los 30e más los componentes hardware que serán emplazados en la placa final. En la Figura 6.1 se puede ver el aspecto de la PCB finalizada.
Figura 6.1: PCB final en 3D
En el desarrollo final de esta placa se han implementado todas las soluciones referentes a los problemas de aislamiento de comunicación y de potencia. Además se ha conseguido desarrollar un diseño específico para este problema con un coste bastante reducido. 187
6.2 Proyecto firmware El proyecto firmware ha finalizado siendo un software estable y seguro que cumple con todas las funcionalidades requeridas de forma segura, fiable y escalable. La aplicación de la orientación a objetos en el desarrollo de sistemas embebidos ha ido cobrando más importancia en los últimos años y es esta la que ha dado más valor a este subproyecto. Se estima que el número de fallos decrecerá radicalmente a la hora de utilizar el firmware diseñado frente a otros firmware basados en un diseño no modular. Además, los tiempos de mantenimiento se reducirán drásticamente. El firmware final, aun con más funcionalidad que el inicial, tiene unos requerimientos de memoria muy bajos. Tras realizar diferentes pruebas, el diseño se ha mantenido estable durante días sin ningún tipo de anomalía. En estas pruebas, se han analizado los consumos de memoria virtual y estos se han mantenido constantes comprobando así que el uso de este recurso se ha realizado de manera correcta. A falta de realizar las pruebas de campo, se puede concluir con que el firmware cumple con las expectativas.
6.3 Proyecto software El software de gestión o proyecto software está formado por una aplicación web. La aplicación web cuenta con una serie de test que comprueban que el diseño funciona en base a lo estipulado. Estos test han funcionado de manera correcta. A día de la entrega del TFG se está esperando la valoración del cliente. Es probable que al ser un frontend el usuario quiera realizar modificaciones sobre el mismo no obstante la funcionalidad principal debería de mantenerse fija (en base a los requisitos) y debería también haber sido cubierta en el desarrollo. Tras realizar una prueba junto al firmware durante varios días, el software de gestión funcionó sin ningún problema. Se detectó algún problema en una de las pruebas que ya ha sido marcado como bug para solucionar en las siguientes entregas.
6.4 Resumen En general se puede decir que el proyecto ha resultado exitoso, los principales objetivos: seguridad, bajo coste, fiabilidad, diseño de referencia se han conseguido sin lugar a dudas. El coste de los prototipos así como del despliegue de este proyecto es mucho menor que el correspondiente con un sistema basado en PLC. Como diseño de referencia se brinda a la empresa Automatinfo la posibilidad de ofrecer proyectos basados en este tipo de plataforma lo que permitirá aumentar la confianza del futuro cliente en lo que hasta ahora era un campo no explotado dentro de la automatización industrial.
188
Capítulo 7
Conclusiones
7.1 Objetivos alcanzados
A
inicio del documento, más concretamente en la Sección 2, se documentaron una serie de objetivos los cuales debían ser cumplidos. En este punto, veremos cómo se han resuelto estos objetivos y los resultados de los mismos de tal modo que el lector pueda tener un resumen de la elaboración del proyecto y del resultado de cada una de sus fases.
7.1.1
L
Objetivo general
El objetivo general de este proyecto, tal y como se comentó anteriormente, consistía en realizar un prototipo funcional que permitiera automatizar las diferentes raseras dentro de cada uno de los procesos productivos de la «Harinera Castellana». Tal y como se ha podido ir viendo a través del documento, la elaboración del proyecto se ha dividido en 3 subproyectos. Cada uno estos subproyectos se ha completado exitosamente a falta de realizar las pruebas de campo que por razones de horario y planificación de la «Harinera Castellana» no se ha podido llevar a cabo aunque sí se hará en un futuro. El proyecto se inició con una especificación de requisitos, más tarde se realizaron reuniones para consensuar las líneas base del proyecto. Seguidamente, se realizó un prototipo tanto a nivel software, como a nivel hardware. Por último, tras ver que el prototipo se adecuaba a las necesidades del cliente se procedió a la realización del prototipo final el cual será enviado al cliente para su evaluación. El resultado global de la realización de este objetivo ha sido altamente satisfactoria, adquiriendo muchos conocimientos tanto a nivel técnico como a nivel profesional.
7.1.2
Objetivos específicos
El objetivo general de un proyecto se puede equiparar a la meta en una carrera, sin embargo, para asegurar que se llega a la meta y poder calcular cómo de rápido vas a llegar, es importante dividir la carrera en pequeños segmentos. Este mismo concepto se aplica a la realización del TFG, donde el objetivo general ha sido dividido en diferentes subobjetivos. A continuación se dará un breve resumen de la realización de cada uno de estos subobjetivos o objetivos específicos. 189
Estudio de alternativas En la primera fase del proyecto, tras realizar la revisión de la especificación de requisitos, se inició una serie de reuniones con la empresa Automatinfo para comprobar la viabilidad de la plataforma propuesta. Hasta ahora este empresa no había utilizado Arduino para la realización de automatización de procesos industriales y no sabían hasta qué punto sería estable. Después de hacer un estudio de las diferentes alternativas existentes en el mercado, se decidió realizar un PCB que añadiera seguridad sin aumentar mucho el coste. Como resultado de estas reuniones y este objetivo nació el subproyecto hardware. Desarrollo de la plataforma hardware Tal y como se ha comentado, tras la realización del estudio de alternativas, se finaliza con la necesidad de realizar una PCB de bajo coste, compatible con Arduino y que además fuera segura. Esta fase del proyecto fue una de las partes que más dificultad me ha supuesto, tanto a nivel técnico como a nivel profesional. El hecho de no tener una buena base en física, cálculo y prácticamente no haber realizado ningún circuito durante la carrera (extracurricularmente los hice como hobbie), me llevaba a un estado en el cual a la hora de implementar alguna solución a un problema no tuviera la certeza ni la confianza para asegurar que dicha solución iba a resultar adecuada. Tras un mes trabajando en este campo al final cogí confianza y finalmente pude avanzar de forma más rápida y segura. Como resultado de este objetivo se ha obtenido una placa PCB completamente funcional y lista para ser probada en el lugar de despliegue. Este objetivo me ha servido de mucho a nivel técnico dado que he aprendido un sin fin de cosas sobre el desarrollo hardware. Análisis y elección de la arquitectura de comunicaciones La arquitectura de comunicaciones es un punto muy importante que se debe tener en cuenta a la hora de planificar el proyecto. Se ha puesto en un objetivo aparte debido a la importancia que tiene, no obstante esto debe ser planificado antes de la elección de la plataforma hardware y por supuesto de su desarrollo. En este caso se han estudiado las diferentes alternativas existentes en el mercado como Profibus, Profinet, Modbus. No obstante, debido a la falta de hardware que soporte estas tecnologías en Arduino así como la sobrecarga que añadían al diseño se optó por diseñar un protocolo de comunicaciones ad hoc basado en una red RS-485. En la realización o implementación de este objetivo he podido aplicar todos los conocimientos de la asignatura «Sistemas distribuidos» la cual me ha sido de gran ayuda en la elaboración de este TFG. Diseño del firmware El firmware es una parte fundamental en cualquier sistema embebido. De la calidad del firmware depende que un producto sea exitoso o no. En esta fase ha sido donde más he podido aplicar todo lo aprendido durante la carrera y que sin lugar a dudas ha añadido un 190
gran valor al proyecto. La aplicación de la orientación a objetos para reducir el número de fallos así como la aplicación de diferentes técnicas para mantener ordenado, legible y mantenible el código harán que el día de mañana, cuando haya que depurar este programa o extenderlo se reduzcan los costes y por lo tanto el precio que percibe el usuario. En esta fase del desarrollo me he dado cuenta de la importancia que tienen asignaturas como «Ingeniería del Software» en proyectos de esta índole y las consecuencias que tiene la aplicación de «buenas prácticas».
Implementación del software de gestión Uno de los requisitos de sistema era la implementación de un método de representación y de «log» para las acciones realizadas sobre cada uno de los cilindros. Tras la reunión mantenida con la «Harinera Castellana» se decidió implementar un sistema web de modo que se pudiera acceder desde cualquier lugar a la fábrica. La elaboración de este se ha completado con éxito. La elaboración de este subproyecto me ha permitido aprender sobre diferentes tecnologías web tales como Bootstrap, Flask, Python (orientado a la web), despliegue de servicios. . . Además, mediante la implementación de este subproyecto he podido presentar una alternativa innovadora en el sector de la automatización industrial.
Presentación de alternativa Por temas relacionados con horarios así como la fecha inicial en la que se creía que se presentaría este TFG (septiembre), a día de hoy, no se ha podido presentar la alternativa final al cliente, no obstante se mantiene relación con el mismo haciendo un seguimiento exhaustivo de cada una de las fases del proyecto. Aunque no se ha realizado la presentación de la alternativa, independientemente del TFG, este proyecto se presentará debido a que aparte de ser un proyecto para el TFG es un proyecto entre la empresa «Automatinfo» y la «Harinera Castellana».
Despliegue del sistema Del mismo modo que el objetivo anterior (Presentación de la alternativa) este objetivo no se ha podido cumplir de momento debido a las reformas que se están realizando en la fábrica y que imposibilitan las pruebas de campo y finalmente el despliegue del sistema. Tras finalizar las obras se realizarán una prueba de campo en uno de los silos y se comprobará la adecuación del diseño. Si el diseño resulta satisfactorio se procederá al despliegue consensuado del sistema. Aunque no se ha podido alcanzar el objetivo sí se ha planificado el despliegue donde he aprendido mucho sobre los diferentes fenómenos que intervienen en la comunicación así como la importancia de una buena infraestructura de red. 191
7.2 Trabajo futuro En este documento se han expuesto las diferentes etapas por las que ha ido pasando el TFG. Desde la especificación de los requisitos hasta la presentación de la alternativa se ha ido evolucionando una idea, convirtiendo esta idea primero en un prototipo y finalmente en un producto listo para ser implantando. Este producto puede ser mejorado o incluso añadirse nuevas características al mismo. A continuación se citarán algunas de las mejoras futuras que se realizarán en el diseño. Es importante que se recuerde que el proyecto no finaliza con el TFG si no que el proyecto con «Automatinfo» sigue en desarrollo. Implementación de representación gráfica: La primera versión del proyecto permite realizar la monitorización de los diferentes procesos en forma tabular. Con el objetivo de dotar al sistema de una mayor usabilidad se implementará una representación visual de modo que el operario pueda reconocer rápidamente qué se está haciendo en la fábrica. Notificaciones: Gracias a la naturaleza del sistema de gestión, es muy fácil expandir el diseño de modo que el mismo cuente con un sistema de notificaciones vía Short Message Service (SMS), Telegram, Whatsapp o incluso email. Despliegue: Como se ha comentado anteriormente aunque sí se ha planificado y diseñado el despliegue, todavía no se ha podido realizar. El despliegue se dejará como trabajo futuro. Modificación de protocolo a Modbus: Se creará una librería de más alto nivel que permita abstraer las peculiaridades de Modbus de tal modo que se use este último protocolo en el bus y así se permita añadir otros elementos industriales a dicho bus. Entrenamiento: Se dará un pequeño curso o presentación a los Ingenieros de Automainfo de modo que estos últimos puedan comprender la arquitectura definida en el proyecto y además de opinar, puedan modificar el programa si algún día es necesario. Certificaciones: En caso de que el proyecto resulte ser exitoso en la implementación, se buscará obtener certificaciones oficiales en el diseño de tal modo que «Automatinfo» pueda mostrar un proyecto certificado, funcional y de bajo coste que le permitirá diferenciarse frente a su competencia. Cambio de servidor: En un futuro se cambiará el servidor del software de gestión con el objetivo de asegurar la estabilidad cuando aumente el número de usuarios conectados.
7.3 Conclusiones personales Durante la carrera se ha tratado de dar una visión general sobre los diferentes aspectos que intervienen en el mundo laboral. Mediante los proyectos propuestos en las asignaturas, hemos aprendido a trabajar en equipo y a gestionar las fechas de entrega. Por otro lado, a 192
nivel técnico, las asignaturas cursadas nos han proporcionado una gran base de conocimiento que será muy valioso en nuestra vida laboral. Durante el TFG se han reforzado los conocimientos adquiridos durante la carrera además de aprender otros muchos que sin duda alguna, de no ser por este proyecto, no habría aprendido hasta la hora de mi inserción en el mundo laboral. Quizá los conocimientos técnicos puedan ser uno de los aspectos más valorados en la realización del TFG. Sin embargo, desde mi punto de vista, los conocimientos más valiosos adquiridos en la realización de este proyecto, han sido los conocimientos profesionales. El trato con clientes es un aspecto que, aunque se pretende simular durante la carrera, es difícil de practicar hasta que verdaderamente toca afrontar esta situación. En la realización TFG he descubierto un salida laboral que hasta ahora desconocía debido quizá a su escasa mención durante la carrera (apenas una o dos asignaturas). Hoy en día, la mayoría de operaciones que antiguamente se realizaban de forma puramente mecánica se están automatizando con sistemas informáticos. Esto ha abierto una gran oportunidad laboral a los ingenieros informáticos que hasta ahora era inexistente. También he podido investigar sobre el gran interés puesto tanto por el «Ministerio de Industria, Energía y Turismo» así como por diferentes empresas en el fenómeno llamado la «Industria 4.0» (ver Sección 3.4). El conocimiento de estas nuevas tendencias me ha llevado a la elaboración de varias ideas de negocio que podrían ser tenidas en cuenta los próximos años. Por otro lado, a nivel técnico este proyecto ha supuesto un auténtico reto. Desde el subproyecto hardware (ver Sección 5.2.2) hasta el software de gestión (ver Sección 5.2.4) he tenido que aprender muchas tecnologías que seguro serán de gran ayuda el día de mañana. En el proyecto hardware he obtenido conocimientos sobre el desarrollo, diseño y análisis de sistemas electrónicos. Teniendo que realizar desde un esquemático hasta el diseño del propio PCB. Los conocimientos requeridos para realizar este tipo de diseño no se adquieren en la carrera por lo que han tenido que ser estudiados de forma extracurricular. Quizá una buena base en cálculo, física y otras asignaturas comunes a otras ingenierías podría haber simplificado la curva de aprendizaje de estos nuevos conceptos. En el desarrollo del firmware he aprendido a tratar con fuertes requisitos de fiabilidad y bajo coste que conducen de una forma severa las diferentes decisiones de diseño. Además, los conocimientos en arquitectura de computadores así como, en ingeniería del software me han ayudado a fundamentar las decisiones de diseño que he propuesto a la hora de realizar el diseño de la plataforma. A modo de resumen el TFG proporciona una gran oportunidad para ver la realidad a la que nos enfrentaremos cuando nos incorporemos al mundo laboral. Aunque he tenido que hacer un esfuerzo muy grande estoy completamente satisfecho con los resultados obtenidos de los que he aprendido tanto de los aciertos como, sobre todo, de los errores.
193
ANEXOS
195
Anexo A
Tutorial Kicad
A.1 Creación del esquemático Para realizar el esquemático lo primero que hay que realizar es un proyecto. Los proyectos quedan definidos por el fichero «proyecto.pro». Es importante tener en cuenta que en Kicad todos los ficheros son de texto plano por lo que se pueden editar con un bloc de notas sin ningún problema. Una vez creado el proyecto se crea un nuevo esquemático y se empieza con el proceso de diseño. El diseño de un esquemático requiere de práctica en el diseño electrónico. Un esquemático únicamente es una representación de las conexiones eléctricas del circuito, por lo que si no se conoce cómo diseñar el circuito no se podrá realizar el esquemático. Para cumplir con los requisitos, en primer lugar vamos a ver cómo se conforman las «sheet» u hojas de diseño en Kicad. Una hoja de diseño consiste en un conjunto de símbolos, componentes y puertos. En Kicad, cada hoja es una «sandbox» o caja de arena. Esto quiere decir que las conexiones internas no se verán desde el exterior a no ser que se especifique de forma explicita. No todos los software de diseño utilizan este paradigma y aunque parezca en un inicio complejo, reporta muchas ventajas. Al tratarse cada hoja como una «sandbox» se puede asemejar a una unidad de pruebas de caja negra (vista desde el exterior) donde no se sabe que hay dentro pero si la interfaz que brinda al exterior y los valores que tiene que devolver, en este caso los niveles de voltaje que se deben obtener. Esta analogía con el diseño software pone de manifiesto alguna de las ventajas que se derivan del diseño jerárquico en Kicad. Para llevar a cabo este diseño jerárquico en primer lugar hay que considerar algunas cosas sobre las conexiones en kicad. Como se puede ver en la Figura A.1a en el esquema existen dos componentes los cuales queremos unir. En este caso, obviando los condensadores de desacoplo, etc, tendremos que unir la salida del LM7812 a la entrada del LM7805 para ello, utilizando la tecla «w» creamos un cable pinchando en primer lugar en el círculo justo al final del pin de salida y llegando al círculo justo al inicio del pin de entrada. En la Figura A.1b se puede ver el estado final. Cuando el diseño crece es incómodo tener tantas líneas verdes (cables) juntos. Para solucionar esto Kicad proporciona una herramienta llamada etiquetas. Las etiquetas no son una 197
característica única de Kicad, lo uitlizan la mayoría de los software de diseño. En la Figura A.2 se puede ver las mismas conexiones tras utilizar las etiquetas. El acceso directo para añadir una etiqueta es la tecla «l». Una vez pulsada la tecla se pedirá un nombre, este nombre es el nombre que aparecerá en el diagrama.
(a) Diagrama de conexiones, los círculos (b) Todos los pines conectados menos el indican un pin sin conectar pin VI del LM7812
Figura A.1: Retardos debido a optocoplamiento
Figura A.2: Alternativa al conexionado con cables mediante etiquetas. Las etiquetas con el mismo nombre están conectadas entre si
Es obvio el pensar que la tierra no se suele especificar así en los diseños (aunque no pasaría nada, únicamente sería una falta contra la estandarización y las buenas prácticas). En Kicad existen un conjunto de etiquetas ya creadas y que nos servirán en la mayoría de los casos. Estas etiquetas son entre otras muchas: GND, VCC, +12, +5, +24, etc. Para añadir estas etiquetas hay que añadirlas como un componente, es decir, exactamente igual como se ha añadido el LM7805 o el LM7812. Para añadir un componente se utiliza la tecla «a». En el cuadro de texto habrá que añadir el texto corrspondiente a la etiqueta o buscar mediante el «wizard». En la Figura A.3 se puede ver el resultado de utilizar las etiquetas estándar. Una vez analizado cómo realizar las conexiones, el siguiente paso consiste en saber cómo generar un diseño jerárquico. Para realizar un diseño jerárquico en primer lugar debemos crear una hoja de esquema que servirá como portada del diseño. Esta hoja inicial se comporta del mismo modo que un main en un programa. Dentro de este «main» vamos instanciando cada uno de los módulos. En la Figura A.4 se puede ver esta página principal con un módulo 198
Figura A.3: Resultado con etiquetas estándar
hijo. Se dice módulo hijo dado que funciona como una jerarquía. Para crear esta nueva hoja «hija» tenemos que ir al panel lateral y pulsar sobre el icono que dice: «create hierarchical sheet». Una vez seleccionada la herramienta solo habrá que hacer un click y seleccionar el tamaño (únicamente es visual) y el nombre del fichero.
Figura A.4: Diseño jerárquico
Para comprobar cómo se utilizan las etiquetas jerárquicas en Kicad, accederemos con el botón derecho sobre la «hoja hija» y seguidamente crearemos el mismo esquema que el de la Figura A.3. Lo único que modificaremos para este ejemplo será la etiqueta de la salida del LM7805 y la de entrada del LM7812, en su lugar crearemos dos etiquetas jerárquicas (barra de herramientas del lateral derecho). Como resultado tendremos un esquema como el de la Figura A.5. Como se puede observar en la Figura A.5 tenemos dos pines jerárquicos, por un lado tenemos el pin de entrada Vcc y por el otro el pin de salida llamado. Del mismo modo en que una función tiene parámetros y retorna valores, en el caso de los esquemáticos jerárquicos, 199
Figura A.5: Diseño jerárquico
una hoja puede tener puertos de entrada y puertos de salida. Para hacer estos puertos visibles desde el exterior hay que dar botón derecho sobre la hoja «hija» y luego clickar sobre el menú llamado «Import sheet pins» de este modo iremos colocando cada uno de los pines anteriormente definidos. El resultado final debería ser como el de la Figura A.6. Ahora desde el exterior se puede acceder a los pines definidos de tal manera que podrán ser transferidos a otro módulo o utilizado para otros fines. Para la creación de este esquemático se ha optado por otra alternativa a los pines jerárquicos. Debido a que este proyecto deberá ser mantenido por Ingenieros de Automática los cuales trabajan con otro tipo de programas CAD en los cuales no es normal el uso de hojas jerárquicas. Se harán todos los pines y etiquetas globales de esta manera desde cualquier hoja hija se podrá acceder a los pines hermanos. Aunque rompe un poco la modularidad se sigue manteniendo una jerarquía y además este esquemático será más sencillo de mantener por los encargados de tal tarea.
A.2 Creación de componente para una librería En esta sección se va a mostrar de forma resumida cómo crear un componente para una librería. En primer lugar hay que clickar sobre el botón «Library Editor - Create/Edit componentes». Desde este editor se pueden crear los componentes para el esquemático. Es importante tener en cuenta que en la mayoría de software de desarrollo electrónico se distingue entre dos tipos de componentes: Componentes para esquemático: Son los componentes que hemos visto durante todas las hojas de esquema. Componentes de representación en el PCB o «footprint» Desde este editor crearemos el componente para el esquemático. Para crear el componente en primer lugar hay que indicar que lo que se quiere realizar es un nuevo componente y no se quiere modificar uno existente, para eso hay que clickar sobre el botón «Create a New Component». Una vez seleccionado nos aparecerá una ventana para indicar el nombre del componente así como otros parámetros bien documentados. En este caso crearemos un 200
Figura A.6: Diseño jerárquico exportación de pines
Figura A.7: Hoja de comunicaciones
componente llamado 485. El siguiente paso consiste en definir la forma del esquemático. Es importante tener en cuenta que esta forma no tiene porqué ser la forma real, sin embargo, para este caso se creará un diseño con la forma real. El paso más importante una vez creada la forma del componente con las herramientas de polígonos, es la asignación de pines. Para añadir un pin habrá que utilizar la segunda herramienta empezando por arriba de la barra de herramientas de la derecha. Una vez hecho click en un punto se nos pedirá varios parámetros que deberán ser rellenados para que más tarde el ERC sea capaz de detectar la mayor parte de fallos posibles. En la Figura A.8 se muestra el cuadro de diálogo que debería aparecer. A continuación se dará una breve descripción de los parámetros requeridos: 201
Pin name: Es el nombre del pin, es recomendable que se ponga el mismo nombre que el que aparece en las hojas de datos del integrado que se esté creando. Pin number: Del mismo modo que con «Pin name» es importante que se siga la numeración del datasheet. Orientation: Únicamente determina la orientación del pin, no es un parámetro decisivo aunque como es lógico deberá ser completado con el valor correcto, de lo contrario, a la hora de crear el esquemático con este componente no será posible conectar ningún cable a los pines. Electrical type: Este es el parámetro más importante de todos. El uso de este parámetro requiere de conocimientos de electrónica no obstante, los valores típicos son: Input, Ouput, Tristate. Graphical style: Este parámetro permite configurar la forma del pin de tal modo que se adapte al estándar.
Figura A.8: Diálogo para la configuración de pines del componente
Una vez generados todos los pines, la siguiente fase consiste en guardar el componente en una librería. En este caso se explicará cómo guardar el componente en una librería nueva. Para ello debemos ir a la barra superior de herramientas y dar al botón representado con un libro con las páginas en blanco. Tras ello ya estará guardado el componente, ya solo queda importarlo al esquema.
A.3 Creación de footprint En esta sección se guiará al lector en la creación de un footprint para el PCB. 202
Figura A.9: Proceso de traducción de componentes esquemáticos a footprint
Para crear el footprint se deberá abrir la herramienta «pcb footprint editor». Una vez abierta deberá aparecer una ventana como la mostrada en la Figura A.10. Desde esta ventana deberemos crear la forma exacta que será impresa en el PCB.
Figura A.10: PCB footprint editor
Este proceso sí es crítico por lo que hay que ser cuidadoso a la hora de realizar las medidas. En la Figura A.11 se puede ver el estado final del footprint. Si se desea ahondar en la utilización de estas herramientas de Kicad se puede consultar [kic16].
A.4 Capas PCB A la hora de crear una PCB hay que tener en cuenta una serie de conceptos que serán recurrentes en la mayor parte de los programas de diseño electrónico. 203
Figura A.11: Footprint RS-485 terminado
Uno de los conceptos claves son las capas tal y como se puede ver en la Figura A.12, existen diversas capas que permiten jerarquizar el diseño. A continuación se dará una breve descripción de dichas capas: F.Cu: Esta capa corresponde a la capa frontal del pcb donde hay cobre. En esta capa será donde «dibujaremos» las diferentes líneas de cobre que se utilizarán para conectar los diferentes componentes. Además, en esta capa también se insertan los «pads» correspondientes a la capa frontal. B.Cu: Es el equivalente a la capa F.Cu con la diferencia de que en este caso hace referencia a la capa inferior. F.Adhes: Esta capa para las PCB normales no se suelen utilizar. Esta capa permite generar un adhesivo que permitirá soldar de una manera más sencilla los componentes Surface Mounted Device (SMD). B.Adhes: Lo mismo que F.Adhes pero para la capa inferior. F.Paste: Del mismo modo que B.Adhes y F.Adhes esta capa normalmente se usa para componentes SMD. Mediante esta capa se genera una máscara con todos los lugares donde no hay cobre. B.Paste: Igual que F.Paste pero para la capa inferior. F.SilkS: Esta capa sí es muy utilizada y es en ella donde se «dibujan» las formas de los componentes así como los textos que más tarde, en el proceso de producción serán trasmitidos a la PCB. B.SilkS: Lo mismo que F.Silks pero para la capa inferior. F.Mask: Esta capa sí es muy utilizada y permite indicar dónde se encuentran los pads de los componentes de tal manera que no se le aplique el barniz a dichos lugares. 204
B.Mask: Lo mismo que F.Mask pero para la capa inferior. *.User: Todas las capas acabadas en User se utilizan para que el diseñador escriba comentarios del mismo modo a como se hace en los programas de ordenador. Edge.Cuts: Esta capa es muy importante dado que permite definir la forma y tamaño de nuestra placa. Esta capa la leerla tanto las herramientas de «pick and place» como las herramientas Control Numérico Computerizado (CNC).
Figura A.12: Capas en Kicad
A modo de resumen, las capas que más se utilizarán serán tanto F.Cu como B.Cu y Edge.Cuts. Las demás capas se definen normalmente por cada componente, de tal manera que el diseñador no debe preocuparse por su utilización salvo en la fase de generación de los ficheros de fabricación.
A.5 Herramienta DRC A continuación se explicarán los parámetros más relevantes a la hora de configurar la herramienta de DRC y cómo se configuran en Kicad. Es importante que este paso se realice al principio no obstante, con el objetivo de dotar al lector de conocimientos previos se ha dejado hasta el final. Para configurar los DRC se deberá ir al menú «Design Rules» y seguidamente a la pestaña «Design rules». Aparecerá un cuadro de diálogo como el mostrado en la Figura A.13. Este cuadro está formado por dos paneles. En el panel superior podemos crear clases que nos 205
permitirán modularizar el diseño. Todos los «cables» que formen parte de una clase tomarán los valores de DRC aquí indicados. En este caso tenemos dos clases: la clase por defecto «Default» y la de «Power». La de por defecto se utiliza para todo aquello que no sea explícitamente de «Power». Por cada clase se definen una serie de atributos que a continuación serán explicados: Clearance: El clearance es la distancia mínima que debe existir entre dos pistas. Track Width: El Track Width se corresponde con el ancho de la pista. El ancho de la pista se suele definir en mils, es decir, en milésimas de pulgadas. En este caso tenemos un ancho de 12 mils para la clase «Default» y 32 mils para la clase de «Power». El ancho de la pista es un parámetro muy estudiado que depende, entre otras cosas, del grosor del cobre, amperaje que circula por la pista, etc. Via Dia: Se corresponde con el diámetro de la vía. Una vía es una conexión entre dos capas que se forma mediante un agujero físico en la placa. El tamaño mínimo de la vía debe ser tal que sea mayor que tamaño del taladro. Via Drill: Via Drill corresponde al tamaño del taladro de la vía. Este parámetro será utilizado por la CNC para realizar los agujeros en la placa. uVia Dia, uVia Drill: Las microvias son elementos más complejos para diseños con más de dos capas por lo que en este caso no será explicado. Una vez definidas las clases que se deseen se puede añadir diferentes «nets» o redes a dicha clase de modo que a la hora de enrutar, cuando el programa detecte que es una net dentro de una familia, configurará la misma con los valores aquí asignados. Por ejemplo, en la Figura A.13 se puede observar como la «net» de 12v así como la de 24 y 5 voltios convertidos están asignados a la familia «power». Una vez configurados todos los valores mencionados se deberá pasar el DRC del sistema, para ello habrá que pulsar sobre el icono con un insecto tras lo cual aparecerá un icono como el de la Figura A.14. En este cuadro podremos añadir alguna restricción más individual y una vez preparado habrá que pulsar sobre el botón «Start DRC». Si no existen errores entonces los cuadros inferiores estarán vacíos, de lo contrario existirá algún error.
206
Figura A.13: Cuadro de diálogo DRC
Figura A.14: Cuadro de ejecución DRC
207
Anexo B
Instalación de Arduino en entorno Eclipse
B.1 Introducción En este apéndice se dará una breve explicación de cómo configurar el entorno de desarrollo Eclipse de modo que el mismo pueda ser utilizado para programar y grabar programas en la plataforma Arduino. El lector podría preguntarse porqué utilizar otro IDE si ya ha utilizado el oficial de Arduino y no ha tenido ningún problema. Arduino se pensó como una plataforma con una curva de aprendizaje muy baja, la ventaja obvia es la rápida adaptación de cualquier persona con mínimos conocimientos de informática al entorno. El problema, no tan obvio en un primer momento, es la carencia de herramientas tan importantes como: control de versiones, gestión de proyectos, etc. Con el objetivo de mostrar el potencial de Arduino, en este apéndice configuraremos un entorno con todas las herramientas necesarias en cualquier ambiente profesional.
B.2 Qué es Eclipse Eclipse es un entorno de desarrollo integrado de código libre y multiplataforma. Eclipse ofrece un «core» sobre el que otros desarrolladores realizan sus modificaciones para crear entornos de desarrollo específicos para cada tecnología. Un ejemplo podría ser el entorno para Java o el entorno de Xilinx para el desarrollo de software sobre su plataforma hardware. Aunque existen plugins para Eclipse que ofrecen una capa de compatibilidad con Arduino, en este apéndice trabajaremos sobre Eclipse para C++ con el objetivo de poder tener control sobre cada una de las partes que conforman la construcción de un binario para Arduino. La página oficial de Eclipse se puede visitar desde el siguiente enlace: https://eclipse. org, en ella se puede encontrar toda la información de la fundación Eclipse. Además, desde el apartado «Download» podrás descargar cada una de las versiones oficiales del entorno.
B.3 Instalación del entorno El primer paso será el descargar nuestro entorno de desarrollo Eclipse sobre el que realizaremos todas las «modificaciones» necesarias para que sea compatible compatible con la 209
Figura B.1: Pantalla inicial de Eclipse plataforma Arduino. Para descargar el entorno, en primer lugar, deberemos acceder a la web de Eclipse y luego al apartado de descargas: http://www.eclipse.org/downloads/ una vez dentro deberemos elegir la opción de «Eclipse IDE for C/C++ Developers». Esta versión nos ofrece muchas herramientas de gran utilidad como: Mylyn Task, Git o un sistema de acceso remoto. Una vez descargado el entorno para la arquitectura correspondiente, el segundo paso será la descompresión del mismo. Eclipse es un programa portable, esto quiere decir que no requiere de una instalación por lo que una vez descomprimido estaremos en disposición de utilizar el mismo. El siguiente paso será ejecutar el programa, en teoría si tenemos Java en nuestro computador el entorno se ejecutará sin ningún tipo de problema, en caso de no tener Java el entorno nos avisará y tendremos que instalarlo. La pantalla inicial tendrá la apariencia de la Figura B.1. Con la instalación del entorno Arduino tendremos todas las herramientas necesarias, como son: Compilador: Utilizaremos el compilador «avr-gcc» y «avr-g++» para compilar nuestros proyectos. Conjunto de librerías Arduino: Las librerías de Arduino, forman parte del llamado «ArduinoCore». Estas librerías nos simplifican tareas repetitivas como la configuración del modulo USART, configuración de pines, etc. Librerías AVR:La librería de Arduino utiliza las librerías de AVR por lo que también tendremos estas últimas en nuestra instalación. Programador: Para programar el Arduino necesitamos un programador «hardware» 210
Figura B.2: Descarga del plugin AVR y un programador «software». En el caso del programador «hardware» ya lo tenemos instanciado dentro de la placa Arduino (una vez instalado el bootloader). Por otro lado, el programador «software» que utilizaremos será «avrdude» que forma parte del conjunto de herramientas de AVR. Mapeado de pines: Como ya sabrás, el entorno Arduino utiliza su propia numeración de pines, de tal modo que si pones pin 13 en una función, el Arduino «sabe» qué pin es y a qué puerto le corresponde (en realidad el encargado de hacer esta conversión como es lógico, no es Arduino, es el compilador). Esto se realiza mediante el archivo de variants que veremos más adelante. Es importante que anotemos la dirección de instalación de Arduino para los pasos siguientes. En el caso de los sistemas GNU/Linux, esta dirección suele ser: /usr/share/arduino.
B.4 Configuración del entorno Ahora que tenemos todo descargado es el momento de realizar la configuración del IDE Eclipse. En primer lugar descargaremos un plugin para el desarrollo de soluciones basadas en microprocesadores AVR dentro de Eclipse. Para descargar un plugin en Eclipse, podemos acceder al menú «Help, Install new software» o «Ayuda, Instalar nuevo software» en Español. Una vez en esa pantalla deberemos pulsar al botón «Add» y luego en el apartado de «Name» poner el nombre que se desee, por ejemplo avr-descargas, y en location la siguiente dirección: http://avr-eclipse.sourceforge.net/ updatesite, deberá quedar como en la Figura B.2. Una vez rellenado el formulario aparecerá ante nosotros un plugin llamado AVR Eclipse Plugin con un «checkbox», deberemos seleccionar dicho «checkbox», seguidamente pulsaremos «Next» y «Finish» según las instrucciones, hasta finalizar la instalación. 211
Figura B.3: Configuración de ejemplo Una vez instalado, el siguiente paso consiste en la configuración de las variables que permiten al plugin saber dónde se encuentran los binarios del compilador, etc. Para configurar el plugin hay que ir al menú «Window, Preferences» o «Ventana, Preferencias». Una vez en el menú deberemos acceder al apartado de «AVR, Paths». Hay que configurar cada una de las variables para que apunten al binario dentro del SDK descargado en el paso anterior. AVR-GCC: /hardware/tools/avr/bin GNU make: Con el entorno descargado para Windows se descarga también la herramienta make por lo que el mismo estará en el directorio del SDK, sin embargo para GNU/Linux esta herramienta no viene incluida dado que forma parte de GNU/Linux y esta de forma nativa para todas las distribuciones por lo que en este caso seguramente el propio plugin detecte el lugar donde se encuentra instalado y aparecerá algo como «system» en esta variable. AVR Header Files: /hardware/tools/avr/avr/include AVRDude: /hardware/tools/avr/bin En la Figura B.3 se puede ver un ejemplo de una de las posibles configuraciones, ten en cuenta que en función de donde se realice la instalación, los path y en consecuencia la configuración variará.
B.5 Creando el proyecto: ArduinoCore Como ya hemos comentado, Arduino nos proporciona un conjunto de librerías que hacen que sea mucho más sencillo el utilizar algunos de los módulos «hardware» del microcontrolador. Para poder contar con todas estas comodidades tendremos que compilar las librerías en un proyecto a parte (esto nos permitirá reutilizar las librería en otros proyectos). Esta 212
tarea en el entorno oficial de Arduino se realiza sin que nosotros tengamos que hacerlo de forma explicita, esto hace que sea mucho más rápido para el usuario pero a la vez, hace poco didáctico el proceso. Para compilar las librerías en primer lugar crearemos un proyecto, para ello vamos al menú «New, C++ Project» y en tipo de proyecto «AVR Cross Target Static Library» el nombre que pondremos al proyecto será «ArduinoCore», el nombre no es determinante, sin embargo este simplifica la labor de comprensión de los pasos que estamos realizando. En configuraciones únicamente seleccionaremos la de «Release» esto se debe a que esta librería no la modificaremos y por lo tanto no necesitamos toda la configuración de «Debug». En la siguiente pantalla de configuración se nos preguntará por el microcontrolador y por la frecuencia. Ambos parámetros deberán ser configurados en función del Arduino sobre el que se vaya a realizar el proyecto. En el caso del Arduino construido en este libro en la configuraremos estos parámetros con ATmega328 y 16000000 (como se puede observar en este ejemplo la frecuencia viene determinada en hercios). Una vez creado el proyecto el siguiente paso consiste en añadir el código fuente de las librerías, y configurar los includes. Para esto último daremos click derecho sobre el proyecto y buscaremos el menú de propiedades. Una vez dentro del mismo deberemos buscar el apartado «C/C++ Build, Settings» y en el apartado «AVR Compiler» ir a la pestaña de «Directories» y añadir el directorio: /hardware/arduino/avr/cores/arduino. Este directorio contiene todos los «headers» de las librerías. Por otro lado tenemos que añadir el «header» que utiliza el entorno Arduino para referirse a sus pines. Este fichero como habrás podido adivinar varía en función del microcontrolador. El fichero se puede encontrar dentro de /hardware/arduino/variants luego selecciona el que necesites, por ejemplo, para el microcontrolador ATmega328 deberíamos utilizar el mapeado standard. Hay que hacer exactamente lo mismo con el otro apartado llamado «AVR C++ Compiler». Ahora que ya tenemos todas las referencias configuradas, el siguiente paso consiste en importar el código fuente de las librerías, para ello damos botón derecho sobre el proyecto y seleccionamos la opción de «Import, File System». En el cuadro de búsqueda hay que ingresar el directorio: /hardware/arduino/avr/cores/arduino. Una vez dentro, selecciona todos los archivos (.cpp y .h) menos el archivo main.cpp. Por último ya solo queda compilar el proyecto, para ello cruzamos los dedos y damos botón derecho «Build Project». Si todo va bien ya tendremos las librerías de Arduino compiladas. 213
B.6 Creando el proyecto final Ahora que tenemos compilado el conjunto de librerías de Arduino para el microcontrolador que estamos utilizando, ya podemos crear un proyecto tal y como lo haríamos en el IDE oficial de Arduino. Para crear un proyecto en primer lugar accedemos al menú: «New, C++ Project» y en tipo de proyecto ponemos: «AVR Cross Target Application» tal y como en la Sección B.5. El nombre del proyecto en este caso no es relevante. Como este proyecto sí que pasará por la fase de «debug» y de «release» dejaremos habilitadas ambas configuraciones. El siguiente paso consiste en añadir los mismos directorios que en la Sección B.5 con el objetivo que se pueda referenciar a los ficheros de cabecera del «core». Además, hay que añadir al propio proyecto en la lista de directorios. Para ello añadir la cadena «${workspace_loc:/${ProjName}}» , tanto en «AVR Compiler» como en «AVR C++ compiler», que indica al compilador que compruebe los ficheros de cabecera de este mismo proyecto. Una vez que tenemos las tres direcciones completadas podemos proceder a enlazar este proyecto con el «core». Para enlazar los código objeto, el primer paso es ir al menú del linker llamado «AVR C++ Linker» y en el apartado «General» sustituir la cadena del cuadro de texto «Command line pattern» por la siguiente «${COMMAND} -s -Os ${OUTPUT_FLAG}${OUTPUT_PREFIX} ${OUTPUT} ${INPUTS} -lm ${FLAGS}», por último en la apartado «libraries» tenemos que indicar dónde se encuentra el fichero con la librería, así como el nombre de la misma. En nuestro caso el nombre era «ArduinoCore» y el ejecutable se puede encontrar en la carpeta release del proyecto «ArduinoCore». Para completar este paso por tanto, en el primer cuadro («libraries -l» debemos poner ArduinoCore y en el cuadro inferior con el nombre «libraries path -L» la siguiente cadena que es relativa al workspace: «${workspace_loc:/ArduinoCore/Release}» el aspecto final debería ser parecido al mostrado en la Figura B.4. Una vez configuradas las librerías deberemos «decir» a eclipse que genere el «.hex» para el Arduino. Para ello hay que ir a las propiedades de AVR dentro del proyecto luego «C/C++ Build, Settings, Additional Tools in Toolchain» y seleccionar la opción «Generate HEX file for flash memory».
B.7 Subiendo el proyecto a nuestro Arduino Para «subir» el «.hex» generado para nuestro proyecto a la memoria flash del Arduino, lo primero que tenemos que hacer es configurar la herramienta «avrdude» que será el programador software encargado de realizar la comunicación con el Arduino para subir el «.hex» al mismo. 214
Figura B.4: Configuración de las librerías «avrdude» utiliza un fichero de configuración llamado «avrconf» para saber los diferentes tipos de programadores hardware con los que cuenta así como las configuraciones que debe realizar para comunicarse con cada uno de ellos. Para configurar este archivo en «avrdude» tenemos que ir a las preferencias generales de «eclipse» y buscar el menú «AVR, AVRdude». Una vez en el menú, el siguiente paso consiste en marcar la casilla «Use custom configuration file for AVRDude» y buscar el fichero «avrconf» en: /hardware/tools/avr/etc/avrdude.conf. Ahora que tenemos preparado el fichero «avrconf» lo siguiente consiste en configurar las propiedades del proyecto para indicar qué tipo de programador «hardware» utilizaremos y que acciones debe realizar «avrdude» para programar el Arduino. El primer paso consiste en ir a las propiedades del proyecto y buscar el menú «AVR, AVRDude». Ahora crearemos una nueva configuración dando al botón «new» de la pestaña «Programmer». El nombre de la configuración puede ser el que desees, se recomienda utilizar el nombre de tu placa así te será más sencillo tener todo ordenado. En «programmer hardware» deberemos buscar «Wiring». En el cuadro de texto llamado «Override default port» deberemos poner el puerto en el cual se encuentra conectado nuestro Arduino. En el caso de GNU/Linux este suele ser /dev/ttyACMX. En Windows el puerto COM deberá escribirse de la siguiente manera «//./COMX». En cuanto a la velocidad en baudios variará en función del «bootloader» y de la placa, los valores típicos son 57600 y 115200. El aspecto de esta ventana de configuración debería ser similar a la Figura B.5. Con todo configurado ya solo queda crear un archivo «main.cpp» en nuestro proyecto con el esquema mostrado en el Listado B.1. 1
#include
2
void setup()
3
{
//config
215
Figura B.5: Configuración de AVRdude 4
}
5
void loop()
6
{
7
//code
8
}
9
int main(void) {
10
init();
11
setup();
12
while(true) { loop();
13 }
14 15
}
Listado B.1: Esqueleto de programa Como se puede observar, aquí se hace patente como, cuando creamos un sketch en el IDE oficial de Arduino realmente estamos creando las dos funciones principales como son setup y loop pero nos despreocupamos de iniciar la plataforma (init()) y de asegurarnos de que el programa nunca finaliza (bucle while). Una vez guardado el programa tendremos que compilar el mismo dando botón derecho sobre el proyecto y sobre la opción «Build Project». Si todo está bien se creará una carpeta llamada «Debug» donde podremos encontrar un fichero llamado «nombreDelProyecto.hex». Ahora solo nos queda subirlo a nuestra placa, para ello pulsamos botón derecho sobre el proyecto y buscamos «AVR, Upload Project to Target Device».
216
Anexo C
Requisitos formales de la Harinera Castellana
217
Versión nº 1 : Fecha: 22-06-2015
Especificaciones para la automatización de raseras en fábrica
Redacción:
Empresa cliente:
FRAGA.S.A .
Empresa proveedora:
AUTOMATINFO S.L.
Especificación aprobada por:
Firma:
Fecha de aprobación:
Contenido: 1- Datos de Partida. 2- Descripción Raseras automatizadas 3- Arquitectura automatismos 4- Trabajos a realizar
Página 1 de 4
218
Versión V1 de fecha 02/07/201615
Automatización raseras manuales de Fábrica. En el presente documento describiremos las especificaciones para automatizar las raseras manuales actuales en el contexto y extensión de la fabrica (se adjuntan en anexo planos). Ubicación
HARINERA CASTELLANA Medina del Campo Valladolid
1. Datos de Partida 1.1. Posibles raseras para automatizar.
Celdas de molienda, sección A: 3 uds (aunque son 4 celdas seguidas, la última estaría siempre abierta). Funcionamiento en modo manual. Si se hacen a la vez las raseras de la zona inferior de las celdas de reposo de la sección A, debería funcionar todo en modo automático (se conocen los porcentajes y fórmulas…). No se requiere regulación proporcional, solo abierto-cerrado. Silos de trigo, parte superior: 12. No se requiere regulación proporcional, solo abierto-cerrado. Ojo porque puede haber dos abiertas por si se llena un silo. El orden de los silos donde por donde avanza el trigo y están colocadas las raseras es: 1 y 12, 2 y 11, 3 y 10, 4 y 9, 5 y 8, 6 y 7. Celdas de reposo sección A, parte superior: 13x2=26 (aunque son 14x2, las 2 últimas siempre abiertas). Aquí hay dos líneas: o Dependiente de la rosca R5: Celdas 1 a la 14, correlativas. No se requiere regulación proporcional, solo abierto-cerrado. Ojo porque puede haber dos o más consecutivas abiertas. Hay que añadir una rasera para habilitar rosca R5 o R6 (la siguiente). Si se abre esta rasera, la mercancía cae en R5, si está cerrada va a R6. o Dependiente de la rosca R6: Celdas 15 a 28. No se requiere regulación proporcional, solo abierto-cerrado. Ojo porque puede haber dos o más consecutivas abiertas Rosca R3: distribución hacia rosca R4 o R5 y R6: 1 rasera para Rosca R4. No se requiere regulación proporcional, solo abierto-cerrado. Si está cerrada, la mercancía fluye hacia rosca R5 y R6. Salida inferior de silos de trigo: 12 unidades. Deben ser regulables. Se pueden abrir varias a la vez, con regulación proporcional, el resto permanecen cerradas. Página 2 de 4 219
Versión V1 de fecha 02/07/201615
Celdas de revoltura: 1. No se requiere regulación proporcional, solo abierto-cerrado. Celdas de reposo, sección A, parte inferior: 14x2=28. Se requiere regulación proporcional porque puede haber 5 celdas abiertas como máximo. Celdas de reposo, sección B, parte inferior: 6x2=12. Se requiere regulación proporcional, como máximo 4 celdas abiertas. Celdas de molienda, sección B: 2 unidades (aunque son 3, la última estaría siempre abierta). No se requiere regulación proporcional, solo abierto-cerrado. Ojo porque son raseras en el tubo. Celdas de reposo sección B, parte superior: 6x2=12. No se requiere regulación proporcional, solo abierto-cerrado, aunque puede haber varias abiertas a la vez. Orden de avance del producto: 1 y 7, 2 y 8, 3 y 9, 4 y 10, 5 y 11, 6 y 12. Son raseras también de tubo.
2. DESCRIPCIÓN DE LAS RASERAS A INSTALAR
Actualmente las raseras son manuales por lo que se tiene que diseñar un nuevo sistema de accionamiento que inicialmente será un cilindro eléctrico. La rasera se tiene que poder abrir y cerrar de forma proporcional a lo indicado por el operador en un sistema central (PC nivel superior). Se tiene que asegurar la posición de la rasera mediante detección a estudiar. Las tiradas de cable son muy largas por lo que habrá que realizar una estructura modular. Se adaptara la rasera con una estructura que soporte al accionamiento, en este caso cilindro eléctrico. Al cilindro se le dotará las protecciones necesarias tanto a nivel eléctrico como mecánico. Se ha de realizar un prototipo instalarlo en una rasera actual y validar su funcionamiento
Página 3 de 4 220
Versión V1 de fecha 02/07/201615
3. ARQUITECTURA DE AUTOMATISMOS
Se piensa en PLC o similar para controlar agrupaciones de raseras de forma coherente con la logística de la fábrica, esto se realizara en estudio conjunto con la fábrica. El número de agrupaciones de raseras que se estimen se unirán a una red concentradora y controlada por un PLC central o bien un PC nivel superior. Desde este y mediante Teclado /pantalla se puede seleccionar la operación a realizar y visualizar las incidencias de la instalación. El concentrador deberá disponer de bases de datos e históricos de incidencias. Se ha de estudiar un sistema degradado para operar los cilindros ante una avería del concentrador.
4. TRABAJOS A REALIZAR
Estudios preliminares mecánicos y de automatismos y software para aplicar. Estudios funcionales. Acuerdos de lanzamiento. Proyectos mecánicos y eléctricos. Valoración económica del proyecto. Timing de ejecución. Realización de prototipo para su validación. Fichas técnicas y descriptivas de funcionamiento. Petición de materiales definitivos. Preparación de documentaciones provisionales. Acuerdos y remarcas. Programas PLCs o controladores. Programaciones de PC para nivel superior. Programación de pantallas Fabricación de armarios. Instalación y montaje mecánico/ eléctrico de elementos. Tiradas de canalizaciones. Tiradas de mangueras eléctricas de interconexión. Realización del Test eléctrico. Carga de programas PLCs y ensayos. Conexión nivel superior Puesta en Marcha. Asistencia tecnica 5 días. La formación al personal de fábrica. Entrega de la documentación.
Página 4 de 4 221
Anexo D
Código y documentación extra
Debido a la envergadura del proyecto no se ha podido incluir todo el código en este documento. Sin embargo, tanto el código como la documentación de todos los subproyectos citados durante el documento están disponible de forma online. A continuación se indicarán los enlaces desde donde el lector podrá acceder a dichos repositorios con el código y la documentación extra, incluido el código fuente de este documento: Ficheros fuentes PCB: El proyecto Kicad se puede descargar desde el siguiente enlace: https://bitbucket.org/JoseAntonioTorre/raseras-kicad
Implementación del protocolo en Python: La librería del protocolo para Python se puede obtener desde el siguiente enlace al repositorio Bitbucket: https://bitbucket. org/JoseAntonioTorre/raserasprotocol
Código y documentación del firmware: El proyecto Eclipse con todo el código del firmware de control se puede obtener desde el siguiente enlace: https://bitbucket.org/ JoseAntonioTorre/raseras. El lector también podrá generar la documentación «Doxygen» desde dicho repositorio. Para ello únicamente deberá ejecutar el siguiente comando: #doxygen Raseras.Doxyfile
Código del software de gestión: La página web o software de gestión se puede ser descargada desde el siguiente enlace: https://bitbucket.org/JoseAntonioTorre/raserasweb
223
Anexo E
GNU Free Documentation License
Version 1.3, 3 November 2008 c 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. Copyright Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
0.
PREAMBLE
The purpose of this License is to make a manual, textbook, or other functional and useful document “free” in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
1.
APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
225
A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”. Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text. The “publisher” means any person or entity that distributes copies of the Document to the public. A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
2.
VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies.
3.
COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
226
4.
MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles. You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
227
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements”.
5.
COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
6.
AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
7.
TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
8.
TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.
228
9.
FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.
10.
RELICENSING
“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site. “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a notfor-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document. An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.
229
Referencias [Abo]
About | Libelium.
http://www.libelium.com/company/.
(Accessed on 06/13/2016).
[aja08]
Ajax: The Definitive Guide. Anaya Multimedia, 2008.
[AT]
Vanessa Romero Segovia Alfred Theorin. A short history about PLC and DCS. https://www.thelibrarybook.net/view.php?res=http:// www.control.lth.se/media/Education/DoctorateProgram/2012/HistoryOfControl/ Vanessa Albert-PLCDCS.pdf&keyword=A+Short+History+About+PLC+and+DCS+-+ Automatic+control.
(Accessed on 06/07/2016).
[BCK96] Mihir Bellare, Ran Canetti, y Hugo Krawczyk. Keying hash functions for message authentication. páginas 1–15. Springer-Verlag, 1996. [boo13]
Bootstrap Responsive Web Development. O’Reilly Media, 2013.
[com08] Computers as Components. Morgan Kaufmann, 2008. [con14]
Programación Concurrente y Tiempo Real. Createspace Independent Publishing Platform, 2014.
[ct09]
Control Techniques Drives and Controls Handbook. Institution of Engineering and Technology, 2009.
[des04]
Decentralization with PROFIBUS DP/DPV1: Architecture and Fundamentals, Configuration and Use with SIMATIC S7. Publicis, 2004.
[dIEyT]
Ministerio de Industria Energía y Turismo. La transformación digital de la industria Española. http://www6.mityc.es/IndustriaConectada40/ informe-industria-conectada40.pdf. (Accessed on 06/07/2016).
[Dis]
Distributed control system - Wikipedia, the free encyclopedia. https://en. wikipedia.org/wiki/Distributed control system. (Accessed on 06/10/2016).
[E.A98]
L.A.Bryan. E.A.Bryan. Programmable Controllers: Theory and Implementation. Industrial Text Company, 1998. 231
[ele81]
Electronics and Instrumentation for Scientists. Benjamin-Cummings Pub Co, 1981.
[emb99] An Embedded Software Primer. Pearson Education, 1999. [emb00] Embedded Microcontrollers. Prentice Hall, 2000. [enf16]
Arduino un enfoque práctico e incremental. Julio Daniel Dondo, 2016.
[fb01]
Fieldbuses for Process Control: Engineering, Operation, and Maintenance. ISA, 2001.
[fsf]
¿Qué es el software libre? - Proyecto GNU - Free Software Foundation. www.gnu.org/philosophy/free-sw.es.html. (Accessed on 06/12/2016).
[gus09]
Programación de sistemas embebidos en C. Alfaomega, 2009.
[hac08]
Hacking. Técnicas fundamentales (Hackers Y Seguridad). Anaya Multimedia, 2008.
[Her13]
Natividad Vargas Hernández. Metodología de diseño para el desarrollo de sistemas embebidos bajo el paradigma de mejora de procesos. Revisa electrónica de posgrado e investigación, 2013. (Accessed on 06/19/2016).
[Ins99]
Texas Instruments.
PCD8544 Datasheet.
datasheet-pdf/view/18170/PHILIPS/PCD8544.html,
https://
http://pdf1.alldatasheet.es/
1999. original document from
Philips Semiconductors. [iso01]
Ingeniería del Software: Un enfoque prático. S.A MCGRAW-HILL, 2001.
[iso06]
Ingeniería del Software. Addison Wesley, 2006.
[jq13]
Learning jQuery. Packt Publishing, 2013.
[Kic10]
Diseño y desarrollo de circuitos impresos con kicad. RC libros, 2010.
[kic16]
Kicad Like a Pro: Learn The World’s Favourite Open Source PCB Electronic Design Automation and make your own professional PCBs. Tech Explorations, 2016.
[Lan13]
Ralph Langner. To Kill a Centrifuge. 2013.
[MA07]
Jürgen Münch y Pekka Abrahamsson, editors. Product-Focused Software Process Improvement, 8th International Conference, PROFES 2007, Riga, Latvia, July 2-4, 2007, Proceedings, volume 4589 of Lecture Notes in Computer Science. Springer, 2007. 232
[mac92] Software Specification and Design: A Disciplined Approach for Real-Time Systems. Wiley, 1992. [mak14] Make Your Own PCBs with EAGLE: From Schematic Designs to Finished Boards. McGraw-Hill, 2014. [mey97] Object-Oriented Software Construction. Prentice-Hall, 1997. [New]
New Industrial Protocols modules for Waspmote: RS-232, RS-485, CAN Bus, Modbus, 4-20mA | Libelium. http://goo.gl/dp8PVS. (Accessed on 06/13/2016).
[Ope]
Open Source ERP and CRM | Odoo. 06/14/2016).
[Ord]
Garbiel Ordoñez. www.oocities.org/gabrielordonez_ve/ARQUITECTURA_PLC.htm. http://www.oocities.org/gabrielordonez ve/ARQUITECTURA PLC.htm. (Accessed on 06/11/2016).
[Pag95]
Martha Banta Page. Narrative Productions in the Age of Taylor, Veblen, and Ford. University Of Chicago Press, 1995.
[pri09]
Principios de electrónica. MC Graw Hill, 2009.
[pro14]
Processing: A Programming Handbook for Visual Designers and Artists. The MIT Press, 2014.
[Sca]
Scada
InductiveAutomation.com. inductiveautomation.com/scada-software/. (Accessed on 06/14/2016).
[sen05]
Sensores y acondicionadores de señal. MARCOMBO, S.A., 2005.
[Stu]
Stuxnet worm hits Iran nuclear plant staff computers - BBC News. http://www. bbc.com/news/world-middle-east-11414483. (Accessed on 06/12/2016).
Software
-
Ignition
https://www.odoo.com/es ES/.
by
(Accessed on
https://
[SVM01] A. Sangiovanni-Vincentelli y G. Martin. Platform-based design and software design methodology for embedded systems. IEEE Design Test of Computers, 18(6):23–33, Nov 2001. [The]
The Making of Arduino - IEEE Spectrum. http://spectrum.ieee.org/geek-life/ hands-on/the-making-of-arduino. (Accessed on 06/12/2016).
[Tin]
Tinkering Makes Comeback Amid Crisis - WSJ. SB125798004542744219. (Accessed on 06/12/2016).
[ttl03]
Electronic Portable Instruments: Design and Applications. CRC Press, 2003. 233
http://www.wsj.com/articles/
[UNE]
UNESCO. Mondialisation/globalisation | Organisation des Nations Unies pour l’éducation, la science et la culture. http://www.unesco.org/new/ fr/social-and-human-sciences/themes/international-migration/glossary/ globalisation/.
(Accessed on 06/07/2016).
[Wik16] Wikipedia. Desarrollo iterativo y creciente — Wikipedia, La enciclopedia libre, 2016. [Internet; descargado 19-junio-2016]. url: https://es.wikipedia.org/w/ index.php?title=Desarrollo iterativo y creciente&oldid=88610540.
234
Este documento fue editado y tipografiado con LATEX empleando la clase esi-tfg (versión 0.20160704) que se puede encontrar en: https://bitbucket.org/arco group/esi-tfg
[respeta esta atribución al autor]
235