PROYECTO FIN DE CARRERA Título Controlador modular programable, basado en procesador de 32 bits y CAN bus Autor/es Alberto Martínez Inchusta Director/es Javier Esteban Vicuña Martínez Facultad Escuela Técnica Superior de Ingeniería Industrial Titulación Proyecto Fin de Carrera Departamento Ingeniería Eléctrica Curso Académico 2012-2013 Controlador modular programable, basado en procesador de 32 bits y CAN bus, proyecto fin de carrera de Alberto Martínez Inchusta, dirigido por Javier Esteban Vicuña Martínez (publicado por la Universidad de La Rioja), se difunde bajo una Licencia Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported. Permisos que vayan más allá de lo cubierto por esta licencia pueden solicitarse a los titulares del copyright. © © El autor Universidad de La Rioja, Servicio de Publicaciones, 2013 publicaciones.unirioja.es E-mail: [email protected] CONTROLADOR MODULAR PROGRAMABLE BASADO EN PROCESADOR DE 32 BITS Y CAN BUS. TITULACIÓN: Ingeniería Industrial Superior. AUTOR: Alberto Martínez Inchusta. DIRECTOR DEL PROYECTO: Javier Esteban Vicuña Martínez. DEPARTAMENTO: Departamento de Ingeniería Eléctrica. CURSO ACADÉMICO: 2012/2013 Índice General Índice de la memoria. 1. Introducción. .............................................................................................1 2. Objeto ........................................................................................................2 3. Alcance.......................................................................................................3 4. Antecedentes..............................................................................................4 5. Normas y referencias ..................................................................................6 6. Definiciones y abreviaturas.........................................................................8 7. Análisis de soluciones................................................................................10 8. Resultados finales......................................................................................24 9. Posibles vías de ampliación. ....................................................................134 Índice de Anexos. 1. Anexo 1. Características técnicas de los componentes electrónicos usados en el hardware de las placas...............................................................................1 2. Anexo 2. Hardware y software del CAN bus..................................................14 3. Anexo 3. Código de la aplicación SCADA........................................................73 4. Anexo 4. Contenido del cd adjunto. ..............................................................74 Índice de Planos. 1. Plano 1. Entradas digitales............................................................................1 2. Plano 2. Salidas digitales...............................................................................2 3. Plano 3. Entradas analógicas.........................................................................3 4. Plano 4. Estructura hardware del autómata..................................................4 5. Plano 5. Placa principal.................................................................................5 6. Plano 6. Esquema electrónico de las salidas digitales rápidas........................6 7. Plano 7. Esquema electrónico de las salidas digitales a triac..........................7 8. Plano 8. Esquema electrónico de las entradas analógicas. .............................8 9. Plano 9. Esquema electrónico de las entradas digitales..................................9 Índice del pliego de condiciones. 1. Disposiciones Generales...............................................................................1 2. Disposiciones legales y normativa aplicable..................................................4 3. Condiciones facultativas................................................................................6 4. Condiciones de ejecución y montaje..............................................................8 5. Condiciones de materiales y equipos...........................................................28 6. Manual de usuario.......................................................................................34 7. Disposición final...........................................................................................48 Índice de Presupuesto. 1. Introducción.................................................................................................1 2. Mediciones...................................................................................................2 3. Cuadros de precios unitarios.........................................................................4 4. Presupuesto parcial.......................................................................................6 5. Presupuesto total........................................................................................10 Memoria Índice de la memoria. 1. Introducción. ............................................................................................................. 1 2. Objeto ........................................................................................................................... 2 3. Alcance ......................................................................................................................... 3 4. Antecedentes. ............................................................................................................ 4 5. Normas y referencias .............................................................................................. 6 5.1 5.2 5.3 Disposiciones legales y normas aplicadas. ........................................................ 6 Bibliografía. .................................................................................................................. 6 Programas. .................................................................................................................... 7 6. Definiciones y abreviaturas. ................................................................................. 8 7. Análisis de soluciones. ......................................................................................... 10 7.1 Comparativa de soluciones para la placa interfaz. ....................................... 10 7.1.1 Análisis de la plataforma Atmel AVR .......................................................................... 10 7.1.2 Análisis de la plataforma Microchip PIC. ................................................................... 11 7.2 Análisis de soluciones para la estructura del autómata alternativo. ..... 12 7.3 Análisis del protocolo de comunicaciones CAN. ............................................ 15 7.3.1 Elementos que componen el sistema CAN Bus. ...................................................... 16 7.3.2 Proceso de transmisión de datos. ................................................................................. 17 7.3.3 Mensajes y tipos de tramas. ............................................................................................ 18 7.3.4 Formato de tramas. ............................................................................................................. 19 7.3.5 Errores en la comunicación. ........................................................................................... 22 8. Resultados finales. ................................................................................................ 24 8.1 Descripción del hardware. ................................................................................... 24 8.1.1 Placa principal (CPU). ........................................................................................................ 24 8.1.2 Módulos de entrada/salida. ............................................................................................ 27 8.2 Descripción del software. ..................................................................................... 39 8.2.1 Programación formulario Zonas. .................................................................................. 39 8.2.2 Programación del formulario Paso1. .......................................................................... 41 8.2.3 Programación del formulario Controles. ................................................................... 49 8.2.4 Manual de usuario del panel SCADA. .......................................................................... 86 8.3 Descripción de las comunicaciones. .................................................................. 98 9. Posibles vías de ampliación. ............................................................................... 135 Controlador modular programable basado en procesador de 32 bits y CAN bus 1. Introducción. • TITULO: “Controlador modular programable basado en procesador de 32 bits y CAN bus” • EMPLAZAMIENTO: Escuela de Enseñanzas Científicas y Técnicas de la Universidad de La Rioja. • PETICIONARIO: Universidad de La Rioja. • AUTOR DEL PROYECTO. Alberto Martínez Inchusta. Razón Social: Logroño (La Rioja) Director del Proyecto: Javier Esteban Vicuña Martínez, profesor del departamento de Ingeniería Eléctrica de la Universidad de La Rioja. E-­‐mail: [email protected] Memoria. 1 Controlador modular programable basado en procesador de 32 bits y CAN bus 2. Objeto El objeto de este proyecto consiste en el diseño hardware de un controlador lógico programable (PLC), basado en microcontrolador de 32 bits, escalable modularmente por medio de CAN bus y compatible con plataforma ARDUINO, que cuente con prestaciones técnicas equiparables a las de los PLC´s industriales básicos, y también el desarrollo de una aplicación software de código abierto, para el desarrollo de aplicaciones de control y monitorización industrial, como alternativa abierta de bajo coste. Partiendo de que una de las principales premisas es obtener una solución económica, dicho software de supervisión, no requiere de la compra de ninguna licencia para el usuario, más adelante se explicará de manera detenida como se ha llevado a cabo y se entenderá el porqué de esta cualidad tan ventajosa. Así mismo, como la placa del microcontrolador elegida no trabaja con los niveles requeridos en el ámbito industrial, se deberá confeccionar una placa de potencia que nos permita adaptar estos niveles a cualquier planta industrial. Otro de los objetos del presente proyecto es dotar al equipo de control alternativo de la mayor modularidad, para ello se empleará el CAN bus que permitirá ir añadiendo al autómata nuevos módulos (placas microcontroladoras). Como se desprende de las líneas anteriores, con este proyecto se va a conseguir una alternativa fiable a los autómatas programables, tanto a nivel económico como técnico, ya que el microcontrolador de 32 bits elegido junto con la placa de potencia que le acompaña, están a la altura de cualquiera de los PLC´s actuales tanto en coste como prestaciones técnicas. Así mismo, el software de supervisión SCADA desarrollado que se facilita al usuario, le permitirá realizar todas las labores de control y supervisión necesarias para tener el dominio absoluto sobre la planta y todo ello a coste cero, sin la necesidad de adquirir licencias propietarias del fabricante del autómata. Memoria. 2 Controlador modular programable basado en procesador de 32 bits y CAN bus 3. Alcance Se trata de un proyecto de diseño industrial de un sistema prototipo y comprende las etapas de diseño electrónico, diseño de tarjetas PCB, comunicaciones y software de programación de tarjetas chipKIT, junto con el diseño de software de supervisión a través de lenguaje de programació visual, así como su posterior puesta en marcha e integración en las comunicaciones creadas y diseñadas (Puerto USB y CAN Bus). Dada la extensión del proyecto, y los medios disponibles en el departamento, quedan fuera del alcance del mismo la realización física de las tarjetas electrónicas diseñadas para el prototipo, que se encargarían a una empresa especializada. La solución integral de control y supervisión a implementar, es un sistema innovador en la medida que se está trabajando con los componentes electrónicos más novedosos, lo que permite al usuario obtener un producto de tamaño reducido con unos tiempos de procesamiento de datos muy altos. Dicha solución permite disponer en todo momento de información referente al funcionamiento y rendimiento de las instalaciones, así como de las posibles anomalías que puedan producirse. Memoria. 3 Controlador modular programable basado en procesador de 32 bits y CAN bus 4. Antecedentes. PLC son las iniciales de Programmable Logic Controller, que traducido resulta Controlador Lógico programable. También puede ser usado el término Autómata programable para referirse a este tipo de dispositivos. A lo largo de este documento se usará indistintamente cada uno de estos términos. Hace algunos años las soluciones de automatización que se podían encontrar en el mercado pasaban indefectiblemente por el uso de tecnologías cableadas incluyendo relés electromecánicos o módulos lógicos neumáticos entre otros. El uso de esta tecnología resultaba muy caro y voluminoso. A finales de la década de los años 60, consciente de estos problemas, la General Motors encarga el diseño de equipos que cumplieran las siguientes especificaciones: • Flexibles: Debían adaptarse a una gran variedad de situaciones. • Estado sólido: Los nuevos equipos debían estar realizados usando componentes electrónicos. • Ambiente: Debían poder soportar los ambientes industriales. • Sencillos: Debían poder ser programados por personas sin conocimientos informáticos. • Lógicos. La aparición de los PLC´s o autómatas programables, supuso una revolución en este mundo, permitiendo la posibilidad de almacenar una secuencia de órdenes en su interior y ejecutarlo de forma cíclica con el fin de realizar una tarea. El impulso inicial es pensar que se trata de un PC, pero existen múltiples diferencias entre ambos, ya que el PLC está diseñado para trabajar en ambientes industriales y ejecutar su programa de forma indefinida siendo menos propenso a fallos que un ordenador convencional. Además, su programación está más orientada al ámbito electromecánico, incluso existen lenguajes que simulan el comportamiento de un sistema de relés y temporizadores. La generalización del uso de estos PLC ha conllevado la diversificación de los modelos existentes en el mercado. Hoy en día los equipos son capaces de realizar complicadas operaciones, incluso en coma flotante, privilegio disponible hasta hace poco sólo en equipos muy costosos. Además, cada vez es más usual que los autómatas de gama baja sean capaces de gestionar un gran número de entradas y salidas, analógicas o digitales, así como controlar varios encoders por poner un ejemplo. Esta diversificación en los autómatas hace que cada vez se vea más abierto los campos de aplicación de estos, así como las tecnologías de las que se nutre para llevar a cabo su propósito. Memoria. 4 Controlador modular programable basado en procesador de 32 bits y CAN bus En el punto en que se encuentra el mundo de la automatización, lleva a definir el presente proyecto, como un proyecto de fusión de conocimientos que permitan dar luz verde a un sistema de control de bajo coste, con las mismas prestaciones que los actuales autómatas programables. Demostrando que existen alternativas al PLC convencional a la hora de realizar el control sobre distintos procesos industriales. Memoria. 5 Controlador modular programable basado en procesador de 32 bits y CAN bus 5. Normas y referencias 5.1 Disposiciones legales y normas aplicadas. 5.2 Bibliografía. Para la realización del presente proyecto, se ha necesitado acudir a diversas fuentes en busca de información acerca de las diferentes áreas que engloba este proyecto. A continuación, se enumerarán las distintas fuentes consultadas: Páginas Web. • • • • • • • • • • • • • http://msdn.microsoft.com/en-­‐us/library/ms950417.aspx http://www.elguille.info/vb/Libros. http://www.digilentinc.com/ http://www.arduino.cc/ http://es.farnell.com/ http://www.analog.com/en/index.html http://www.fairchildsemi.com http://www.ti.com/ww/en/analog/overview/index.shtml http://www.national.com http://www.onsemi.com http://www.avagotech.com/pages/home/ http://www.comchiptech.com http://www.can-­‐cia.org/ Apuntes. • • Apuntes de la asignatura “Automatización Industrial Avanzada”. Apuntes de “Electrónica analógica”. Libros. • Microcontroladores PIC: sistema integrado para el autoaprendizaje. Memoria. 6 Controlador modular programable basado en procesador de 32 bits y CAN bus 5.3 Programas. • • • • • • • • • • • • Visual basic studio 6.0 Compilador de chipKIT. Microsoft Office. kiCAD Top Solid Photoshop Autocad Fritzing VMware Fusion Wings3D 1.4.1 MWSnap Proteus 7.2 Portable Memoria. 7 Controlador modular programable basado en procesador de 32 bits y CAN bus 6. Definiciones y abreviaturas. Definiciones. • • • • • • • • • • • • Bus CAN: protocolo de comunicaciones desarrollado por la firma alemana Robert Bosch GmbH, basado en una topología bus para la transmisión de mensajes en entornos distribuidos. Código abierto: es el término con el que se conoce al software distribuido y desarrollado libremente. El código abierto tiene un punto de vista más orientado a los beneficios prácticos de poder acceder al código, que a las cuestiones éticas y morales las cuales se destacan en el software libre. Archivo .dll: Bibliotecas de vínculos dinámicos. Microcontrolador: es un circuito integrado programable, capaz de ejecutar órdenes grabadas en su memoria. Está formado por la unidad central de procesamiento, memoria y periféricos de entrada y salida. Framework: Es un conjunto estandarizado de conceptos, prácticas y criterios para enfocar un tipo de problemática particular, que sirve como referencia para enfrentar y resolver nuevos problemas de índole similar. Bit: Es la unidad mínima de información empleada en informática, capaz de representar dos estados, verdadero o falso, activado o desactivado. Byte: Unidad de información formada por 8 bits. Core: Parte principal de los microcontroladores y microprocesadores que se encarga de todo el procesamiento. Está formado por los registros, la unidad de control, la unidad aritmético lógica y los buses. Compilador: Programa informático que traduce el código fuente escrito en un lenguaje de programación a otro lenguaje de programación de menor nivel, generando un programa equivalente que la máquina sea capaz de interpretar. Normalmente al lenguaje al que se compila suele ser a lenguaje máquina. DIP: Empaquetado en el que se pueden fabricar los chips, consistente en dos filas paralelas de pines distribuidas a lo largo del empaquetado y con una separación de 0,1 pulgadas entre ellos. Shield: En el mundo relacionado con Arduino, se refiere a la placa que se conecta encima de éste para ampliar sus capacidades tanto de procesamiento, como de control o interfaz. Bootloader: Porción de código almacenado en una zona especial de la flashdel microcontrolador que le permite ejecutarse en cada inicio. Normalmente es utilizado para poder programar el microcontrolador a través del puerto serie en vez de con un programador especializado. Memoria. 8 Controlador modular programable basado en procesador de 32 bits y CAN bus Abreviaturas. • • • • • • • • CAN : Controller área Network. PIC: Peripheral interface Controller. H: High L: Low ACK: Acknowledgement. USB: Universal Serial Bus. SCADA: Supervisory Control And Data Acquisition PLC: Programmable Logic Controller Memoria. 9 Controlador modular programable basado en procesador de 32 bits y CAN bus 7. Análisis de soluciones. 7.1 Comparativa de soluciones para la placa interfaz. La interacción con el mundo físico se realizará a través de un microcontrolador con una cantidad aceptable de pines disponibles para el uso del cliente, salidas PWM, entradas digitales y analógicas, temporizadores, etc. que ofrezcan un gran abanico de posibilidades. Dichas placas electrónicas deberán reunir una serie de posibilidades, tales como: • • • • Alta disponibilidad por parte de los distribuidores a nivel mundial. Así mismo, es interesante que dichos componentes electrónicos no se encuentren en proceso de descatalogación o que sean susceptibles en un corto plazo de ser descatalogados. Precio reducido, incluso en bajas cantidades, con una relación funcionalidad/precio alta. Baja cantidad de electrónica adicional necesaria para el funcionamiento del microcontrolador. 7.1.1 Análisis de la plataforma Atmel AVR La arquitectura AVR, perteneciente a Atmel, es de 8 bits y fue diseñada desde el comienzo para una eficiente ejecución de código C compilado. ARDUINO. Dicha arquitectura ha sufrido un incremento en popularidad como consecuencia del lanzamiento de la plataforma Arduino, lo que garantiza una gran cantidad de documentación, ejemplos de código y una comunidad de usuarios densamente poblada. Arduino puede entenderse como un conjunto de librerías que facilitan en gran medida el desarrollo en la plataforma AVR, las cuales presentan una gran facilidad de uso. Así mismo, Arduino también es una sencilla placa de desarrollo, que puede encontrarse en cualquier distribuidor de electrónica del mundo debido a su gran popularidad. Su precio alterna entre los 18 o 26 euros según modelo y distribuidor. Una de las ventajas más destacadas y la razón por la que Arduino eligió la plataforma AVR, es la existencia del compilador libre basado en GCC denominado avr-­‐gcc. Memoria. 10 Controlador modular programable basado en procesador de 32 bits y CAN bus Ventajas • Compilador libre y gratuito. • Gran comunidad de usuarios y cantidad de información gratuita. Desventajas • Precio. 7.1.2 Análisis de la plataforma Microchip PIC. Microchip con su familia de microcontroladores PIC, ha estado liderando el mercado del desarrollo de proyectos personales a través del programa de muestras de Microchip. Sus compiladores junto con las librerías, son gratuitos o en algunos casos poseen un límite de compilación, sin embargo, poseen licencias con cláusulas que dificultan la distribución del código fuente en según qué casos. PINGÜINO. Pingüino nace como consecuencia de la idea de una serie de desarrolladores de portar las librerías Arduino a la arquitectura PIC. Aunque funcionales, estas librerías no presentan el mismo nivel de desarrollo ni de fiabilidad que las de Arduino. Sin embargo, continuando con el programa de muestras Microchip, consiguió formar una sólida base de usuarios. chipKIT. De una colaboración entre Digilent y la propia Microchip nace chipKIT, la alternativa real a Arduino, consiguiendo portar con fiabilidad las liberías de Arduino e intentando mantenerlas a la par con respecto a estas. Una de los problemas que se planteaban, estaba en la línea del compilador, ya que aunque el entorno de desarrollo era el mismo que el de Arduino, su compilador poseía el inconveniente de no ser libre al seguir usando los propietarios ya existentes. Más tarde, como solución a este problema, se liberó parte del compilador para su uso con las placas chipKIT. Sin embargo, como gran ventaja, chipKIT posee un microcontrolador de 32 bits, lo que posibilita realizar aquellos trabajos que requieren una gran cantidad de procesamiento con respecto al micro de 8 bits de Arduino. Ventajas • Microcontrolador de 32 bits. • API exactamente igual que la de Arduino. • Provee de dos controladores CAN Desventajas • Compilador no libre del todo. • Pequeña comunidad de usuarios. Memoria. 11 Controlador modular programable basado en procesador de 32 bits y CAN bus 7.2 Análisis de soluciones para la estructura del autómata alternativo. La estructura interna de los autómatas programables puede ser descrita en cinco bloques: El bloque de entradas, es el encargado de recibir las señales procedentes de los sensores. Además, estas señales deberán de ser adaptadas para su comprensión por parte de la CPU. También tiene como misión proteger los circuitos internos del PLC. Por su parte, el bloque de salidas es un concepto inverso al anterior, de manera que su misión es interpretar las órdenes de la CPU, descodificarlas, amplificarlas y enviarlas a los actuadores. La CPU, puede definirse como la unidad en la que reside la inteligencia del sistema, de forma que en base a las instrucciones programadas y el valor de las entradas, activa las salidas. Así mismo, cualquier PLC requiere de una fuente de alimentación que sea capaz de adaptar las tensiones a los valores necesarios para los dispositivos electrónicos internos. Por último, nombrar a los interfaces, que son los canales de comunicación con el exterior. Figura 1) Estructura de los autómatas convencionales. Partiendo de la estructura interna que presentan los autómatas programables convencionales, se plantean tres soluciones posibles para el equipo de control alternativo del presente proyecto. En primer lugar se enumerarán cada una de ellas y posteriormente se pasará a realizar un análisis más profundo. La primera propuesta y la más sencilla de implementar, estaría basada en una placa de desarrollo chipKIT MAX32, en la que se delimitarían el número de entradas y salidas tanto digitales como analógicas, emulando así a los autómatas compactos. Memoria. 12 Controlador modular programable basado en procesador de 32 bits y CAN bus En segundo lugar, de nuevo se partiría de una única placa de desarrollo chipKIT MAX32, sin embargo, en este caso la placa de potencia se diseñaría bajo una idea de autómata modular (aunque no en el sentido amplio de la palabra), dando al usuario la posibilidad de decidir el número de entradas analógicas o digitales que desee, así como el tipo de cada una de ellas. En la tercera solución, es cuando se plantea un diseño plenamente modular, en la que se utilizarían tantas placas de desarrollo chipKIT MAX32 como el usuario desee o necesite para llevar a buen puerto su instalación industrial. Como se ha citado al principio, en esta primera parte del análisis únicamente se está realizando una enumeración y será en la parte posterior cuando el lector comprenda mejor cada una de las propuestas. PRIMERA PROPUESTA. Esta primera solución, es una idea muy primitiva pero eficaz, basada en una placa chipKIT 32MAX, la cual aporta una gran cantidad de pines, en concreto, 16 entradas analógicas, 5 salidas digitales y 57 entradas/salidas digitales. De manera que el diseñador delimitaría el número de entradas y salidas que poseería el equipo de control, obteniendo como resultado un elemento estanco, cuyo inconveniente principal aparecería en el supuesto caso de que el usuario necesitaría simplemente una entrada digital más que las dispuestas, lo que haría desechar la opción de uso de este tipo de dispositivos de control. Por lo tanto, en caso de tomar la decisión de diseñar bajo estas premisas, se estaría limitando el campo de aplicación de estos dispositivos de control, a aquellas instalaciones que no superarían el número de entradas y salidas ofertadas. De hecho, este es el único inconveniente a esta solución, ya que si se analiza la capacidad del microprocesador, se observa que con esos tiempos de procesamiento se puede dar respuesta a cualquier tipo de proceso a controlar. Además, con el mero hecho de seleccionar los componentes electrónicos oportunos (de la placa de potencia) para igualar los tiempos de conmutación de los PLC convencionales, estaríamos ante una gran solución al problema del presente proyecto. Además, con esta disposición se tienen los cinco bloques principales de los autómatas programables en una placa de un tamaño mucho más reducido que el de los autómatas programables estándar. SEGUNDA PROPUESTA. La segunda opción también requiere de una única placa de desarrollo chipKIT 32MAX, a la que como se dijo en la primera parte de este análisis se le pretende conferir el mayor grado (dentro de las posibilidades que ofrece esta disposición) de adaptabilidad para el usuario. Memoria. 13 Controlador modular programable basado en procesador de 32 bits y CAN bus Para ello, la placa de potencia se debería diseñar de tal manera, que exista una placa principal, la cual posea una serie de zócalos en los que se insertarían los diferentes módulos de entradas y salidas. Estos módulos de entradas y salidas, serían placas secundarias que poseerían una cantidad concreta de entradas o salidas, emulando a los módulos de entradas y salidas que se pueden adquirir a cualquier fabricante de autómatas. De esta manera, se tendría la placa principal unida a la chipKIT 32MAX y posteriormente se le irían incluyendo placas secundarias en función de las necesidades del usuario. Con esto se obtiene una solución mucho más modulable que la anterior, sin embargo, el problema principal que se presentaba en la primera propuesta sigue sin subsanarse. TERCERA PROPUESTA. Es con esta tercera propuesta con la que se elimina el problema que aparece a lo largo de este análisis. Esto se consigue dotando a esta tercera solución de la cualidad de modulable en el sentido amplio de la palabra. Para ello se requiere de varias placas de desarrollo chipKIT 32MAX, en concreto como mínimo serán necesarias dos chipKIT. La primera de ellas realizará las labores de la CPU, y la otra emulará a los bloques de entradas y salidas de los autómatas convencionales. Es decir, la primera placa (CPU), albergará el programa de control, así como las instrucciones necesarias para controlar las distintas comunicaciones y las posteriores placas, serán idénticas a las descritas en la segunda propuesta, pudiendo añadir tantas placas como se quiera (en función de las necesidades del cliente), por lo que obviamente con esta nueva disposición se evita el problema del límite de entradas/salidas. Figura 2) Estructura del autómata alternativo. Memoria. 14 Controlador modular programable basado en procesador de 32 bits y CAN bus Esta solución parece la más correcta y así lo es, sin embargo complica mucho más la labor del diseñador, ya que requiere de un enlace de comunicación entre las diferentes placas, que se pasará a analizar en el siguiente punto. 7.3 Análisis del protocolo de comunicaciones CAN. El protocolo de comunicaron CAN (Controller Area Network) fue desarrollado en los años 80 para resolver problemas de comunicación entre los diferentes sistemas de control de los coches. Debido a su robustez, la idea no tardó en pasar al sector de la automatización y control. El CAN bus es un protocolo serie asíncrono del tipo CSMA/CD. Al ser CSMA, cada nodo de la red debe monitorizar el bus y si detecta que no existe actividad, puede enviar un mensaje. Así mismo, al ser CD, si dos nodos de la red comienzan a transmitir a la vez un mensaje, ambos detectan la colisión, dicho problema se resuelve mediante el uso de las prioridades que más tarde se explicarán. El medio físico que permite la circulación de la información entre los distintos nodos, es un par de cables trenzados. La impedancia característica de la línea es del orden de 120 ohmios, por lo que se emplean resistencias de este valor en ambos extremos del bus para evitar ondas reflejadas y que el bus se convierta en una antena. Este bus tiene una longitud máxima de 1000 metros a 40 Kbps, con una velocidad máxima de 1Mbps a 40 metros. Entre los distintos nodos circulan paquetes de ceros y unos con una longitud limitada y con una estructura definida en campos que conforman el mensaje. Uno de estos campos identifica el tipo de dato que transporta, así como la unidad que lo transmite y la prioridad para transmitirlo con respecto a otros. En realidad, el mensaje no va direccionado a ninguna unidad de mando en concreto, sino que cada una de ellas deberá ser capaz de reconocer mediante el identificador si el mensaje le interesa o no. Todas las unidades de la red pueden ser transmisoras y receptoras, y el número de módulos conectados es variable, en función de las necesidades de la instalación. Como ya se ha dicho anteriormente, si no se cumple la condición de que el bus este libre, el módulo no podrá introducir un mensaje en el bus. En el supuesto caso, de que dos módulos intenten transmitir, el conflicto se resolverá mediante las prioridades, que están marcadas por el identificador. De tal manera, que aquel nodo con el identificador más bajo, será el que mayor prioridad tenga para transmitir. Obviamente, el sistema está dotado de una serie de mecanismos que aseguran que el mensaje es transmitido y recibido correctamente. En el momento que un mensaje presenta un error, es anulado y vuelto a transmitir de manera automática. Así mismo, en caso de que un nodo presente problemas, lo comunica al resto de integrantes de la red, si la situación no se soluciona, este nodo se verá excluido de la comunicación, pero esto no significa que la red no siga funcionando. Memoria. 15 Controlador modular programable basado en procesador de 32 bits y CAN bus Este protocolo se encuentra estructurado de acuerdo con el modelo OSI en una arquitectura de dos capas, la capa física y la capa de enlace de datos. El resto de capas del modelo OSI (red, transporte, sesión, presentación y aplicación) no están especificadas pero hay que diseñarlas. Sobre todo es de vital importancia especificar un protocolo de alto nivel (HLP). Entre las características principales del bus CAN, aparecen algunas como: • • • • • • • • Priorización del mensaje. Comunicación basada en mensajes y no en comunicaciones. Garantía de los tiempos de retardo. Flexibilidad de la configuración. Recepción múltiple con tiempos de sincronización. Robustez en sistemas de amplios datos. Sistema multimaestro. El límite de nodos, lo marca el hardware. 7.3.1 Elementos que componen el sistema CAN Bus. Cables. La información circula a través de dos cables trenzados que unen los diferentes nodos que conforman el sistema. Esta información es transmitida por diferencia de tensión entre ambos cables, de tal manera que un valor alto de tensión representa un uno y un valor bajo de tensión representa un cero. La combinación de unos ceros, forman las tramas que circulan a lo largo de la red. En un cable los valores de tensión oscilan entre 0 y 2,25 voltios, por ello es denominado como cable L (Low). En el otro cable, los valores de tensión son superiores (entre 2,75 y 5 voltios), por lo que se denomina H, del acrónimo de High. En el supuesto caso de que se interrumpa la línea H o se derive a masa, el sistema trabajara con la señal L con respecto a masa, en el caso de interrumpirse la línea L, sucedería lo contrario. Figura 3) Par trenzado. Elementos de cierre o terminador. Físicamente estos elementos son unas resistencias, que se colocan en los extremos de los cables H y L. Sus valores son habitualmente de 120 ohmios y se colocan con el objetivo de adecuar el funcionamiento del sistema a diferentes longitudes de cables y número de módulos conectados, ya que impiden posibles efectos parásitos que pueden corromper el mensaje. Memoria. 16 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 4) Cierre o terminador. Controlador. Es el elemento encargado de la transmisión entre el microprocesador del módulo y el transmisor-­‐receptor. Trabaja acondicionando la información que entra y sale entre ambos componentes. Existirá un controlador por nodo, y entre sus labores principales se encuentra la determinación de la velocidad de los mensajes, así como la sincronización entre los diferentes módulos para la correcta emisión y recepción de los mensajes. Figura 5) Controlador. Transmisor/Receptor. El transmisor-­‐receptor es el elemento que tiene como misión recibir y transmitir los datos, además de acondicionar y preparar la información para que pueda ser utilizada por los controladores. Esta preparación consiste en situar los niveles de tensión de forma adecuada, amplificando la señal cuando la información se vuelca en la línea y reduciéndola cuando es recogida de la misma y suministrada al controlador. 7.3.2 Proceso de transmisión de datos. Como ya se ha descrito más arriba, el CAN bus está orientado hacia el mensaje y no al destinatario. La información que circula por el par trenzado es transmitida en forma de mensajes estructurados, de tal manera que una parte del mismo es un identificador que establece la clase de dato que contiene. Por su parte, cada uno de los módulos reciben el mensaje, lo filtran y únicamente lo emplean aquellos que necesitan dicho dato. Obviamente, cada uno de estos módulos es capaz de introducir como de recoger mensajes. Así mismo y sin ánimo de ser repetitivo, destacar que en el caso de que el bus este libre, cualquier módulo puede comenzar a transmitir. Este proceso de transmisión de datos requiere del desarrollo de varios pasos que serán explicados a continuación. Memoria. 17 Controlador modular programable basado en procesador de 32 bits y CAN bus Suministro de datos. Un módulo recibe información de los sensores que tiene asociados y posteriormente su microprocesador pasa la información al controlador donde es gestionada y preparada para ser pasada al transmisor-­‐receptor donde se traducirá en señales eléctricas. Transmisión de datos. El controlador de los módulos transfiere los datos, el identificador y la petición de inicio de transmisión, con el objetivo de transmitir de manera correcta el mensaje a lo largo de la red. Para conseguir el citado objetivo, el bus debe de encontrarse libre y en el hipotético caso, de encontrarse en conflicto con otro módulo, ha de tener mayor prioridad. Una vez logrado el objetivo, el resto de nodos se convierten en receptores a la espera del mensaje, siempre y cuando este les sea de interés. Recepción del mensaje. Cuando todos los módulos se posicionan en estado de escucha, reciben el mensaje y a continuación verifican el identificador con el objetivo de determinar si el mensaje va a ser utilizado por ellos. De esta manera, aquellos que necesitan el mensaje lo procesan y aquellos que no lo necesitan simplemente lo ignoran. El protocolo CAN dispone de mecanismos para detectar errores en la transmisión de mensajes, de forma que todos los receptores realizan un chequeo del mensaje analizando una parte del mismo, llamado campo CRC. 7.3.3 Mensajes y tipos de tramas. Al igual que todas las comunicaciones de este tipo, el mensaje es una sucesión de ceros y unos, que se representan por distintos niveles de tensión en los cables del CAN. CAN utiliza mensajes con una estructura predefinida, que en una jerga más coloquial se conocen como tramas. Se distinguen dos variantes de tramas CAN, las definidas en CAN estándar y las definidas en el CAN extendido. La diferencia sustancial entre ambas tramas viene impuesta por el número de bits que emplea para el identificador, requiriendo la primera 11 bits y la segunda 29 bits. Las tramas CAN son de longitud reducida, la más larga es de 130 bits en CAN estándar y 154 bits en CAN extendida. En un bus Can existe la posibilidad de enviar las tramas de una manera automática, ya sea ante la aparición de un suceso o por un proceso realizado durante una cierta frecuencia. Memoria. 18 Controlador modular programable basado en procesador de 32 bits y CAN bus La trama de interrogación remota es empleada únicamente para detectar la presencia de módulos o para configuración de información en un módulo recién incorporado a la red. Las tramas principales que son manejadas en el CAN bus son: Trama de datos La que un módulo utiliza normalmente para poner información en el bus. Puede incluir entre 0 y 8 bytes de información útil. Trama de interrogación remota. Puede ser utilizada por un módulo para solicitar la transmisión de una trama de datos con la información implicada a un identificador dado. El módulo que disponga de la información definida por el identificador la transmitirá en una trama de datos. Trama de error. Se usan para señalar al resto de módulos la detección de cualquier error, impidiendo normalmente el mensaje erróneo 7.3.4 Formato de tramas. El mensaje se descompone en varios campos de diferentes tamaños, gracias a los cuales es posible llevar a cabo el intercambio de información entre los distintos nodos. Trama de datos. Figura 6) Trama de Bus CAN. Campo de inicio del mensaje. El mensaje se inicia con bit dominante, cuyo flanco descendente es utilizado por los módulos para sincronizarse entre si. Campo de árbitro. Los 11 bits de este campo se usan como identificador que permite reconocer a los módulos su prioridad. De esta manera, cuanto más bajo sea el valor del identificador más alta es la prioridad, y por lo tanto, determina el orden en que van a ser introducidos los mensajes en la línea. El bit RTR indica si el mensaje contiene datos (RTR = 0) o si se trata de una trama remota sin datos (RTR = 1). Campo de control. Este campo informa sobre las características del campo de datos. El bit IDE indica cuando es un “0” que se trata de una trama estándar (BasicCAN, 11bits) y cuando es un “1” que es una trama extendida. El segundo bit (RB0) es siempre recesivo. Los cuatro bits que componen el campo DLC indican el número de bytes contenido en el campo de datos (0 a 8). Memoria. 19 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 7) Campo de control. Campo de datos. En este campo aparece la información del mensaje con los datos que el módulo correspondiente introduce en la línea CAN. Puede contener entre 0 y 8 bytes. Figura 8) Campo de datos. Campo de aseguramiento. Este campo tiene una longitud de 16 bits y se utiliza para detectar errores por los 15 primeros, mientras que el último siempre será un bit recesivo para delimitar el campo CRC. Figura 9) Campo de aseguramiento. Campo de confirmación (ACK). El campo ACK se compone de dos bits que son siempre transmitidos como recesivos. Todos los módulos que reciben el mismo CRC modifican el primer bit del campo ACK por uno dominante, de forma que le módulo que esta todavía transmitiendo reconoce que al menos un módulo ha recibido un mensaje que se ha escrito correctamente. De no ser así, el módulo transmisor interpreta que su mensaje tiene un error. Figura 10) Campo de confirmación ACK. Campo de final del mensaje. Este campo indica el final del mensaje con una cadena de 7 bits recesivos. Figura 11) Campo de final del mansaje. Espaciado entre tramas (IFS). Consta mínimo de tres bits. Memoria. 20 Controlador modular programable basado en procesador de 32 bits y CAN bus Trama remota. El formato es idéntico al de la trama de datos, salvo por la diferencia de que el bit RTR es recesivo. Así mismo volver a destacar que una trama remota no incluye datos y que el identificador es el del mensaje que se solicita. Figura 12) Trama remota. Trama de error. Las tramas de error son generadas por cualquier módulo que detecta un error. Consiste en dos campos: Indicador de error ("Error Flag") y Delimitador de error. El delimitador de error consta de 8 bits recesivos consecutivos y permite a los módulos reiniciar la comunicación de nuevo tras el error. El indicador de error varía según el estado de error: • • Si un módulo en estado de error "Activo" detecta un error en el bus interrumpe la comunicación del mensaje en proceso generando un "Indicador de error activo" que consiste en una secuencia de 6 bits dominantes sucesivos. Esta secuencia rompe la regla de relleno de bits y provocará la generación de tramas de error en otros módulos. Por tanto el Indicador de error puede extenderse entre 6 y 12 bits dominantes sucesivos. Finalmente se espera el campo que delimita el error formado por los 8 bits recesivos. Entonces la comunicación se reinicia y el módulo que había sido interrumpido reintenta la transmisión del mensaje. Si un módulo en estado de error "Pasivo" detecta un error, el módulo transmite un "Indicador de error pasivo" seguido, de nuevo, por el campo delimitador de error. El indicador de error de tipo pasivo consiste en 6 bits recesivos seguidos y, por lo tanto, la trama de error para un módulo pasivo es una secuencia de 14 bits recesivos. De aquí se deduce que la transmisión de la trama de error de tipo pasivo no afectará a ningún módulo en la red, excepto cuando el error es detectado por el propio módulo que está transmitiendo. En ese caso los demás módulos detectaran una violación de las reglas de relleno y transmitirán a su vez tramas de error. Tras señalar un error por medio de la trama de error apropiada cada módulo transmite bits recesivos hasta que recibe un bit también recesivo, luego transmite 7 bits recesivos antes de finalizar el tratamiento de error. Arbitraje. Memoria. 21 Controlador modular programable basado en procesador de 32 bits y CAN bus Un módulo transmisor monitoriza constantemente el estado del bus. Durante la transmisión del campo Arbitraje la detección de un bit dominante, cuando el bit transmitido ha sido recesivo, hace que el módulo detenga la transmisión y pase a recepción de trama. Así, no se pierde información y no se destruye por colisión ninguna trama de datos o remota. En un bus único un identificador de mensaje ha de ser asignado a un solo módulo concreto, es decir, se ha de evitar que dos módulos puedan iniciar la transmisión simultánea de mensajes con el mismo identificador y datos diferentes. La filosofía CAN se basa en que un mensaje es único en el sistema. Las tramas remotas con identificador concreto que puedan ser generadas por cualquier módulo han de coincidir en cuanto al campo longitud + longitud del campo de datos + contenido de estos datos, el mensaje ha de ser único en el sistema y estar asignado a un módulo concreto. Figura 13) Acceso al bus CAN. 7.3.5 Errores en la comunicación. Aunque como ya se ha citado anteriormente, los sistemas de seguridad que incorpora CAN bus lo convierten en uno de los protocolos de comunicación más robustos. Puede darse el caso, de que exista algún mal funcionamiento, que requiere un proceso de gestión. No se utilizan mensajes de ACK, los errores se señalizan cuando ocurren. A nivel de trama hay tres mecanismos posibles: usar CRC, chequeo de formato de trama, y los receptores señalizando las tramas recibidas forzando el bit ACK a dominante, y en caso de que esto no ocurriese, significaría un error en ACK. A nivel de bit se implementan dos mecanismos, la monitorización, donde el transmisor puede monitorizar el bus para observar si lo que envía es lo que aparece en el bus. Esto detecta errores globales y locales al transmisor, y el bit stuffing. Si se detecta algún error, al menos la estación aborta la transmisión mediante el envío de una trama de error. Tras esta trama, el transmisor reintenta el envío. Una estación defectuosa podría abortar mensajes correctos, lo que podría bloquear el bus. El protocolo CAN aporta un mecanismo para diferenciar errores esporádicos y permanentes: un análisis estadístico de las situaciones de error. Si una estación detecta un estado permanente de error, entra en un estado de Memoria. 22 Controlador modular programable basado en procesador de 32 bits y CAN bus operación que el resto de la red CAN puede seguir funcionando, debiendo poder auto desconectarse para que este mecanismo funcione. Memoria. 23 Controlador modular programable basado en procesador de 32 bits y CAN bus 8. Resultados finales. 8.1 Descripción del hardware. En el apartado 7.2 del presente proyecto se planteaban tres posibles soluciones con las que implementar el equipo de control alternativo. Como se deduce de dicho análisis, la tercera solución es la más modulable y por lo tanto la solución a adoptar. Dicha solución esta compuesta por varios elementos que se enumerarán y describirán a continuación: • • Placa principal (CPU), chipKIT MAX32. Placas secudarias (módulos de entrada/salida) chipKIT 32MAX junto a sus respectivas placas de potencia. Figura 14) Estructura hardware del autómata. 8.1.1 Placa principal (CPU). Dicha placa principal, tendrá como misión coordinadar las comunicaciones y ejecutar ciclicamente el programa de control, de manera que en función de los valores de las entradas y de las variables internas, ordenara activarse las salidas que correspondan. Debido a que no debe leer ni escribir nada por sus pines no requerirá de una placa que adapte sus niveles. La placa de desarrollo elegida para esta misión es el chipKIT MAX32 que presenta en su interior un PIC de 32 bits altamente capacitado para esta labor. Además, su integración en ambas redes de comunicaciones no requiere de hardware adicional (a excepción del transceiver MCP2551, cuyo coste es despreciable) ya que posee dos controladores de CAN y un puerto USB 2.0. Memoria. 24 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 15) Descripción de todas las patillas del chip (PIC32MX795F512L). Figura 16) Descripción de las patillas del chipKIT MAX32 1. Conector USB, para convertir de USB serie. 2. Conector de herramientas de depuración de microchip. 3. Conector de alimentación externa. 4. Fuente de alimentación (regulador de 3,3 V). 5. Puente de selección de alimentación. 6. Fuente de alimentación (regulador de 5 V). 7. J2 Conector shield. 8. Microcontrolador principal de la placa PIC32. 9. J5, J7 conectores de señal analógica. 10. J6, J8, J9 y J15 señal digital y alimentación. 11. LED de usuario. 12. JP3/JP4 Selección de puente maestro/esclavo SPI. 13. J13 conector de señal SPI. 14. J3, J4, J14 conector de señal digital. Memoria. 25 Controlador modular programable basado en procesador de 32 bits y CAN bus 15. Estado comunicaciones LED. 16. Botón RESET. Algunas de las características más destacables son: Reloj: Ofrece varias opciones de configuración de la frecuencia de oscilación, permitiendo al usuario escoger según se adapte a sus necesidades: • • • • • • • • Utilizando un cristal o un resonador cerámico y conectándolos a los pines OSC1 y OSC2 del PIC. El sistema de oscilador tiene las siguientes características: Como fuente oscilador de reloj tiene cuatro opciones internas y externas. En el chip tiene un interruptor que manipula el usuario de divisor y multiplicador de entrada y también un divisor de salida para aumentar la frecuencia de operación al seleccionar las fuentes internas y externas. Fuente de reloj se puede controlar por software. A prueba de fallos, detecta los fallos de reloj y permite la recuperación de aplicaciones de seguridad. El modulo del oscilador se compone de unos registros de funciones especiales: -­‐ OSCCON: registro de control del oscilador. -­‐ OSCTUN: registro de ajuste de FRC -­‐ REFOCON: registro de control de la referencia del oscilador. -­‐ REFOTRIM: registro de trim de la frecuencia del oscilador. • También tenemos los registros de configuración del dispositivo -­‐ DEVCFG1: Palabra de configuración de dispositivo 1. -­‐ DEVGFG2: Palabra de configuración de dispositivo 2. Memoria de datos: Tiene 128 Kbytes de memoria RAM. Memoria de programa: Tiene 512 kbytes de memoria Flash. Periféricos: El Max32 ofrece 83 pines I/O que soportan un número de funciones periféricas, como UART, SPI y puertos I2C y salidas de ancho de pulso modulado. Dieciséis de los pines I/O se pueden utilizar como entradas analógicas o como entradas y salidas digitales. El microcontrolador PIC32 en el Max32 también proporciona un 10/100 Ethernet MAC, USB 2.0 completo, un regulador de velocidad OTG, y dos controladores CAN. El uso de estos periféricos avanzados requiere una tarjeta Memoria. 26 Controlador modular programable basado en procesador de 32 bits y CAN bus adicional (por ejemplo, el Digilent Red Shield) para proporcionar el hardware adicional que se requiere. El Max32 puede ser alimentado a través de USB y externamente con un adaptador de corriente AC-­‐DC o baterías. 8.1.2 Módulos de entrada/salida. Las placas secundarias son los módulos que aparecen en cada uno de los nodos de la red CAN. Estas placas serán las encargadas de dar órdenes a los actuadores y de obtener a través de sus pines la información que les transmita los sensores. Como consecuencia de su labor, requieren de una placa de potencia que adapte los niveles al ámbito industrial. La citada placa de potencia presenta dos partes, por un lado una placa principal, la cual posee una serie de zócalos en los que se insertarán los diferentes módulos de entradas y salidas. Estos módulos serán placas secundarias que poseerán una cantidad concreta de pines, emulando a los módulos de entradas y salidas que se puede adquirir a cualquier fabricante de autómatas. De esta manera, se tendrá la placa principal unida a la chipKIT 32MAX y posteriormente se le irán incluyendo placas secundarias en función de las necesidades del cliente. Placa principal. El aspecto de la placa principal es el de la imagen inferior, en ella se pueden observar los distintos zócalos que albergarán los módulos de entradas/salidas, así como los diferentes componentes electrónicos que forman: • • • La fuente de alimentación de los módulos. El hardware de las cinco salidas analógicas. Los switch para indicar el número de módulo en la red CAN Memoria. 27 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 17) Simulación en 3D de la placa principal que albergará los módulos de entrada/salida junto al chipKIT. El chipKIT será acoplado a la placa principal a través de los pin head, que se encuentran dispuestos de tal manera que la placa de desarrollo encaje perfectamente. El esquema electrónico de la fuente de alimentación es el siguiente: Figura 18) Circuito electrónico de la fuente de alimentación. Dicho circuito electrónico esta compuesto principalmente por dos reguladores, un LM7815 y un MC7915, que convierten los +/-­‐ 24 voltios a +/-­‐ 15 voltios. El coste de dicha fuente de alimentación ronda un euro. El hardware de las salidas analógicas amplifica a 24 voltios las señales de 3.3 voltios que saca el chipKIT. Para ello se empleará el driver FOD8321 dispuesto de la siguiente manera. El coste de las cinco salidas analógicas ronda los cinco euros. Memoria. 28 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 19) Circuito electrónico de una salida analógica. Placas secundarias. Existe varios modelos de este tipo de placas, entre las que se encuentran: • • • • Módulos de cuatro entradas analógicas. Módulos de siete entradas digitales tipo PNP Módulos de seis salidas digitales de alta velocidad. Módulos de salidas de alterna. Los módulos de cuatro entradas analógicas constan de varios bloques que permiten adaptar los niveles procedentes de los sensores analógicos a los valores con los que trabaja chipKIT. Su precio es el más caro de todos los módulos, rondando los 50 euros. Sin embargo, los componentes con los que ha sido diseñado le permite competir de manera directa en el mercado actual. A continuación se muestra una visión general del módulo junto con su modelo en 3D. Figura 20) Simulación en 3D de los módulos de entradas analógicas. Memoria. 29 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 21) Bloques que componen los módulos de entradas analógicas. Los micro-­‐switches que se observan en el modelo en 3D, permiten al usuario seleccionar si el sensor analógico con el que se esta trabajando, aporta una señal de 4-­‐20 mA (intensidad) o por el contrario aporta voltajes. Estos pulsadores conmutan el analog-­‐switch (ADG 5413), de tal manera que direccionan la señal del sensor hacia el bloque de adaptación de intensidad-­‐voltaje o hacia el bloque de reducción de voltajes. El primero de los bloques convierte los mA en voltios, de tal manera que si aparece en los borneros 4mA el micro recibirá cero voltios y si aparece 20 mA el micro recibirá 3.3 voltios. Este circuito electrónico esta basado en el RCV420KP y presenta la siguiente estructura: Figura 22) Circuito electrónico que convierte intensidad a tensión. Por su parte, el segundo de los bloques, convierte los 48 voltios en 3.3 a través de un amplificador inversor. Como en realidad lo que hace este amplificador es pasar de 48 voltios a -­‐3.3 voltios, es necesario invertir de nuevo la señal y esto se realiza mediante un transistor. Memoria. 30 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 23) Circuito electrónico que disminuye la tensión hasta 3.3 voltios. El siguiente analog-­‐switch (AD7512 DIKN) comandado por los microswitch a los que se ha hecho referencia más arriba, recogerá la señal o bien del primer bloque o bien del segundo en función de los indicado por el usuario a través de estos elementos. Esta señal adaptada ya a sus niveles de trabajo será la que recibirá el chipKIT. ENTRADAS ANALÓGICAS Número de Entradas 4 Rango de voltajes de entrada(V) 9÷40 v Retraso de señal a ON 202 ns Retraso de señal a OFF 140 ns Voltaje a salida máximo de estado OFF 0.8 v Voltaje a salida mínimo de estado ON 3.3 v Intensidad máxima de entrada 30 mA Rango de temperaturas -­‐25÷85 ºC Precio 50 euros Figura 24) Especificaciones técnicas de los módulos de entradas analógicas. La electrónica bajo la que se ha diseñado los módulos de entradas digitales, reduce el voltaje que llega de los sensores (aportando un 0 si aparece menos 5.1 voltios y 3.3 voltios cuando es superior a la cifra anterior) y además, aisla al chipKIT de picos de tensión que podrían destruir la placa de desarrollo. Su precio ronda los siete euros. El circuito electrónico queda de la siguiente manera. Figura 25) Circuito electrónico que aisla y adapta niveles. Memoria. 31 Controlador modular programable basado en procesador de 32 bits y CAN bus Como se observa, el optoacoplador 4N25 es el encargado de aislar la placa chipKIT del medio exterior. El circuito que se encuentra a su izquierda esta formado por dos resistencias, un diodo led y un zener. La misión del zener es regular la tensión entre sus extremos, de tal manera que entre esos dos puntos siempre aparezca 5.1 voltios. Como el optoacoplador únicamente requiere 1.5 voltios para conducir, reparto los 3.8 voltios entre el diodo led y la resistencia. 5.1 = 2.2 + 1.5 + R2 * 10mA à R2 = 140 ohmios 48 = 60mA * R1 + 2.2+ 140 * 10mA + 1.5 à R1 = 715 ohmios Vout = 5 * R3 / (R5 + R3) à R5 = 5,1 K A la derecha del optoacoplador la estructura más destacable es una red RC para el filtrado de la señal. El circuito en su conjunto fue probado en una protoboard y funciona de manera correcta. Se presentan a continuación una serie de imágenes en las que aparece el montaje y las medidas que se realizarón con el osciloscopio. Figura 26) Comprobando el diseño. Memoria. 32 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 27) Vin=24v Vout =4.8 [etiqueta2(azul)=Vin etiqueta 1(verde)=Vout] Figura 28) Vin=5.6v Vout =2.67v [etiqueta6(amarilla)=Vout etiqueta 7(azul)=Vin] Memoria. 33 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 29) Vin=4.4v Vout =1.18v [etiqueta8(amarilla)=Vout etiqueta 9(azul)=Vin] Figura 30) Vin=28v (máximo de la fuente del laboratorio) Vout =4.8 [etiqueta10(amarilla)=Vout etiqueta 11(azul)=Vin] El aspecto en 3D de los módulos de entradas digitales es el siguiente. Memoria. 34 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 31) Simulación en 3D de los módulos de entradas digitales Memoria. 35 Controlador modular programable basado en procesador de 32 bits y CAN bus ENTRADAS DIGITALES Número de Entradas 7 Rango de voltajes de entrada(V) 5.1÷48 v Retraso de señal a ON 2us Retraso de señal a OFF 2us Voltaje a salida máximo de estado OFF 1.2 v Voltaje a salida mínimo de estado ON 5v Intensidad máxima de entrada 60 mA Rango de temperaturas -­‐65÷125 ºC Precio 9 euros Figura 32) Especificaciones técnicas de los módulos de entradas digitales. Por su parte, la electrónica de los módulos de salidas digitales rápidas es muy sencilla, basándose únicamente en un convertidor de intensidad a voltaje, en concreto el FOD 8321. El funcionamiento de este componente es muy simple, de tal manera que si le llega por la patilla uno entre 10 y 16 mA, sacará por la patilla cinco la tensión que se le coloque en la patilla seis. Figura 33) Circuito electrónico de las salidas digitales rápidas. El precio de estos módulos ronda los siete euros y su aspecto simulado es el que se expone a continuación. SALIDAS DIGITALES RAPIDAS Número de Entradas Rango de voltajes de salida(V) Retraso de señal a ON Retraso de señal a OFF Voltaje de entrada máximo Intensidad máxima de entrada Rango de temperaturas Precio 6 0÷35 v 500 ns 500 ns 5 v 25 mA -­‐40÷100 ºC 7 euros Figura 34) Especificaciones técnicas de los módulos de salidas digitales rápidas. Memoria. 36 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 35) Simulación en 3D de los módulos de salidas digitales rápidas. Las interfaces de salidas digital con triac, están basadas en un diodo luminiscente y un triac sensible a la luz (optotriac) que controla a un triac de mayor potencia. Figura 36) Circuito electrónico de las salidas digitales a triac. Figura 37) Simulación en 3D de los módulos de salidas digitales a TRIAC. Memoria. 37 Controlador modular programable basado en procesador de 32 bits y CAN bus SALIDAS DIGITALES a triac Número de Entradas Rango de voltajes de salida(V) 6 115÷230 Vac Rango de 1 lógico hasta 1A Intensidad media a la entrada 25mA Voltaje de salida máximo para 1 lógico 3Vp Voltaje de salida máximo para 1 lógico 1.8Vp Rango de temperaturas -­‐40÷150 ºC Precio 19 euros Figura 38) Especificaciones técnicas de las salidas digitales a triac. Memoria. 38 Controlador modular programable basado en procesador de 32 bits y CAN bus 8.2 Descripción del software. En las siguientes líneas se procederá a explicar la programación que hace posible la ejecución del panel SCADA, creado para controlar y monitorizar las diferentes variables que se extienden a lo largo de cada uno de los módulos de la red CAN. Así mismo, se aportara a la descripción un manual de usuario de la aplicación. En primer lugar destacar que la aplicación esta llevada a cabo mediante el software Visual Basic 6, sin embargo, al usuario/cliente únicamente se le entregará un archivo ejecutable que no requiere instalación alguna, hecho que permite reducir aún más los costes de este autómata alternativo, ya que de esta manera el cliente no tiene que adquirir ningún tipo de licencia para ejecutarla. La aplicación como se verá más adelante consta de cuatro pantallas o formularios, una pantalla inicial a modo de presentación, que apenas requiere de programación y que por ello será obviada en esta primera parte de la descripción. Una segunda pantalla (en VB6 denominada “Zonas”), que será utilizada para cargar la imagen de fondo que el usuario desee y que servirá de plantilla a la hora de crear los controles. 8.2.1 Programación formulario Zonas. El objetivo que se perseguía en este formulario, era conseguir emular un cuadro de selección con el que designar la zona en la que se quiere colocar la imagen de fondo y posteriormente posicionar a esta. Para ello se hace uso de una API de Windows que devuelve el valor en pixels de la posición en la que se encuentra el puntero. A partir de estos datos, cuando se producen los eventos de MouseDown y MouseUP sobre el formulario, se guarda la posición de la esquina superior e inferior del cuadro de selección. Con estos datos y unas sencillas operaciones de cálculo, se determina el tamaño y posición de la imagen de fondo. Posteriormente se dimensiona el elemento Image (en base a las medidas anteriores), que será el contenedor de la imagen de fondo. Para designar dicha imagen de fondo aparecerá una ventana emergente solicitando la ruta (esta operación se realiza a través del elemento CommonDialog). Una vez marcado el directorio, se cargara la imagen sobre el control Image. Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, Y As Single) Dim cursorpos As POINTAPI GetCursorPos cursorpos listo = True Xsuperior = cursorpos.x Memoria. 39 Controlador modular programable basado en procesador de 32 bits y CAN bus Ysuperior = cursorpos.Y - 26 End Sub Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, Y As Single) listo = False Dim cursorpos As POINTAPI GetCursorPos cursorpos Xinferior = cursorpos.x Yinferior = cursorpos.Y - 26 Ancho = Xinferior - Xsuperior Alto = Yinferior - Ysuperior 'Paso1.Show 1 Image1.Move Xsuperior, Ysuperior, Ancho, Alto Fondo(0) = Ancho Fondo(1) = Alto Fondo(2) = Xsuperior Fondo(3) = Ysuperior Call menudesp1.activar("Cargue la imagen de fondo.", 3, 2, True, "Cargar") End Sub A través del evento MouseMove y con el apoyo de la Api de Windows se podrá ir dibujando un cuadrado, que irá actualizando su tamaño a medida que se desplaza el ratón consiguiendo el efecto de un cuadro de selección típico de Windows. Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, Y As Single) Dim cursorpos As POINTAPI GetCursorPos cursorpos If listo = True Then Zonas.Cls Line (Xsuperior, Ysuperior)-(cursorpos.x, cursorpos.Y - 26), vbWhite, BF End If End Sub Memoria. 40 Controlador modular programable basado en procesador de 32 bits y CAN bus 8.2.2 Programación del formulario Paso1. La tercera pantalla, denominada en visual basic como “Paso1”, es un formulario que permite crear los diferentes elementos a través de los cuales el usuario podrá interactuar con el proceso. Figura 39) Formulario de la aplicación SCADA. Como se puede observar en la imagen superior, el formulario (al que más adelante se verá cómo se accede) presenta dos botones, un botón de agregar y otro de aceptar. El primero incluye el elemento de control en su tabla correspondiente (existe una tabla para los indicadores digitales, otra diferente para los controles digitales, etc). El segundo botón cuando es pulsado dibuja el elemento de control sobre el cuarto formulario, para ello se ayuda de la función LoadPicture, cuya labor es crear un objeto indexado al ya existente. A continuación se analizará la creación de cada uno de los elementos desde el punto de vista del botón de Agregar. Creación de controles digitales (Button). Para crear un control digital se tiene que rellenar el formulario como dicta el manual de usuario, una vez rellenado de forma correcta, la aplicación ya sabe el elemento a generar. La tabla de los controles digitales presenta los siguientes campos, que posteriormente serán utilizados (tras pulsar el botón Aceptar) para crear el control digital sobre el formulario cuatro. Indice Valor Ruta Ruta Color Color PIN Estado Color(1) Modulo Memoria. 41 Controlador modular programable basado en procesador de 32 bits y CAN bus por Imagen Imagen ON defecto ON OFF OFF Actual Imagen(0) El campo “Valor defecto” es usado por el botón Aceptar, para poner el aspecto inicial, así mismo, los cuatro campos siguientes son utilizados en el evento click para cambiar el aspecto en función de lo solicitado por el usuario. Las celdas siete y ocho, son los datos que requiere el chipKIT para poder actualizar las salidas, por lo tanto son datos a enviar junto con la celda diez, que indica el modulo al que pertenece el PIN. Por último, la celda nueve es una celda de apoyo, para saber si se ha pulsado la opción de botón con color o botón animado. Botón Agregar (correspondiente a la parte de controles booleanos). If (Option2(1) And Option1(2)) = True Then booleanos cantidadBotones = cantidadBotones + 1 'Esto para controles Tabla_Control_Dig(cantidadBotones, 1) = cantidadBotones If Option3(0) = True Then Tabla_Control_Dig(cantidadBotones, 2) = 0 Else Tabla_Control_Dig(cantidadBotones, 2) = 1 End If If Option5(0) = True Then Tabla_Control_Dig(cantidadBotones, 9) = 1 Tabla_Control_Dig(cantidadBotones,5) = DialogoColorOn.color Tabla_Control_Dig(cantidadBotones,6)= DialogoColorOFF.color Else Tabla_Control_Dig(cantidadBotones, 9) = 0 Tabla_Control_Dig(cantidadBotones, 3) = BotON.FileName Tabla_Control_Dig(cantidadBotones, 4) = BotonOFF.FileName End If Tabla_Control_Dig(cantidadBotones, 7) = Text5.Text Tabla_Control_Dig(cantidadBotones, 10) = Text10.Text Tabla_Control_Dig(cantidadBotones,8)= Tabla_Control_Dig(cantidadBotones, 3) datos(Controles.cantidad, 6) = 0 End If ' Label19.Caption = Tabla_Indicador_Dig(cantidadindica, 1) If ((Option1(0) Or Option1(1)) And Option2(0)) 'Indicadores analógicos cantidadindicanalog = cantidadindicanalog + 1 Tabla_Indicador_Analog(cantidadindicanalog, cantidadindicanalog Tabla_Indicador_Analog(cantidadindicanalog, 2) = Tabla_Indicador_Analog(cantidadindicanalog, 3) = Tabla_Indicador_Analog(cantidadindicanalog, 4) = Tabla_Indicador_Analog(cantidadindicanalog, 5) = Tabla_Indicador_Analog(cantidadindicanalog, colorfondo.color Tabla_Indicador_Analog(cantidadindicanalog, colorprogreso.color = True Then 1) = Text6.Text Text7.Text 0 Text5.Text 6) Memoria. = 7) = 42 Controlador modular programable basado en procesador de 32 bits y CAN bus Tabla_Indicador_Analog(cantidadindicanalog, 9) = Text8.Text Tabla_Indicador_Analog(cantidadindicanalog, 10) = Text10.Text datos(Controles.cantidad, 6) = 1 End If Boton Aceptar (Correspondiente a la parte de controles booleanos). If (Option2(1) And Option1(2)) = True Then booleanos 'Esto para controles If Tabla_Control_Dig(cantidadBotones, 2) = 1 Then 'Has señalado por defecto = ON If Tabla_Control_Dig(cantidadBotones, 9) = 1 Then 'Has señalado Color Controles.mi_imagen(Controles.cantidad).Visible = False Load Controles.Command4(cantidadBotones) Controles.Command4(cantidadBotones).BackColor = Tabla_Control_Dig(cantidadBotones, 5) Controles.Command4(cantidadBotones).Top = Controles.Ys - 26 Controles.Command4(cantidadBotones).Left = Controles.Xs Controles.Command4(cantidadBotones).Width = Controles.Dimx Controles.Command4(cantidadBotones).Height = Controles.Dimy Controles.Command4(cantidadBotones).Visible = True Picture7.Picture = Nothing Picture6.Picture = Nothing Paso1.Hide Controles.Show End If If Tabla_Control_Dig(cantidadBotones, 9) = 0 Then 'Has señalado Imagen Controles.mi_imagen(Controles.cantidad).Visible = False 'cantidadBotones = cantidadBotones + 1 Load Controles.Command4(cantidadBotones) Controles.Command4(cantidadBotones).Picture = LoadPicture(Tabla_Control_Dig(cantidadBotones, 3)) 'Controles.Command4(cantidadBotones).BackColor = Tabla_Control_Dig(cantidadBotones, 5) Controles.Command4(cantidadBotones).Top = Controles.Ys - 26 Controles.Command4(cantidadBotones).Left = Controles.Xs Controles.Command4(cantidadBotones).Width = Controles.Dimx Controles.Command4(cantidadBotones).Height = Controles.Dimy Controles.Command4(cantidadBotones).Visible = True Picture7.Picture = Nothing Picture6.Picture = Nothing Paso1.Hide Controles.Show End If End If If Tabla_Control_Dig(cantidadBotones, 2) = 0 Then 'Has señalado por defecto = OFF If Tabla_Control_Dig(cantidadBotones, 9) = 1 Then 'Has señalado Color Controles.mi_imagen(Controles.cantidad).Visible = False Load Controles.Command4(cantidadBotones) Controles.Command4(cantidadBotones).BackColor= Tabla_Control_Dig(cantidadBotones, 6) Controles.Command4(cantidadBotones).Top = Controles.Ys - 26 Memoria. 43 Controlador modular programable basado en procesador de 32 bits y CAN bus Controles.Command4(cantidadBotones).Left = Controles.Xs Controles.Command4(cantidadBotones).Width = Controles.Dimx Controles.Command4(cantidadBotones).Height = Controles.Dimy Controles.Command4(cantidadBotones).Visible = True Picture7.Picture = Nothing Picture6.Picture = Nothing Paso1.Hide Controles.Show End If If Tabla_Control_Dig(cantidadBotones, 9) = 0 Then 'Has señalado Imagen Controles.mi_imagen(Controles.cantidad).Visible = False 'cantidadBotones = cantidadBotones + 1 Load Controles.Command4(cantidadBotones) Controles.Command4(cantidadBotones).Picture = LoadPicture(Tabla_Control_Dig(cantidadBotones, 4)) 'Controles.Command4(cantidadBotones).BackColor = Tabla_Control_Dig(cantidadBotones, 5) Controles.Command4(cantidadBotones).Top = Controles.Ys - 26 Controles.Command4(cantidadBotones).Left = Controles.Xs Controles.Command4(cantidadBotones).Width = Controles.Dimx Controles.Command4(cantidadBotones).Height = Controles.Dimy Controles.Command4(cantidadBotones).Visible = True Picture7.Picture = Nothing Picture6.Picture = Nothing Paso1.Hide Controles.Show End If End If End If Creación de indicadores digitales (Shape). Las directrices para crear un indicador digital son idénticas a las mencionadas para el elemento de control anterior. En cuanto a la tabla de los indicadores digitales sí que varía y se pasará a analizar a continuación. Cantidad Ruta Ruta PIN Estado Valor Modulo ¿Alarma? Texto Imagen Imagen Actual por SIà1 alarma ON OFF defecto NOà0 Las tres primeras celdas son usadas en un timer (en el formulario cuatro) para cambiar la imagen en función del estado del campo cinco. Es decir, si en el campo cinco aparece un uno, la imagen a mostrar será la que se encuentre en la ruta de la celda dos. La actualización de este “estado actual” será estudiada en el análisis del formulario cuatro cuando se estudie la comunicación PC-­‐chipKIT, ya que este valor proviene de lo que mande codificado el chipKIT a través del puerto USB. La celda siete, es el módulo al que pertenece el PIN que se encuentra recogido en el campo cuatro. Memoria. 44 Controlador modular programable basado en procesador de 32 bits y CAN bus Por último los campos ocho y nueve permiten la gestión de alarmas en los indicadores digitales. Indicando a través del campo ocho si el usuario requiere alarma y en el campo nueve aparece el texto que el usuario quiere que aparezca. Botón Agregar. If (Option2(0) And Option1(2)) = True Then 'Esto para indicadores booleanos cantidadindica = cantidadindica + 1 Tabla_Indicador_Dig(cantidadindica, 1) = Controles.cantidad Tabla_Indicador_Dig(cantidadindica, 2) = DialogON.FileName Tabla_Indicador_Dig(cantidadindica, 3) = DialogOFF.FileName Tabla_Indicador_Dig(cantidadindica, 4) = Text5.Text Tabla_Indicador_Dig(cantidadindica, 6) = Text10.Text If Option3(1) Then Tabla_Indicador_Dig(cantidadindica, 5) = 1 Else Tabla_Indicador_Dig(cantidadindica, 5) = 0 End If datos(Controles.cantidad, 6) = 3 End If Botón Aceptar. If (Option2(0) And Option1(2)) indicadores booleanos If Option3(1) = True Then = True Then 'Esto para Controles.mi_imagen(Controles.cantidad).Picture = LoadPicture(DialogON.FileName) SetLayeredWindowAttributes Controles.mi_imagen(Controles.cantidad).hwnd, RGB(0, 0, 255), 0, LWA_COLORKEY Controles.mi_imagen(Controles.cantidad).ScaleMode = 3 Controles.mi_imagen(Controles.cantidad).AutoRedraw = True Controles.mi_imagen(Controles.cantidad).PaintPicture Controles.mi_imagen(Controles.cantidad).Picture, _ 0, 0, Controles.mi_imagen(Controles.cantidad).ScaleWidth, Controles.mi_imagen(Controles.cantidad).ScaleHeight Picture1.Picture = Nothing Picture4.Picture = Nothing Paso1.Hide Controles.Show Else Controles.mi_imagen(Controles.cantidad).Picture = LoadPicture(DialogOFF.FileName) SetLayeredWindowAttributes Controles.mi_imagen(Controles.cantidad).hwnd, RGB(0, 0, 255), 0, LWA_COLORKEY Controles.mi_imagen(Controles.cantidad).ScaleMode = 3 Controles.mi_imagen(Controles.cantidad).AutoRedraw = True 'Controles.mi_imagen(Controles.cantidad).PaintPicture Controles.mi_imagen(Controles.cantidad).Picture, _ '0, 0, Controles.mi_imagen(Controles.cantidad).ScaleWidth, Controles.mi_imagen(Controles.cantidad).ScaleHeight Controles.mi_imagen(Controles.cantidad).PaintPicture Controles.mi_imagen(Controles.cantidad).Picture, _ 0, 0, Controles.mi_imagen(Controles.cantidad).ScaleWidth, Controles.mi_imagen(Controles.cantidad).ScaleHeight Memoria. 45 Controlador modular programable basado en procesador de 32 bits y CAN bus Picture1.Picture = Nothing Picture4.Picture = Nothing Paso1.Hide Controles.Show End If End If Creación de controles analógicos (Slider). La tabla correspondiente a los controles analógicos, contienen un gran número de datos. Máximo Mínimo DimX DimY PIN Valor Indice Unidad Slider(0) Modulo por de Text(1) defecto medida Tanto los controles analógicos como los indicadores son más complejos que los digitales, ya que requieren un número de datos mayor. Los dos primeros datos, son utilizados para realizar el escalado. Ejemplo de escalado. Si en la primera celda aparece un 20 y en la segunda un 0, la información que se debe de mandar al chipKIT es un 255 (20 -­‐> 255) y un 0 para el mínimo (0 -­‐> 0). Las dos siguientes celdas son empleadas para el aspecto visual del slider junto con la octava. Los demás campos tienen el mismo cometido que en los controles digitales. Botón Agregar. If ((Option1(0) Or Option1(1)) And Option2(1)) = True Then 'Controles analógicos cantidadcontrolanalog = cantidadcontrolanalog + 1 Tabla_Control_Analog(cantidadcontrolanalog, 1) = Text6.Text Tabla_Control_Analog(cantidadcontrolanalog, 2) = Text7.Text Tabla_Control_Analog(cantidadcontrolanalog, 3) = Controles.Dimx Tabla_Control_Analog(cantidadcontrolanalog, 4) = Controles.Dimy Tabla_Control_Analog(cantidadcontrolanalog, 5) = Text5.Text Tabla_Control_Analog(cantidadcontrolanalog, 6) = 0 Tabla_Control_Analog(cantidadcontrolanalog, 7) = cantidadcontrolanalog Tabla_Control_Analog(cantidadcontrolanalog, 8) = Text9.Text If Option30 = True Then Tabla_Control_Analog(cantidadcontrolanalog, 9) = 1 Else Tabla_Control_Analog(cantidadcontrolanalog, 9) = 0 End If Tabla_Control_Analog(cantidadcontrolanalog, 10) = Text10.Text datos(Controles.cantidad, 6) = 2 End If Memoria. 46 Controlador modular programable basado en procesador de 32 bits y CAN bus Botón Aceptar. If ((Option1(0) Or Option1(1)) And Option2(1)) = True 'Controles analógicos If Option30 = False Then Controles.mi_imagen(Controles.cantidad).Visible = False Load Controles.Pic_slider(Paso1.cantidadcontrolanalog) Controles.Pic_slider(cantidadcontrolanalog).Top Controles.Ys - 26 Controles.Pic_slider(cantidadcontrolanalog).Left Controles.Xs Controles.Pic_slider(cantidadcontrolanalog).Width = 15 Controles.Pic_slider(cantidadcontrolanalog).Height Controles.Dimy Then = = = Controles.Pic_slider(cantidadcontrolanalog).Visible = True Load Controles.Pic_Barra(Paso1.cantidadcontrolanalog) Controles.Pic_Barra(cantidadcontrolanalog).Top Controles.Ys - 26 Controles.Pic_Barra(cantidadcontrolanalog).Left Controles.Xs Controles.Pic_Barra(cantidadcontrolanalog).Width Controles.Dimx Controles.Pic_Barra(cantidadcontrolanalog).Height Controles.Dimy Controles.Pic_Barra(cantidadcontrolanalog).ZOrder vbBringToFront Controles.Pic_Barra(cantidadcontrolanalog).Visible = True Controles.Pic_slider(cantidadcontrolanalog).ZOrder vbBringToFront = = = = Load Controles.Label2(cantidadcontrolanalog) Controles.Label2(cantidadcontrolanalog).Top = Controles.Ys 26 + Controles.Dimy + 10 Controles.Label2(cantidadcontrolanalog).Left = Controles.Xs + (Controles.Dimx / 2) - 5 Controles.Label2(cantidadcontrolanalog).Width = Controles.Dimx + 20 Controles.Label2(cantidadcontrolanalog).Height = 25 Controles.Label2(cantidadcontrolanalog).Visible = True Controles.Label2(cantidadcontrolanalog).ZOrder vbBringToFront Else Controles.mi_imagen(Controles.cantidad).Visible = False Load Controles.Text1(cantidadcontrolanalog) Controles.Text1(cantidadcontrolanalog).Top = Controles.Ys - 26 Controles.Text1(cantidadcontrolanalog).Left = Controles.Xs Controles.Text1(cantidadcontrolanalog).Width = Controles.Dimx Controles.Text1(cantidadcontrolanalog).Height = Controles.Dimy Controles.Text1(cantidadcontrolanalog).ZOrder vbBringToFront Controles.Text1(cantidadcontrolanalog).Visible = True Controles.Text1(cantidadcontrolanalog).ZOrder vbBringToFront End If Paso1.Hide Memoria. 47 Controlador modular programable basado en procesador de 32 bits y CAN bus Controles.Show End If Creación de indicadores analógicos (ProgressBar). La tabla de los indicadores analógico requiere el mismo número de campos que la de los controles. Índice Máximo Mínimo Valor PIN Color Color Vertical(0) Unidad Modulo actual fondo progr Horiz (1) de medida Alarma Texto Valor SI à1 de limite NOà 0 alarma De nuevo los valores “máximo” y “mínimo” son utilizados para realizar el escalado, que junto al campo cuatro también son utilizados para variar su estado visual en función de lo que mande chipKIT. El resto de campos, son necesarios para poder manejar este tipo de controles en visual basic. Es en la cuarta pantalla (en VB6 denominada Controles) donde se lleva a cabo todas las operaciones necesarias para la creación de la aplicación SCADA y por lo tanto es el formulario que más programación requiere. Los tres últimos campos son utilizados por visual basic para generar las alarmas cuando así se lo indique el usuario. Botón Agregar. If ((Option1(0) Or Option1(1)) And Option2(0)) 'Indicadores analógicos cantidadindicanalog = cantidadindicanalog + 1 Tabla_Indicador_Analog(cantidadindicanalog, cantidadindicanalog Tabla_Indicador_Analog(cantidadindicanalog, 2) Tabla_Indicador_Analog(cantidadindicanalog, 3) Tabla_Indicador_Analog(cantidadindicanalog, 4) Tabla_Indicador_Analog(cantidadindicanalog, 5) Tabla_Indicador_Analog(cantidadindicanalog, colorfondo.color Tabla_Indicador_Analog(cantidadindicanalog, colorprogreso.color Tabla_Indicador_Analog(cantidadindicanalog, 9) Tabla_Indicador_Analog(cantidadindicanalog, Text10.Text = True Then 1) = = = = = Text6.Text Text7.Text 0 Text5.Text 6) = 7) = = Text8.Text 10) = datos(Controles.cantidad, 6) = 1 End If Botón Aceptar. If ((Option1(0) Or Option1(1)) And Option2(0)) = True 'Indicadores analógicos Controles.mi_imagen(Controles.cantidad).Visible = False Load Controles.ProgressBar1(cantidadindicanalog) If Option4(0) = True Then Memoria. Then 48 Controlador modular programable basado en procesador de 32 bits y CAN bus Controles.ProgressBar1(cantidadindicanalog).Orientation = ccOrientationHorizontal Tabla_Indicador_Analog(cantidadindicanalog, 8) = 1 Else Controles.ProgressBar1(cantidadindicanalog).Orientation = ccOrientationVertical Tabla_Indicador_Analog(cantidadindicanalog, 8) = 0 End If Color_Fondo Controles.ProgressBar1(cantidadindicanalog).hwnd, colorfondo.color Color_Progreso Controles.ProgressBar1(cantidadindicanalog).hwnd, colorprogreso.color Controles.ProgressBar1(cantidadindicanalog).Top = Controles.Ys - 26 Controles.ProgressBar1(cantidadindicanalog).Left = Controles.Xs Controles.ProgressBar1(cantidadindicanalog).Width = Controles.Dimx Controles.ProgressBar1(cantidadindicanalog).Height = Controles.Dimy Controles.ProgressBar1(cantidadindicanalog).Visible = True Picture2.Picture = Nothing Picture8.Picture = Nothing Load Controles.Label1(cantidadindicanalog) Controles.Label1(cantidadindicanalog).Top = Controles.Ys 26 + Controles.Dimy + 10 Controles.Label1(cantidadindicanalog).Left = Controles.Xs 10 Controles.Label1(cantidadindicanalog).Width = Controles.Dimx + 20 Controles.Label1(cantidadindicanalog).Height = 25 Controles.Label1(cantidadindicanalog).Visible = True Controles.Label1(cantidadindicanalog).ZOrder vbBringToFront Paso1.Hide Controles.Show End If 8.2.3 Programación del formulario Controles. Este formulario es el eje central de la aplicación, sobre el se vertebran diferentes operaciones como, guardar el panel SCADA o cargar uno ya existente. Además, de manera invisible para el usuario, también se lleva a cabo la gestión de la comunicación serie con el chipKIT. Así mismo, se realiza de manera automatica la programación de la CPU o placa principal chipKIT. Botón de Guardar y Botón de Cargar. El botón Guardar a través de su pulsación permite salvar todo el trabajo ya realizado sobre el SCADA. El archivo que genera, es del tipo .xlsx es decir un archivo tipo Excel. En el cual se irá guardando celda a celda cada una de las tablas mencionadas anteriormente, de tal manera que cuando se quiera rescatar el trabajo realizado (botón de Cargar), únicamente sea necesario volver a leer este Memoria. 49 Controlador modular programable basado en procesador de 32 bits y CAN bus archivo e ir conformando esas tablas. Una vez que VB disponga de esas tablas, trabajará de forma normal y en base a esos datos cargados. A continuación se muestra la programación que requiere cada uno de los botones, que como se observa es bastante extensa y nada simple. Por ello, es más didáctico quedarse con la idea general que entrar en detalle en cada una de las líneas de programación. Programación del botón guardar. Dim oExcel As Object Dim oBook As Object Dim oSheet As Object 'Abre un nuevo libro en excel Set oExcel = CreateObject("Excel.Application") Set oBook = oExcel.Workbooks.Add 'Añade la cabeceras Set oSheet = oBook.Worksheets(1) 'Comienza a pasar los Arrays oSheet.range("A1").Resize(1).Value = Controles.cantidad oSheet.range("A2").Resize(1).Value = Paso1.cantidadBotones oSheet.range("A3").Resize(1).Value = Paso1.cantidadindica oSheet.range("A4").Resize(1).Value Paso1.cantidadindicanalog oSheet.range("A5").Resize(1).Value Paso1.cantidadcontrolanalog = = oSheet.range("A6").Resize(40, 6).Value = datos oSheet.range("A" & (CStr(Controles.cantidad) + 6)).Resize(40, 10).Value = Tabla_Control_Dig oSheet.range("A" & (CStr(Controles.cantidad) + 6 + CStr(Paso1.cantidadBotones))).Resize(40, 6).Value = Tabla_Indicador_Dig oSheet.range("A" & (CStr(Controles.cantidad) + 6 + CStr(Paso1.cantidadBotones) + CStr(Paso1.cantidadindica))).Resize(40, 10).Value = Tabla_Indicador_Analog oSheet.range("A" & (CStr(Controles.cantidad) + 6 + CStr(Paso1.cantidadBotones) + CStr(Paso1.cantidadindica) + CStr(Paso1.cantidadindicanalog))).Resize(40, 10).Value = Tabla_Control_Analog oSheet.range("A" & (CStr(Controles.cantidad) + 6 CStr(Paso1.cantidadBotones) + CStr(Paso1.cantidadindica) CStr(Paso1.cantidadindicanalog) CStr(Paso1.cantidadcontrolanalog))).Resize(1, 5).Value = Fondo 'Save the Workbook and Quit Excel Guardar.ShowSave oSheet.SaveAs Guardar.FileName oExcel.Quit Programación del botón Cargar. Memoria. 50 + + + Controlador modular programable basado en procesador de 32 bits y CAN bus Dim obj As Object, libro As Object, Hoja As Object Dim Arch As String, Cant As Integer, x As Integer 'Creo un vector de Enteros generico Dim MiVector() As Integer Dim i As Integer Dim j As Integer 'creo nueva instancia de Excel Set obj = CreateObject("Excel.Application") 'Abro el archivo. Uso un ComomDialog Cargar.ShowOpen Arch = Cargar.FileName 'Abro el libro Set libro = obj.Workbooks.Open(Arch) 'referencia la Hoja, por defecto la hoja activa Set Hoja = obj.ActiveSheet 'Escribo en los Arrays Controles.cantidad = Hoja.cells(1, 1) Paso1.cantidadBotones = Hoja.cells(2, 1) Paso1.cantidadindica = Hoja.cells(3, 1) Paso1.cantidadindicanalog = Hoja.cells(4, 1) Paso1.cantidadcontrolanalog = Hoja.cells(5, 1) Fondo(0) = Hoja.cells(6 + Controles.cantidad Paso1.cantidadBotones + Paso1.cantidadindica Paso1.cantidadindicanalog + Paso1.cantidadcontrolanalog, 1).Value Fondo(1) = Hoja.cells(6 + Controles.cantidad Paso1.cantidadBotones + Paso1.cantidadindica Paso1.cantidadindicanalog + Paso1.cantidadcontrolanalog, 2).Value Fondo(2) = Hoja.cells(6 + Controles.cantidad Paso1.cantidadBotones + Paso1.cantidadindica Paso1.cantidadindicanalog + Paso1.cantidadcontrolanalog, 3).Value Fondo(3) = Hoja.cells(6 + Controles.cantidad Paso1.cantidadBotones + Paso1.cantidadindica Paso1.cantidadindicanalog + Paso1.cantidadcontrolanalog, 4).Value Fondo(4) = Hoja.cells(6 + Controles.cantidad Paso1.cantidadBotones + Paso1.cantidadindica Paso1.cantidadindicanalog + Paso1.cantidadcontrolanalog, 5).Value Image2.Move Fondo(2), Fondo(3), Fondo(0), Fondo(1) Image2.Picture = LoadPicture(Fondo(4)) + + + + + + + + + + For i = 1 To Controles.cantidad For j = 1 To 6 datos(i, j) = Hoja.cells(i + 5, j).Value Next Next For i = 1 To Paso1.cantidadBotones For j = 1 To 10 Tabla_Control_Dig(i, j) = Controles.cantidad, j).Value Next Next Hoja.cells(i For i = 1 To Paso1.cantidadindica For j = 1 To 6 Tabla_Indicador_Dig(i, j) = Hoja.cells(i Controles.cantidad + Paso1.cantidadBotones, j).Value Memoria. + + 5 + 5 + 51 Controlador modular programable basado en procesador de 32 bits y CAN bus Next Next For i = 1 To Paso1.cantidadindicanalog For j = 1 To 10 Tabla_Indicador_Analog(i, j) = Hoja.cells(i + 5 + Controles.cantidad + Paso1.cantidadBotones + Paso1.cantidadindica, j).Value Next Next For i = 1 To Paso1.cantidadcontrolanalog For j = 1 To 10 Tabla_Control_Analog(i, j) = Hoja.cells(i + 5 + Controles.cantidad + Paso1.cantidadBotones + Paso1.cantidadindica + Paso1.cantidadindicanalog, j).Value Next Next ' Cierro Excel obj.Quit Set obj = Nothing Set libro = Nothing Set Hoja = Nothing 'Cargar las imagenes en el form excel = 1 excelID = 1 excelIA = 1 excelCD = 1 excelCA = 1 While (excel <= Controles.cantidad) Load mi_imagen(excel) mi_imagen(excel).Visible = False mi_imagen(excel).Move datos(excel, 4), datos(excel, 5), datos(excel, 2), datos(excel, 3) mi_imagen(excel).ScaleMode = vbPixels mi_imagen(excel).Visible = True SetParent mi_imagen(excel).hwnd, 0 SetWindowLong mi_imagen(excel).hwnd, GWL_EXSTYLE, GetWindowLong(mi_imagen(excel).hwnd, GWL_EXSTYLE) Or WS_EX_LAYERED Or WS_CHILD SetLayeredWindowAttributes mi_imagen(excel).hwnd, 0, 100, LWA_ALPHA SetParent mi_imagen(excel).hwnd, Me.hwnd tipo = datos(excel, 6) Select Case tipo Case 0 'Controles Digitales If Tabla_Control_Dig(excelCD, 9) = 1 Then señalado Color mi_imagen(excel).Visible = False Load Command4(excelCD) If Tabla_Control_Dig(excelCD, 5) = 1 Then Command4(excelCD).BackColor Tabla_Control_Dig(excelCD, 5) Else Command4(excelCD).BackColor Tabla_Control_Dig(excelCD, 6) Memoria. 'Has = = 52 Controlador modular programable basado en procesador de 32 bits y CAN bus End If Command4(excelCD).Top = datos(excel, 5) - 26 Command4(excelCD).Left = datos(excel, 4) Command4(excelCD).Width = datos(excel, 2) Command4(excelCD).Height = datos(excel, 3) Command4(excelCD).Visible = True End If If Tabla_Control_Dig(excelCD, 9) = 0 Then 'Has señalado Imagen Controles.mi_imagen(excel).Visible = False Load Command4(excelCD) If Tabla_Control_Dig(excelCD, 5) = 1 Then Command4(excelCD).Picture LoadPicture(Tabla_Control_Dig(excelCD, 3)) Else Command4(excelCD).Picture LoadPicture(Tabla_Control_Dig(excelCD, 3)) End If Command4(excelCD).Top = datos(excel, 5) - 26 Command4(excelCD).Left = datos(excel, 4) Command4(excelCD).Width = datos(excel, 2) Command4(excelCD).Height = datos(excel, 3) Command4(excelCD).Visible = True End If excelCD = excelCD + 1 Case 1 'Indicadores analógicos mi_imagen(excel).Visible = False Load ProgressBar1(excelIA) If Tabla_Indicador_Analog(excelIA, 8) = 1 Then ProgressBar1(excelIA).Orientation ccOrientationHorizontal Else ProgressBar1(excelIA).Orientation ccOrientationVertical End If = = = = Color_Fondo ProgressBar1(excelIA).hwnd, Tabla_Indicador_Analog(excelIA, 6) Color_Progreso ProgressBar1(excelIA).hwnd, Tabla_Indicador_Analog(excelIA, 7) ProgressBar1(excelIA).Top = datos(excel, 5) - 26 ProgressBar1(excelIA).Left = datos(excel, 4) ProgressBar1(excelIA).Width = datos(excel, 2) ProgressBar1(excelIA).Height = datos(excel, 3) ProgressBar1(excelIA).Visible = True Load Controles.Label1(excelIA) Controles.Label1(excelIA).Top = datos(excel, 5) - 26 + datos(excel, 3) + 10 Controles.Label1(excelIA).Left = datos(excel, 4) 10 Controles.Label1(excelIA).Width = datos(excel, 2) + 20 Controles.Label1(excelIA).Height = 25 Controles.Label1(excelIA).Visible = True Controles.Label1(excelIA).ZOrder vbBringToFront excelIA = excelIA + 1 Case 2 'Controles analógicos. If Tabla_Control_Analog(excelCA, 9) = 0 Then Memoria. 53 Controlador modular programable basado en procesador de 32 bits y CAN bus mi_imagen(excel).Visible = False Load Pic_slider(excelCA) Pic_slider(excelCA).Top = datos(excel, 5) - 26 Pic_slider(excelCA).Left = datos(excel, 4) Pic_slider(excelCA).Width = 15 Pic_slider(excelCA).Height = datos(excel, 3) Pic_slider(excelCA).Visible = True Load Pic_Barra(excelCA) Pic_Barra(excelCA).Top = datos(excel, 5) - 26 Pic_Barra(excelCA).Left = datos(excel, 4) Pic_Barra(excelCA).Width = datos(excel, 2) Pic_Barra(excelCA).Height = datos(excel, 3) Pic_Barra(excelCA).ZOrder vbBringToFront Pic_Barra(excelCA).Visible = True Pic_slider(excelCA).ZOrder vbBringToFront Load Controles.Label2(excelCA) Controles.Label2(excelCA).Top = datos(excel, 5) - 26 + datos(excel, 3) + 10 Controles.Label2(excelCA).Left = datos(excel, 4) + (datos(excel, 2) / 2) - 5 Controles.Label2(excelCA).Width = datos(excel, 2) + 20 Controles.Label2(excelCA).Height = 25 Controles.Label2(excelCA).Visible = True Controles.Label2(excelCA).ZOrder vbBringToFront Else mi_imagen(excel).Visible = False Load Text1(excelCA) Text1(excelCA).Top = datos(excel, 5) - 26 Text1(excelCA).Left = datos(excel, 4) Text1(excelCA).Width = datos(excel, 2) Text1(excelCA).Height = datos(excel, 3) Text1(excelCA).ZOrder vbBringToFront Text1(excelCA).Visible = True End If excelCA = excelCA + 1 Case 3 'indicadores digitales If Tabla_Indicador_Dig(excelID, 5) = 0 Then mi_imagen(excel).Picture = LoadPicture(Tabla_Indicador_Dig(excelID, 3)) SetLayeredWindowAttributes mi_imagen(excel).hwnd, RGB(0, 0, 255), 0, LWA_COLORKEY mi_imagen(excel).ScaleMode = 3 mi_imagen(excel).AutoRedraw = True mi_imagen(excel).PaintPicture mi_imagen(excel).Picture, _ 0, 0, mi_imagen(excel).ScaleWidth, mi_imagen(excel).ScaleHeight Else mi_imagen(excel).Picture = LoadPicture(Tabla_Indicador_Dig(excelID, 2)) SetLayeredWindowAttributes mi_imagen(excel).hwnd, RGB(0, 0, 255), 0, LWA_COLORKEY mi_imagen(excel).ScaleMode = 3 mi_imagen(excel).AutoRedraw = True mi_imagen(excel).PaintPicture mi_imagen(excel).Picture, _ Memoria. 54 Controlador modular programable basado en procesador de 32 bits y CAN bus 0, 0, mi_imagen(excel).ScaleHeight End If excelID = excelID + 1 End Select excel = excel + 1 Wend mi_imagen(excel).ScaleWidth, Botón de Programación de chipKIT. El botón de “programar chipKIT” tiene como objetivo liberar al usuario de toda programación que no tenga nada que ver con su algoritmo de control, ya que esto último es algo variable en función de la situación en que vaya a emplearse este equipo de control. De tal manera que las labores que se realizan de manera automática son las siguientes: • Programación de las comunicaciones vía puerto USB que le permite al chipKIT estar en contacto con el PC. • Programación de las comunicaciones CAN, así como la gestión de la configuración de los diferentes módulos que forman la red CAN. • Programación del estado de los pines de los pines del módulo 0, es decir, de la placa chipKIT principal (CPU). Los dos primeros puntos por su complejidad e importancia serán tratados en puntos posteriores de forma más extensa. Sin embargo si que se entrará a explicar el tercer punto. Toda placa chipKIT requiere de una zona de programación en la que se le diga como va a trabajar cada uno de sus pines (entrada o salida). Esta podría ser labor del usuario, sin embargo, para facilitar el uso de este tipo de placas, es el propio Visual Basic el que genera ese código en función de los datos que tiene en las tablas antes mencionadas. Quedando la programación de esa parte del Sketch de chipKIT de la siguiente manera. Un ejemplo: // ZONA DE ENTRADAS Y SALIDAS pinMode(10,OUTPUT); //Control analogico analogWrite(10,0); pinMode(1,OUTPUT); //Control analogico analogWrite(1,0); pinMode(0,INPUT); //Indicador analogico pinMode(1,INPUT); //Indicador analogico pinMode(1,INPUT); //Indicador analogico pinMode(1,INPUT); //Indicador analogico pinMode(1,INPUT); //Indicador analogico pinMode(33,INPUT); //Indicador digital pinMode(35,INPUT); //Indicador digital pinMode(39,INPUT); //Indicador digital pinMode(40,INPUT); //Indicador digital pinMode(25,OUTPUT); //Control digital digitalWrite(25,0); Memoria. 55 Controlador modular programable basado en procesador de 32 bits y CAN bus Se puede observar en las líneas superiores como los pines 10,1 y 25 quedan configurados como salidas y los demás como entradas. Cada uno de estos pines corresponderá a un módulo determinado, para saber a que módulo corresponde cada uno de estos pines en líneas posteriores se programará una serie de arrays que contendrán estos datos. Ejemplo. unsigned int MODULO1_ID[] = {39,0}; // Array de indicadores digitales del modulo 1 unsigned int PINES_MODULO1_ID[] = {39}; // Array de indicadores digitales del modulo 1 unsigned int MODULO2_ID[] = {40,0}; // Array de indicadores digitales del modulo 2 unsigned int PINES_MODULO2_ID[] = {40}; // Array de indicadores digitales del modulo 2 unsigned int MODULO3_ID[] = {}; // Array de indicadores digitales del modulo 3 unsigned int PINES_MODULO3_ID[] = {}; // Array de indicadores digitales del modulo 3 unsigned int MODULO1_IA[] = {1,0}; // Array de indicadores analogicos del modulo 1 unsigned int PINES_MODULO1_IA[] = {1}; // Array de indicadores analogicos del modulo 1 unsigned int MODULO2_IA[] = {1,0}; // Array de indicadores analogicos del modulo 2 unsigned int PINES_MODULO2_IA[] = {1}; // Array de indicadores analogicos del modulo 2 unsigned int MODULO3_IA[] = {1,0}; // Array de indicadores analogicos del modulo 3 unsigned int PINES_MODULO3_IA[] = {1}; // Array de indicadores analogicos del modulo 3 unsigned int cantidad =4; // Cantidad de indicadores digitales unsigned int cantidadanalog =5; // Cantidad de indicadores analogicos unsigned int pines_digi_entrada[] = {33,0,35,0,39,1,40,2}; // Array de indicadores digitales unsigned int pines_analog_entrada[] = {0,0,1,0,1,1,1,2,1,3}; // Array de indicadores analogicos Para liberar al usuario de todo este trabajo, es necesario programarlo de manera automática mediante visual basic. Las líneas de código que llevan a cabo esta labor son las siguientes. Private Sub Command3_Click() chipKIT ' Esta variable contendrá la queremos acceder Dim Archivo As String 'Escribir programación en dirección del archivo al que Dim Linea As String Dim texto As String Archivo = "C:\Documents and Settings\Administrador\Mis documentos\Proyecto SCADAv6.2\Archivos de programa\ARDUINOv1_8\ARDUINOv1_8.pde" ' Abrimos el archivo con la variable Archivo, y como el acceso será de lectura _ utilizamos el modo Input seguido del número de archivo "#1" Memoria. 56 Controlador modular programable basado en procesador de 32 bits y CAN bus Open Archivo For Input As #1 ' Creamos un bucle para controlar que después de llegar al final del archivo _ la sentencia Input, no continue leyendo y se produzca un error en tiempo de eje _ cucíon. Para ello utilizamos la condición Not EoF(1), que traducido quiere decir _ mientras no llegue al final del archivo, que continúe leyendo línea por línea. _ While Not EOF(1) Line Input #1, Linea Dim F As Integer F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Output As F Print #F, Linea Close F Wend ' Cerramos el archivo Close #1 Dim punteroprogramar As Byte punteroprogramar = 1 'Colocar pines de controles analogicos While (punteroprogramar <= Paso1.cantidadcontrolanalog) F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "pinMode(" & Tabla_Control_Analog(punteroprogramar, 5) & ",OUTPUT); //Control analogico" Print #F, "analogWrite(" & Tabla_Control_Analog(punteroprogramar, 5) & ",0);" Close F punteroprogramar = punteroprogramar + 1 Wend 'Colocar pines de indicadores analogicos punteroprogramar = 1 While (punteroprogramar <= Paso1.cantidadindicanalog) F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "pinMode(" & Tabla_Indicador_Analog(punteroprogramar, 5) & ",INPUT); //Indicador analogico" Close F punteroprogramar = punteroprogramar + 1 Wend 'Colocar pines de indicadores digitales punteroprogramar = 1 While (punteroprogramar <= Paso1.cantidadindica) F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Memoria. 57 Controlador modular programable basado en procesador de 32 bits y CAN bus Print #F, "pinMode(" & Tabla_Indicador_Dig(punteroprogramar, 4) & ",INPUT); //Indicador digital" Close F punteroprogramar = punteroprogramar + 1 Wend 'Colocar pines de controles digitales punteroprogramar = 1 While (punteroprogramar <= Paso1.cantidadBotones) F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "pinMode(" & Tabla_Control_Dig(punteroprogramar, 7) & ",OUTPUT); //Control digital" Print #F, "digitalWrite(" & Tabla_Control_Dig(punteroprogramar, 7) & "," & Tabla_Control_Dig(punteroprogramar, 2) & ");" Close F punteroprogramar = punteroprogramar + 1 Wend 'Colocar Void loop F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "}" Close F F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "void loop(){" Close F 'Crear tablas necesarias para el BUS CAN 'Modulo1_ID y PINES_MODULO1_ID Dim punteromodulos As Byte punteromodulos = 1 While (punteromodulos < Paso1.cantidadindica) If (Tabla_Indicador_Dig(punteromodulos, 6) = 1) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," & Tabla_Indicador_Dig(punteromodulos, 5) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Dig(punteromodulos, 6) = 1) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," & Tabla_Indicador_Dig(punteromodulos, 5) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int MODULO1_ID[] = {" & texto & "}; // Array de indicadores digitales del modulo 1" Close F texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindica) Memoria. 58 Controlador modular programable basado en procesador de 32 bits y CAN bus If (Tabla_Indicador_Dig(punteromodulos, 6) = 1) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Dig(punteromodulos, 6) = 1) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int PINES_MODULO1_ID[] = {" & texto & "}; // Array de indicadores digitales del modulo 1" Close F 'Modulo2_ID y PINES_MODULO2_ID texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindica) If (Tabla_Indicador_Dig(punteromodulos, 6) = 2) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," & Tabla_Indicador_Dig(punteromodulos, 5) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Dig(punteromodulos, 6) = 2) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," & Tabla_Indicador_Dig(punteromodulos, 5) F = FreeFile End If Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int MODULO2_ID[] = {" & texto & "}; // Array de indicadores digitales del modulo 2" Close F texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindica) If (Tabla_Indicador_Dig(punteromodulos, 6) = 2) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Dig(punteromodulos, 6) = 2) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) End If F = FreeFile Memoria. 59 Controlador modular programable basado en procesador de 32 bits y CAN bus Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int PINES_MODULO2_ID[] = {" & texto & "}; // Array de indicadores digitales del modulo 2" Close F 'Modulo3_ID y PINES_MODULO3_ID texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindica) If (Tabla_Indicador_Dig(punteromodulos, 6) = 3) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," & Tabla_Indicador_Dig(punteromodulos, 5) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Dig(punteromodulos, 6) = 3) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," & Tabla_Indicador_Dig(punteromodulos, 5) F = FreeFile End If Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int MODULO3_ID[] = {" & texto & "}; // Array de indicadores digitales del modulo 3" Close F texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindica) If (Tabla_Indicador_Dig(punteromodulos, 6) = 3) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Dig(punteromodulos, 6) = 3) Then texto = texto & Tabla_Indicador_Dig(punteromodulos, 4) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int PINES_MODULO3_ID[] = {" & texto & "}; // Array de indicadores digitales del modulo 3" Close F 'Modulo1_IA y PINES_MODULO1_IA punteromodulos = 1 While (punteromodulos < Paso1.cantidadindicanalog) If (Tabla_Indicador_Analog(punteromodulos, 10) = 1) Then Memoria. 60 Controlador modular programable basado en procesador de 32 bits y CAN bus texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) & "," & Tabla_Indicador_Analog(punteromodulos, 4) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Analog(punteromodulos, 10) = 1) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) & "," & Tabla_Indicador_Analog(punteromodulos, 4) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int MODULO1_IA[] = {" & texto & "}; // Array de indicadores analogicos del modulo 1" Close F texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindicanalog) If (Tabla_Indicador_Analog(punteromodulos, 10) = 1) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Analog(punteromodulos, 10) = 1) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int PINES_MODULO1_IA[] = {" & texto & "}; // Array de indicadores analogicos del modulo 1" Close F 'Modulo2_IA y PINES_MODULO2_IA texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindicanalog) If (Tabla_Indicador_Analog(punteromodulos, 10) = 2) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) & "," & Tabla_Indicador_Analog(punteromodulos, 4) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Analog(punteromodulos, 10) = 2) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) & "," & Tabla_Indicador_Analog(punteromodulos, 4) End If F = FreeFile Memoria. 61 Controlador modular programable basado en procesador de 32 bits y CAN bus Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int MODULO2_IA[] = {" & texto & "}; // Array de indicadores analogicos del modulo 2" Close F texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindicanalog) If (Tabla_Indicador_Analog(punteromodulos, 10) = 2) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Analog(punteromodulos, 10) = 2) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int PINES_MODULO2_IA[] = {" & texto & "}; // Array de indicadores analogicos del modulo 2" Close F 'Modulo3_IA y PINES_MODULO3_IA texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindicanalog) If (Tabla_Indicador_Analog(punteromodulos, 10) = 3) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) & "," & Tabla_Indicador_Analog(punteromodulos, 4) & "," punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Analog(punteromodulos, 10) = 3) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) & "," & Tabla_Indicador_Analog(punteromodulos, 4) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int MODULO3_IA[] = {" & texto & "}; // Array de indicadores analogicos del modulo 3" Close F texto = Empty punteromodulos = 1 While (punteromodulos < Paso1.cantidadindicanalog) If (Tabla_Indicador_Analog(punteromodulos, 10) = 3) Then texto = Tabla_Indicador_Analog(punteromodulos, 5) texto Memoria. & 62 Controlador modular programable basado en procesador de 32 bits y CAN bus punteromodulos = punteromodulos + 1 Else punteromodulos = punteromodulos + 1 End If Wend If (Tabla_Indicador_Analog(punteromodulos, 10) = 3) Then texto = texto & Tabla_Indicador_Analog(punteromodulos, 5) End If F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int PINES_MODULO3_IA[] = {" & texto & "}; // Array de indicadores analogicos del modulo 3" Close F 'Fin de la parte del BUS CAN 'Colocar arrays que necesita arduino para la comunicación F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int cantidad =" & Paso1.cantidadindica & "; // Cantidad de indicadores digitales" Close F F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int cantidadanalog =" & Paso1.cantidadindicanalog & "; // Cantidad de indicadores analogicos" Close F 'Colocar array de indicadores digitales punteroprogramar = 1 texto = Empty If Paso1.cantidadindica = 1 Then F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int pines_digi_entrada[] = {" & Tabla_Indicador_Dig(punteroprogramar, 4), Tabla_Indicador_Dig(punteroprogramar, 6) & "}; // Array de indicadores digitales" Close F Else While (punteroprogramar < Paso1.cantidadindica) texto = texto & Tabla_Indicador_Dig(punteroprogramar, 4) & "," & Tabla_Indicador_Dig(punteroprogramar, 6) & "," punteroprogramar = punteroprogramar + 1 Wend texto = texto & Tabla_Indicador_Dig(punteroprogramar, 4) & "," & Tabla_Indicador_Dig(punteroprogramar, 6) F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int pines_digi_entrada[] = {" & texto & "}; // Array de indicadores digitales" Close F Memoria. 63 Controlador modular programable basado en procesador de 32 bits y CAN bus End If 'Colocar array de indicadores analogicos punteroprogramar = 1 texto = Empty If Paso1.cantidadindicanalog = 1 Then F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int pines_analog_entrada[] = {" & Tabla_Indicador_Analog(punteroprogramar, 5), Tabla_Indicador_Analog(punteroprogramar, 10); "}; // Array de indicadores analogicos" Close F Else While (punteroprogramar < Paso1.cantidadindicanalog) texto = texto & Tabla_Indicador_Analog(punteroprogramar, 5) & "," & Tabla_Indicador_Analog(punteroprogramar, 10) & "," punteroprogramar = punteroprogramar + 1 Wend texto = texto & Tabla_Indicador_Analog(punteroprogramar, 5) & "," & Tabla_Indicador_Analog(punteroprogramar, 10) F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, "unsigned int pines_analog_entrada[] = {" & texto & "}; // Array de indicadores analogicos" Close F End If 'Colocar la tercera parte Archivo = "C:\Documents and Settings\Administrador\Mis documentos\Proyecto SCADAv6.2\Archivos de programa\Arduinov1_8B\ARDUINOv1_8\ARDUINOv1_8.pde" Open Archivo For Input As #1 While Not EOF(1) Line Input #1, Linea F = FreeFile Open "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde" For Append As F Print #F, Linea Close F Wend Close #1 'Abrir el archivo Dim res As Long res = ShellExecute(Me.hwnd, "Open", "C:\Documents and Settings\Administrador\Mis documentos\Mis imágenes\sketch_aug16a\sketch_aug16a.pde", "", "", 1) End Sub En líneas generales lo que hace todo este código de programación es unir dos archivos, en los que se encuentra programado aquello que es fijo (comunicaciones) y además le añade ciertos datos (ya mencionados líneas más Memoria. 64 Controlador modular programable basado en procesador de 32 bits y CAN bus arriba) que son variables en función de la aplicación SCADA que haya diseñado el usuario. De manera que a lo largo de todas estas líneas de código se esta siguiendo una serie de pasos que pueden resumirse en unas pocas líneas. El primer paso es abrir un archivo (ubicado en “Archivos de programa”) que contiene cierta información fija, leer su contenido y pegarlo en el sketch a generar. Posteriormente se vuelve a abrir el sketch a generar y se le incluye los datos variables que configuran la placa principal y los diferentes módulos de la red CAN. Una vez en este punto, la siguiente tarea es abrir otro archivo almacenado en la carpeta “Archivos de programa”, leer su contenido y pegarlo al final del sketch que se esta generando. Una vez finalizada esta última acción se abre el sketch y se presenta al usuario, para que este pueda programar su algoritmo de control. Cuando finalice su algoritmo de control, deberá cargar el programa a través del USB que es el medio de comunicación entre la placa principal y el SCADA. Figura 40) Diagrama de flujo. Generar programa para chipKIT. Comunicaciones vía USB, PC-­‐chipKIT. La comunicación chipKIT-­‐PC se lleva a cabo mediante el puerto USB, que en un principio y por las funciones tan simples que hacen posible el envio y recepción de datos, puede parecer una comunicación sencilla, pero nada más lejos de la Memoria. 65 Controlador modular programable basado en procesador de 32 bits y CAN bus realidad. Ya que a diferencia de CAN, este tipo de comunicaciones no presenta una trama predefinida, sino que debe ser el propio diseñador el que genere la trama de entendimiento entre ambas partes. La trama de comunicación chipKIT à PC esta formada por varios campos y presenta la estructura siguiente. Inicio Lectura Checksum Bytes de Separador Bytes del Finalizador de pines pines dato de dato Checksum (.) trama digitales digitales analógico analógico de pines (:) (/) analógicos Esta es la trama que permite al chipKIT reportar la información al SCADA sobre el estado de sus pines de entrada, con el objetivo de que este pueda actualizar las diferentes tablas y de esta manera presentar al usuario la información actualizada (tanto en los indicadores digitales como analógicos). El primero de los campos que manda chipKIT es un byte de inicio de la comunicación, VB hasta que no encuentra este dato desecha toda la información. Una vez que constata que le ha llegado el carácter “:”, lee el siguiente dato o datos en función del número de indicadores que existan. VB tiene en una variable almacenado la cantidad de indicadores que existen y el sabe que si tiene entre 1 y 8 indicadores, únicamente le llegará un dato de lectura de pines digitales, si tiene más de 8 pero menos de 16, le llegarán dos y así sucesivamente como se puede observar en la programación. Una vez que ha leído el dato que contiene información sobre el estado de las entradas digitales, comprueba que esa información ha llegado de manera correcta. Para ello realiza un checksum, es decir, suma todos los datos de lectura de pines que le han llegado y a ese resultado le suma un valor constante. Si ese dato que se obtiene coincide con el siguiente valor que llega por el puerto serie (“checksum pines digitales”), la información ha llegado correctamente, si no es así desecha toda la trama y vuelve a leer. El siguiente paso es leer el estado de las entradas analógicas, por la forma de enviar estos datos de chipKIT, los valores que llegan a VB están separados en cifras, es decir, chipKIT cuando manda un 1023, en realidad manda cuatro bytes en el que el primer byte llega un 1, en el segundo un 0 y así sucesivamente hasta formar la cifra. Este número deberá ser reconstruido en VB para su posterior uso. Una vez leídos todos los datos de los pines analógicos, se lee en campo de “Checksum analógico”, que deberá ser utilizado para comprobar de nuevo que los datos recibidos son correctos. Por último se leerá el campo “Finalizador” que marcará a VB el final de trama. Memoria. 66 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 41) Diagrama de flujo. Comunicación chipKIT-­‐PC La programación que hace posible este entendimiento entre chipKIT y el panel SCADA es la siguiente. Programación en Visual Basic. Private Sub recoge_arduino_Timer() 'COMUNICACIONES Select Case numindicadoresarduino Case 1 To 8 numindicadoresarduino = 2 Case 9 To 16 numindicadoresarduino = 3 Case 17 To 24 numindicadoresarduino = 4 Case 25 To 32 numindicadoresarduino = 5 Case 33 To 40 numindicadoresarduino = 6 Memoria. 67 Controlador modular programable basado en procesador de 32 bits y CAN bus Case 41 To 48 numindicadoresarduino Case 49 To 56 numindicadoresarduino Case 57 To 64 numindicadoresarduino Case 65 To 72 numindicadoresarduino Case 73 To 81 numindicadoresarduino End Select = 7 = 8 = 9 = 10 = 11 If (SerieC.InBufferCount > 113) Then SerieC.InputLen = 0 Label5.Caption = SerieC.Input SerieC.InputLen = 1 End If lee: If (SerieC.InBufferCount <> 0) Then numindicadoresarduino = Paso1.cantidadindica BYTES(0) = SerieC.Input If (BYTES(0) = "+") Then 'MODULOS BYTES(0) = SerieC.Input If (BYTES(0) = "+") Then BYTES(0) = SerieC.Input If (BYTES(0) = "+") Then ' !!!AQUI COMPRUEBO EL DATO DEL QUE SE TRATA Dim msgvalue As Boolean msgvalue = MsgBox("Modulo 0: Conectado" & vbCr & "Modulo 1: Desconectado" & vbCr & "Modulo 2: Desconectado" & vbCr & "Modulo 3: Desconectado", vbOKCancel) BYTES(0) = SerieC.Input End If End If End If If (BYTES(0) = "") Then 'INDICADORES GoTo lee Else If (Asc(BYTES(0)) = 58) Then Select Case numindicadoresarduino Case 1 To 8 numindicadoresarduino = 2 Case 9 To 16 numindicadoresarduino = 3 Case 17 To 24 numindicadoresarduino = 4 Case 25 To 32 numindicadoresarduino = 5 Case 33 To 40 numindicadoresarduino = 6 Case 41 To 48 numindicadoresarduino = 7 Case 49 To 56 Memoria. 68 Controlador modular programable basado en procesador de 32 bits y CAN bus numindicadoresarduino = 8 Case 57 To 64 numindicadoresarduino = 9 Case 65 To 72 numindicadoresarduino = 10 Case 73 To 81 numindicadoresarduino = 11 End Select While (numindicadoresarduino <> 0) BYTES(numindicadoresarduino) = SerieC.Input If (BYTES(numindicadoresarduino) = "") Then BYTES(numindicadoresarduino) = 0 GoTo lee End If numindicadoresarduino = numindicadoresarduino - 1 Wend punteroA = 0 auxiliar = 0 While (auxiliar <> ".") BYTESANALOG(punteroA) = SerieC.Input auxiliar = BYTESANALOG(punteroA) If (BYTESANALOG(punteroA) = "") Then BYTESANALOG(numindicadoresarduinoanalog) = 0 GoTo lee End If punteroA = punteroA + 1 Wend Else GoTo lee End If End If numindicadoresarduino = Paso1.cantidadindica Select Case numindicadoresarduino Case 1 To 8 numindicadoresarduino = 2 Case 9 To 16 numindicadoresarduino = 3 Case 17 To 24 numindicadoresarduino = 4 Case 25 To 32 numindicadoresarduino = 5 Case 33 To 40 numindicadoresarduino = 6 Case 41 To 48 numindicadoresarduino = 7 Case 49 To 56 numindicadoresarduino = 8 Case 57 To 64 numindicadoresarduino = 9 Case 65 To 72 numindicadoresarduino = 10 Case 73 To 81 numindicadoresarduino = 11 Memoria. 69 Controlador modular programable basado en procesador de 32 bits y CAN bus End Select While (numindicadoresarduino <> 0) entero = BYTES(numindicadoresarduino) Checksum = Checksum Xor Asc(entero) numindicadoresarduino = numindicadoresarduino - 2 Wend Checksum = Checksum Xor 17 punteroAA = 0 punteroestadoanalogica = 1 While (punteroAA < punteroA) If (BYTESANALOG(punteroAA) <> "/") And (BYTESANALOG(punteroAA) <> ".") Then cnt = cnt + 1 punteroAA = punteroAA + 1 Else punteroanalog = punteroAA - cnt Select Case cnt Case 1 estadoanalogica(punteroestadoanalogica) = BYTESANALOG(punteroanalog) punteroestadoanalogica = punteroestadoanalogica + 1 Case 2 estadoanalogica(punteroestadoanalogica) = BYTESANALOG(punteroanalog) * 10 punteroanalog = punteroanalog + 1 estadoanalogica(punteroestadoanalogica) = estadoanalogica(punteroestadoanalogica) + BYTESANALOG(punteroanalog) punteroestadoanalogica = punteroestadoanalogica + 1 Case 3 estadoanalogica(punteroestadoanalogica) = BYTESANALOG(punteroanalog) * 100 punteroanalog = punteroanalog + 1 estadoanalogica(punteroestadoanalogica) = estadoanalogica(punteroestadoanalogica) + BYTESANALOG(punteroanalog) * 10 punteroanalog = punteroanalog + 1 estadoanalogica(punteroestadoanalogica) = estadoanalogica(punteroestadoanalogica) + BYTESANALOG(punteroanalog) punteroestadoanalogica = punteroestadoanalogica + 1 Case 4 estadoanalogica(punteroestadoanalogica) = BYTESANALOG(punteroanalog) * 1000 punteroanalog = punteroanalog + 1 estadoanalogica(punteroestadoanalogica) = estadoanalogica(punteroestadoanalogica) + BYTESANALOG(punteroanalog) * 100 punteroanalog = punteroanalog + 1 estadoanalogica(punteroestadoanalogica) = estadoanalogica(punteroestadoanalogica) + BYTESANALOG(punteroanalog) * 10 punteroanalog = punteroanalog + 1 Memoria. 70 Controlador modular programable basado en procesador de 32 bits y CAN bus estadoanalogica(punteroestadoanalogica) = estadoanalogica(punteroestadoanalogica) + BYTESANALOG(punteroanalog) punteroestadoanalogica = punteroestadoanalogica + 1 End Select punteroanalog = 0 punteroAA = punteroAA + 1 cnt = 0 End If Wend punteroAA = 1 Checktramanalog = 0 Checksumanalog = estadoanalogica(punteroestadoanalogica - 1) While (punteroAA < (punteroestadoanalogica - 1)) Checktramanalog = Checktramanalog estadoanalogica(punteroAA) punteroAA = punteroAA + 1 Wend Xor Checktramanalog = Checktramanalog Xor 17 If ((Asc(BYTES(1)) = Checksum) And (Checksumanalog Checktramanalog)) Then 'habilitar_timer = True numindicadoresarduino = Paso1.cantidadindica puntero = 1 Select Case numindicadoresarduino Case 1 To 8 numindicadoresarduino = 2 Case 9 To 16 numindicadoresarduino = 3 Case 17 To 24 numindicadoresarduino = 4 Case 25 To 32 numindicadoresarduino = 5 Case 33 To 40 numindicadoresarduino = 6 Case 41 To 48 numindicadoresarduino = 7 Case 49 To 56 numindicadoresarduino = 8 Case 57 To 64 numindicadoresarduino = 9 Case 65 To 72 numindicadoresarduino = 10 Case 73 To 81 numindicadoresarduino = 11 End Select While (numindicadoresarduino <> 1) Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 128) / 128 puntero = puntero + 1 Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 64) / 64 puntero = puntero + 1 Memoria. = 5) = 5) = 71 Controlador modular programable basado en procesador de 32 bits y CAN bus Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 32) / 32 puntero = puntero + 1 Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 16) / 16 puntero = puntero + 1 Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 8) / 8 puntero = puntero + 1 Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 4) / 4 puntero = puntero + 1 Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 2) / 2 puntero = puntero + 1 Tabla_Indicador_Dig(puntero, (Asc(BYTES(numindicadoresarduino)) And 1) numindicadoresarduino numindicadoresarduino - 1 Wend 5) = 5) = 5) = 5) = 5) = 5) = = punteroAA = 1 puntero = 1 While (punteroAA < (punteroestadoanalogica - 1)) Tabla_Indicador_Analog(puntero, 4) estadoanalogica(punteroAA) punteroAA = punteroAA + 1 puntero = puntero + 1 Wend = Else Checksum = 0 Checksumanalog = 0 GoTo lee End If numindicadores = Paso1.cantidadindica While numindicadores <> 0 If Tabla_Indicador_Dig(numindicadores, 5) = 1 Then mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).Picture = LoadPicture(Tabla_Indicador_Dig(numindicadores, 2)) SetLayeredWindowAttributes mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).hwnd, RGB(0, 0, 255), 0, LWA_COLORKEY mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).ScaleMode = 3 mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).AutoRedraw = True mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).PaintPicture mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).Picture, _ 0, 0, mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).ScaleWidth, mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).ScaleHeight Else mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).Picture = LoadPicture(Tabla_Indicador_Dig(numindicadores, 3)) SetLayeredWindowAttributes mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).hwnd, RGB(0, 0, 255), 0, LWA_COLORKEY Memoria. 72 Controlador modular programable basado en procesador de 32 bits y CAN bus mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).ScaleMode = 3 mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).AutoRedraw = True mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).PaintPicture mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).Picture, _ 0, 0, mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).ScaleWidth, mi_imagen(Tabla_Indicador_Dig(numindicadores, 1)).ScaleHeight End If numindicadores = numindicadores - 1 Wend numindicadoresanalog = Paso1.cantidadindicanalog While numindicadoresanalog <> 0 ProgressBar1(numindicadoresanalog).Max Tabla_Indicador_Analog(numindicadoresanalog, 2) ProgressBar1(numindicadoresanalog).Min Tabla_Indicador_Analog(numindicadoresanalog, 1) ProgressBar1(numindicadoresanalog).Value (Tabla_Indicador_Analog(numindicadoresanalog, 4) (Tabla_Indicador_Analog(numindicadoresanalog, 2) Tabla_Indicador_Analog(numindicadoresanalog, 1)) / 1023) (Tabla_Indicador_Analog(numindicadoresanalog, 1)) Label1(numindicadoresanalog).Caption Round((Tabla_Indicador_Analog(numindicadoresanalog, 4) (Tabla_Indicador_Analog(numindicadoresanalog, 2) Tabla_Indicador_Analog(numindicadoresanalog, 1)) / 1023) (Tabla_Indicador_Analog(numindicadoresanalog, 1))) (Tabla_Indicador_Analog(numindicadoresanalog, 9)) numindicadoresanalog = numindicadoresanalog - 1 Wend = = = * + = * + & End If End Sub Programación en chipKIT. //----------------------------------------------------------------//ZONA DE COMUNICACIONES. NO REALIZE NINGÚN CAMBIO POR FAVOR. //----------------------------------------------------------------//Declaro variables para controles. unsigned int dato; // variable con la que voy desapilando el buffer. int num_led; //Me indica el LED a encender en los controles int brillo; //Me indica el brillo que le quiero dar al LED en los controles analogicos int estado; // Me indica el estado de los controles digitales //Declaro variables para indicadores int punteroindicadoresdig; int datoindic; // Dato que le mando a VB para informarle de 7 en 7 del estado de los indicadores int datoindic2; // Dato que le mando a VB para informarle de 7 en 7 del estado de los indicadores int datoindic3; int datoindic4; Memoria. 73 Controlador modular programable basado en procesador de 32 bits y CAN bus int datoindic5; int datoindic6; int datoindic7; int datoindic8; int datoindic9; int datoindic10; int checksum; //Dato con el que comparo a ver si puedo comenzar a enviar el estado de los indicadores datoindic =0; checksum = 0; datoindic2 = 0; datoindic3 = 0; datoindic4 = 0; datoindic5 = 0; datoindic6 = 0; datoindic7 = 0; datoindic8 = 0; datoindic9 = 0; datoindic10 = 0; int punteroindicadoresanalog; int checksumanalog; checksumanalog = 0; //MAPA DE MEMORIA int zonas_controles_digitales[80]; //ZONA EN LA QUE ESTA EL ESTADO DE LOS CONTROLES DIGITALES, ORDENADOS POR PINES. EJ 46 VALOR, ESTADO DEL PIN 46 int zonas_controles_analogicos[11]; //ZONA EN LA QUE ESTA EL ESTADO DE LOS CONTROLES ANALOGICOS, SE ORDENAN DE LA MISMA MANERA QUE EN EL ANTERIOR int zonas_indicadores_digitales[80]; //ZONA EN LA QUE SE ENCUENTRA EL ESTADO DE LOS INDICADORES DIGITALES, ORDENADOS POR LOS PINES INDICADOS EN LA VARIABLE ARRAY. EL PRIMER VALOR int i=0; // SERA EL ESTADO DEL PIN 33. for(i=0; i<80; i++){ zonas_indicadores_digitales[i]=0; } int zonas_indicadores_analogicos[16]; //ZONA EN LA QUE SE ENCUENTRA EL ESTADO DE LOS INDICADORES ANALOGICOS //Zona en la que se va a enviar la configuración de los pines a cada módulo //Zona en la que se va a leer el buffer de entrada, para poder actualizar los controles. if(Serial.available()) { while (Serial.available()>0){ dato = Serial.read(); //read Serial if (dato == 0){ dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; //delay(1000); dato = Serial.read(); brillo = dato; //read Serial Memoria. 74 Controlador modular programable basado en procesador de 32 bits y CAN bus analogWrite(num_led,brillo); zonas_controles_analogicos[num_led] = brillo; } else{ num_led = (dato & 0x7E) >>1; //delay(1000); estado = (dato & 0x80) >> 7; digitalWrite(num_led,estado); zonas_controles_digitales[num_led] = estado; } } if (dato == 1){ lcd.setCursor(0, 1); lcd.print("MODULO 1"); } } } //Zona en la que se va a enviar la tabla de indicadores, para que los lea VB. int punteroauxiliar; // Con este recorro la tabla de pines indicadores digitales int punteroM1ID; punteroindicadoresdig = 0; //Indicadores DIGITALES punteroauxiliar =0; punteroM1ID = 0; while (punteroindicadoresdig != cantidad * 2){ PIN = pines_digi_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; MODULO = pines_digi_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; switch (MODULO){ case 0: //MODULO 0 zonas_indicadores_digitales[punteroindicadoresdig] = digitalRead (PIN); punteroindicadoresdig = punteroindicadoresdig +1 ; break; case 1: //MODULO 1 while (PIN != MODULO1_ID[punteroM1ID]){ punteroM1ID = punteroM1ID + 2; } punteroM1ID = punteroM1ID + 1; zonas_indicadores_digitales[punteroindicadoresdig] = MODULO1_ID[punteroM1ID]; punteroM1ID = 0; punteroindicadoresdig = punteroindicadoresdig +1 ; break; case 2: //MODULO 2 while (PIN != MODULO2_ID[punteroM1ID]){ punteroM1ID = punteroM1ID + 2; } punteroM1ID = punteroM1ID + 1; zonas_indicadores_digitales[punteroindicadoresdig] = MODULO2_ID[punteroM1ID]; punteroM1ID = 0; punteroindicadoresdig = punteroindicadoresdig +1 ; break; Memoria. 75 Controlador modular programable basado en procesador de 32 bits y CAN bus case 3: //MODULO 3 while (PIN != MODULO3_ID[punteroM1ID]){ punteroM1ID = punteroM1ID + 2; } punteroM1ID = punteroM1ID + 1; zonas_indicadores_digitales[punteroindicadoresdig] = MODULO3_ID[punteroM1ID]; punteroM1ID = 0; punteroindicadoresdig = punteroindicadoresdig +1 ; break; } } punteroindicadoresdig = 0; switch (cantidad) { case 1 ... 8: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = datoindic ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(checksum,BYTE); break; case 9 ... 16: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(checksum,BYTE); break; case 17 ... 24: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } Memoria. 76 Controlador modular programable basado en procesador de 32 bits y CAN bus while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(checksum,BYTE); break; case 25 ... 32: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^datoindic4) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(checksum,BYTE); break; Memoria. 77 Controlador modular programable basado en procesador de 32 bits y CAN bus case 33 ... 40: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = datoindic5 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^datoindic4 ^datoindic5) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(checksum,BYTE); break; case 41 ... 48: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; Memoria. 78 Controlador modular programable basado en procesador de 32 bits y CAN bus } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = datoindic5 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = datoindic6 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^datoindic4 ^datoindic5^datoindic6) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(checksum,BYTE); break; case 49 ... 56: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; Memoria. 79 Controlador modular programable basado en procesador de 32 bits y CAN bus punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = datoindic5 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = datoindic6 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = datoindic7 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(checksum,BYTE); break; case 57 ... 64: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; Memoria. 80 Controlador modular programable basado en procesador de 32 bits y CAN bus datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = datoindic5 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = datoindic6 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = datoindic7 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic8 <<1; datoindic6 = datoindic8 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7 ^ datoindic8) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(datoindic8,BYTE); Serial.print(checksum,BYTE); break; case 65 ... 72: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; Memoria. 81 Controlador modular programable basado en procesador de 32 bits y CAN bus punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = datoindic5 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = datoindic6 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = datoindic7 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic8 <<1; datoindic6 = datoindic8 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic9 <<1; datoindic6 = datoindic9 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } Memoria. 82 Controlador modular programable basado en procesador de 32 bits y CAN bus checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7 ^ datoindic8 ^ datoindic9) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(datoindic8,BYTE); Serial.print(datoindic9,BYTE); Serial.print(checksum,BYTE); break; case 73 ... 80: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = datoindic2 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = datoindic3 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = datoindic4 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = datoindic5 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = datoindic6 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ Memoria. 83 Controlador modular programable basado en procesador de 32 bits y CAN bus datoindic6 = datoindic7 <<1; datoindic6 = datoindic7 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic8 <<1; datoindic6 = datoindic8 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic9 <<1; datoindic6 = datoindic9 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic10 <<1; datoindic6 = datoindic10 + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7 ^ datoindic8 ^ datoindic9 ^ datoindic10) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(datoindic8,BYTE); Serial.print(datoindic9,BYTE); Serial.print(datoindic10,BYTE); Serial.print(checksum,BYTE); break; } int punteroM1IA; //Indicadores ANALOGICOS punteroindicadoresanalog = 0; punteroauxiliar =0; punteroM1IA = 0; PIN = 0; MODULO = 0; while (punteroindicadoresanalog != cantidadanalog * 2){ PIN = pines_analog_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; MODULO = pines_analog_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; switch (MODULO){ case 0: //MODULO 0 Memoria. 84 Controlador modular programable basado en procesador de 32 bits y CAN bus zonas_indicadores_analogicos[punteroindicadoresanalog] = analogRead (PIN); punteroindicadoresanalog = punteroindicadoresanalog +1 ; break; case 1: //MODULO 1 while (PIN != MODULO1_IA[punteroM1IA]){ punteroM1IA = punteroM1IA + 2; } punteroM1IA = punteroM1IA + 1; zonas_indicadores_analogicos[punteroindicadoresanalog] MODULO1_IA[punteroM1IA]; punteroM1IA = 0; punteroindicadoresanalog punteroindicadoresanalog +1 ; break; case 2: //MODULO 2 while (PIN != MODULO2_IA[punteroM1IA]){ punteroM1IA = punteroM1IA + 2; } punteroM1IA = punteroM1IA + 1; = = zonas_indicadores_analogicos[punteroindicadoresanalog] MODULO2_IA[punteroM1IA]; punteroM1IA = 0; punteroindicadoresanalog punteroindicadoresanalog +1 ; break; case 3: //MODULO 3 while (PIN != MODULO3_IA[punteroM1IA]){ punteroM1IA = punteroM1IA + 2; } punteroM1IA = punteroM1IA + 1; = zonas_indicadores_analogicos[punteroindicadoresanalog] MODULO3_IA[punteroM1IA]; punteroM1IA = 0; punteroindicadoresanalog punteroindicadoresanalog +1 ; break; } } = = = punteroindicadoresanalog = 0; checksumanalog = 0; while (punteroindicadoresanalog != cantidadanalog){ Serial.print(zonas_indicadores_analogicos[punteroindicadoresanalog] ); checksumanalog = checksumanalog ^ zonas_indicadores_analogicos[punteroindicadoresanalog] ; punteroindicadoresanalog = punteroindicadoresanalog +1 ; Serial.print (47,BYTE); } checksumanalog = checksumanalog ^17; Serial.print (checksumanalog); Serial.print (46,BYTE); Memoria. 85 Controlador modular programable basado en procesador de 32 bits y CAN bus 8.2.4 Manual de usuario del panel SCADA. Como ya se ha hecho mención anteriormente, el panel SCADA esta formado por cuatro pantallas, cuya programación ya ha sido analizada extensamente. A continuación se va a presentar los resultados visuales de dicha programación. La primera pantalla que aparece es una pantalla de presentación, en la que aparecen dos botones, los cuales rezan de la siguiente manera, “PROYECTO NUEVO” y “PROYECTO EXISTENTE”. El primero de los botones permite crear un SCADA desde cero, por su parte el segúndo botón concede al usuario la posibilidad de partir de un panel SCADA ya realizado o en proceso de realización. Figura 42) Pantalla de presentación de la aplicación. Se va a partir del supuesto caso en que el usuario decide crear el proyecto desde cero, ya que la única diferencia que existe con respecto a la otra opción es la no necesidad de pasar por una pantalla intermedia, que se va a analizar a continuación. Si por el contrario, se pulsaría la opción de “PROYECTO EXISTENTE”, la aplicación direccionaria al usuario a la última de las pantallas, una vez ahí, este debería pulsar el botón cargar y seleccionar el archivo (.xlsx) que desea cargar. La siguiente pantalla a la que nos conducirá la aplicación será un formulario limpio, que recibirá al usuario con una ventana emergente, en la que se le pedirá que “delimite la zona en la que se desea colocar la imagen de fondo”. Figura 43) Asistente de creación del panel SCADA Memoria. 86 Controlador modular programable basado en procesador de 32 bits y CAN bus El primer paso a realizar en esta pantalla, será delimitar el área en la que se quiere colocar la imagen. Esto se consigue de la misma manera que cuando se quiere realizar una selección sobre cualquier aplicación Windows. Una vez que ya se le ha indicado a la aplicación el área en la que se quiere imprimir la imagen aparecerá de nuevo otra ventana emergente, que indicará al usuario cual es el paso siguiente, “Cargue la imagen de fondo”. Figura 44) Asistente de creación del panel SCADA Pulsando sobre el botón cargar, se desplegará una pantalla emergente en la que se solicitará la ruta de la imagen de fondo. Figura 45) Solicita la ruta de la imagen de fondo. Una vez seleccionado el archivo .jpeg que se desea cargar, inmediatamente se colocará la imagen sobre el fondo. Memoria. 87 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 46) Estado de la aplicación una vez cargada la imagen de fondo. Se pulsa el botón siguiente para pasar a la siguiente página en la que se podrá llevar a cabo la creación de los diferentes elementos que permitirán al usuario interacturar con el proceso. Una vez situado el la tercera página, de nuevo aparecerá una ventana emergente en la que pedirá al usuario que “marque las zonas a controlar y edítelas”. Figura 47) El asistente indica al usuario que puede comenzar a crear las zonas de control. Memoria. 88 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 48) Asistente de cración del panel SCADA. De manera, que siguiendo las instrucciones del asistente la siguiente tarea será crear las diferentes zonas de control. Para ello, de nuevo se marca la zona sobre la que se desea situar el elemento de control, en caso de que el usuario no esté convencido con el resultado obtenido, posee un botón de “MODIFICAR” que le permite borrar esta zona y volver a crear otra. Una vez que el usuario decida que esa es la zona final sobre la que desea colocar el elemento de control, pulsará en la zona remarcada y le aparecerá una ventana emergente a modo de formulario, que deberá rellenar para seleccionar si desea crear un botón, un shape, un slider, una etiqueta o una progressbar. Figura 49) Formulario para crear los diferentes elementos de control. Memoria. 89 Controlador modular programable basado en procesador de 32 bits y CAN bus En caso de querer crear un botón el formulario deberá ser rellenado de la siguiente manera. Figura 50) Formulario rellenado para crear un botón. De manera que estamos creando un control booleano, cuyo estado por defecto es apagado y que configura al pin 25 del módulo cero como salida. Así mismo, en la parte de la derecha del formulario, permite elegir si se quiere un botón de color (que se ponga en verde cuando el actuador este encendido o en rojo en caso contrario) o un botón animado en el que se alterne la imagen elegida en función de la posición en que se encuentre. Una vez cumplimentado el formulario, se pulsa el botón Agregar, con el fin de guardar este componente y posteriormente se pulsa Aceptar para posicionar el control seobre la imagen de fondo. Figura 51) Aplicación SCADA con el botón ya creado. Memoria. 90 Controlador modular programable basado en procesador de 32 bits y CAN bus Si el usuario necesita crear un slider o text, deberá cumplimentar el formulario de la siguiente manera. Figura 52) Formulario rellenado para crear un slider. De nuevo creamos un control, pero en este caso los datos con los que trabaja son de tipo real. Se le indicará por tanto cual será el valor máximo y mínimo con los que se quiere trabajar y la aplicación de manera interna (como ya se ha explicado anteriormente) llevará a cabo el escalado. Se configura como salida analógica el pin 10 de módulo 0 y se le indica a la aplicación que cuando ofrezca el valor en el que este posicionado el slider lo acompañe de la unidad de medida que se le indique. Una vez realizado el formulario se seguirán la operativa será la misma que la expuesta en el punto anterior. Figura 53) Aplicación SCADA con el slider ya creado. Memoria. 91 Controlador modular programable basado en procesador de 32 bits y CAN bus En caso de querer crear un text, el formulario se rellena de la misma manera que en el anterior punto a excepción de que hay que marcar el check “text Analógico”. Figura 54) Formulario rellenado para crear un text. Figura 55) Panel SCADA con el text ya creado. Memoria. 92 Controlador modular programable basado en procesador de 32 bits y CAN bus Para crear una progressbar el proceso es el mismo que con el resto de controles, únicamente cambia la manera de rellenar el formulario. Figura 56) Formulario rellenado para crear una progressbar. En este caso se ha seleccionado un indicador (pin 0 del módulo 0), que trabajará con datos reales (analógicos), cuyos valores oscilarán entre 0 y 30. En la parte derecha se puede seleccionar la forma de relleno, o bien vertical o bien horizontal, así como el color de fondo y el color de la barra de progreso. De nuevo se le da la posibilidad al usuario de definir las unidades con las que esta trabajando y que acompañarán al dato que indica cual es el valor de la entrada analógico (esta valor ya esta escalado, en este caso entre 0 y 30). Así mismo el usuario podrá utilizar el servicio de gestión de alarmas marcando el check “Generar alarma”. Los campos que debe de rellenar es el valor límite a partir del cual quiere que se genere la alarma y el texto que quiere que aparezca. Figura 57) Generación de alarma tras superar el valor límite. Memoria. 93 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 58) Aplicación SCADA con la progressbar ya creada. El último elemento a crear, es un shape, que requiere rellenar el formulario como se expone a continuación. Figura 59) Formulario rellenado para crear un shape. Con este formulario se indica que el pin 35 del módulo 0 debe trabajar como entrada digital (Booleano, Indicador) y que parte de un estado por defecto de cero (en este caso de apertura total de la válvula). En la parte de la derecha existen dos zonas que pinchando sobre ellas dan la posibilidad al usuario de seleccionar la ruta de las imágenes que deben aparecer en función del estado de las entrada. Además se ha seleccionado que se genere una alarma cuando el sensor transmita cero voltios. Memoria. 94 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 60) Generación de alarma. De nuevo se pulsa Agregar y Aceptar y se cierra la ventana emergente apareciendo el shape en la página principal. Figura 61) Aplicación SCADA con el shape ya creado. Una vez que se tienen creados todos los elementos de control necesarios, es una práctica recomendable guardar la aplicación, para ello se pulsa el botón “GUARDAR” y se presentara una ventana emergente que solicitara al usuario el nombre que quiere dar al archivo y donde lo quiere guardar, tras cumplimentar ambas acciones la aplicación SCADA ya estará salvada y esperando a que en algún otro momento pueda ser cargada. Figura 62) Ventana emergente que solicita la ruta en la que se quiere guardar la aplicación. El siguiente paso es generar el código que necesita el chipKIT principal para poder gestionar tanto las comunicaciones con el PC como con los distintos módulos integrados en el bus CAN, así como la configuración de los pines de cada uno de los módulos que existen en la red CAN. Para ello, se pulsa el botón “PROGRAMAR chpKIT”, la ventana emergente que aparece es la siguiente. Memoria. 95 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 63) Ventana de programación y compilación chipKIT. *Antes de realizar esta acción el usuario debe asegurarse que esta conectado el PC con la placa de desarrollo mediante el cable USB. Una vez que aparezca el entorno de programación de chipKIT, el usuario deberá buscar la zona en la que ponga “Escriba el código programa a partir de esta zona” y ahí programar su algoritmo de control. Cuando ya lo tenga programado deberá cargar el programa a la placa, mediante la pulsación del botón: Figura 64) Botón transferir. En ese momento se comenzará a transferir el programa, mientras se este realizando esta acción no se debe modificar ninguna línea de la programación. Memoria. 96 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 65) Programa transfiriéndose al chipKIT. Una vez se ha transferido el programa de manera correcta, se pulsa el botón “CONECTAR” que permitirá establecer las comunicaciones entre los diferentes módulos y el panel SCADA. Inmediatamente después de realizar esta acción, saltará un aviso en el que se comunicará el estado de todos los módulos de la red CAN y el usuario deberá decidir si desea continuar o por el contrario reiniciar la conexión. Figura 66) Estado de los módulos del bus CAN. Figura 67) La aplicación funcionando. Memoria. 97 Controlador modular programable basado en procesador de 32 bits y CAN bus 8.3 Descripción de las comunicaciones. A continuación se pasará a describir el enlace de comunicación CAN, el cual permitirá el intercambio de información entre los diferentes módulos y el panel SCADA. Dicha labor requiere de dos actores principales, la unidad master (módulo cero) y los slaves que se necesiten (módulos uno, dos y tres). La unidad master tiene como misión: gestionar la configuración de los slaves, y transmitir al SCADA la información proveniente de los mismos. Por su parte, las unidades slaves únicamente deberán estar reportando información de sus pines configurados como entradas y además, estar atentas a si el master les indica que deben cambiar el estado de sus pines de salida. Si el usuario decidierá que se le quiere integrar algún tipo de algoritmo de control, únicamente debería de programarlo en la zona destinada para ello. Descripción de la programación que configura los slaves desde el módulo master. Antes de proceder a la configuración de los slaves, es necesario realizar unos pasos previos: 1.-­‐ Declaración de variables. 2.-­‐ Definición de filtros. 3.-­‐ Inicialización de los nodos. 4.-­‐ Programación de funciones de utilidad CAN y comprobación de su estado. Memoria. 98 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 68) Pasos previos a la configuración de los nodos. Líneas de programación // Incluir librerías: #include <WProgram.h> #include "chipKITCAN.h" #include <LiquidCrystal.h> // inicializar la libreria con el numero de pins del interfaz LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // ------------------------------------------------------------// Definición de constantes y variables locales // ------------------------------------------------------------// Direcciones de red de los nodos //FILTROS #define FILTROCONFIGURA_M1D 0x0100L //Filtro para configurar #define FILTROCONFIGURA_M1A 0x0101L //Filtro para configurar slave1 slave1 Memoria. 99 Controlador modular programable basado en procesador de 32 bits y CAN bus #define FILTROCONFIGURA_M2D 0x0200L //Filtro para configurar #define FILTROCONFIGURA_M2A 0x0201L //Filtro para configurar #define FILTROCONFIGURA_M3D 0x0300L //Filtro para configurar #define FILTROCONFIGURA_M3A 0x0301L //Filtro para configurar slave2 slave2 slave3 slave3 #define FILTROINFORMATIVO_FC_M1 0x0111L //Filtro indicar al módulo 1 que ya no le va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x1011L indicando al modulo 0 que ya esta configurado //Filtro que manda modulo 1 #define FILTROINFORMATIVO_FC_M2 0x0211L //Filtro indicar al módulo 2 que ya no le va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M2 0x2011L indicando al modulo 0 que ya esta configurado //Filtro que manda modulo 2 #define FILTROINFORMATIVO_FC_M2 0x0311L //Filtro indicar al módulo 3 que ya no le va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M3 0x3011L indicando al modulo 0 que ya esta configurado //Filtro que manda modulo 3 #define FILTROINFORMATIVO_ESTADO_M1D manda el estado de un pin digital 0x101100L //El modulo 1 me #define FILTROINFORMATIVO_ESTADO_M2D manda el estado de un pin digital 0x201100L //El modulo 2 me #define FILTROINFORMATIVO_ESTADO_M3D manda el estado de un pin digital 0x301100L //El modulo 3 me #define FILTROINFORMATIVO_ESTADO_M1A manda el estado de un pin analogico 0x101101L //El modulo 1 me #define FILTROINFORMATIVO_ESTADO_M2A manda el estado de un pin analogico 0x201101L //El modulo 2 me #define FILTROINFORMATIVO_ESTADO_M3A manda el estado de un pin analógico 0x301101L //El modulo 3 me #define FILTROINFORMATIVO_CONTROL_M1A 0x011101L como quiere que ponga un pin analogico en el modulo 1 //El modulo 0 manda #define FILTROINFORMATIVO_CONTROL_M2A 0x021101L como quiere que ponga un pin analogico en el modulo 2 //El modulo 0 manda #define FILTROINFORMATIVO_CONTROL_M3A 0x031101L como quiere que ponga un pin analogico en el modulo 3 //El modulo 0 manda #define FILTROINFORMATIVO_CONTROL_M1D 0x011100L como quiere que ponga un pin digital en el modulo 1 //El modulo 0 manda #define FILTROINFORMATIVO_CONTROL_M2D 0x021100L como quiere que ponga un pin digital en el modulo 2 //El modulo 0 manda #define FILTROINFORMATIVO_CONTROL_M3D 0x031100L como quiere que ponga un pin digital en el modulo 3 //El modulo 0 manda Memoria. 100 Controlador modular programable basado en procesador de 32 bits y CAN bus #define modulo1can1 0x110L #define modulo2can1 0x120L #define modulo3can1 0x130L #define modulo0can1 0x110L // Definición de la frecuencia y de la velocidad #define SYS_FREQ (80000000L) #define CAN_BUS_SPEED 250000 // velocidad CAN // -----------------------------------------------------------// Variables globales // -----------------------------------------------------------// Interfaz de instancias del nodo controlador CAN CAN canMod1(CAN::CAN1); // este objeto lo usa el modulo CAN1 CAN canMod2(CAN::CAN2); // este objeto lo usa el modulo CAN2 byte DatosMsg[7]; // -----------------------------------------------------------// Variables locales // -----------------------------------------------------------uint8_t el modulo REMOTA = 0x0C; // Indico si esta correcto // Buffer de mensajes CAN uint8_t CAN1MessageFifoArea [2 * 8 * 16]; uint8_t CAN2MessageFifoArea [2 * 8 * 16]; // Flags indicadores de eventos de las rutinas de interrupción. static volatile bool isCAN1MsgReceived = false; static volatile bool isCAN2MsgReceived = false; // -----------------------------------------------------------// Declaraciones directas // ------------------------------------------------------------ void initCan1 (uint32_t myaddr); void doCan1Interrupt(); void txCAN1remota(uint32_t rxnode, uint8_t dato); envió de tramas remotas void txCAN1(uint32_t dato2, uint8_t dato ); rxnode, uint8_t dato0, // uint8_t Memoria. función dato1, para uint8_t 101 Controlador modular programable basado en procesador de 32 bits y CAN bus void rxCAN1remota(void); las tramas remotas // función para recibir void rxCAN1(void); // -----------------------------------------------------------// Definición de procedimientos // -----------------------------------------------------------void setup(){ lcd.begin(16, 2); // inicializar LCD lcd.print("PROYECTO"); // Escribir un mensaje en LCD Serial.begin(9600); //Puerto serie, configuración // Inicializar cada controlador CAN que va a ser usado. (En este caso solo se utiliza el CAN1) // Instalar las rutinas de servicio de interrupción. canMod1.attachInterrupt (doCan1Interrupt); // Inicializar cada controlador CAN que va a ser usado. (En este caso solo se utiliza el CAN1) initCan1 (modulo0can1); //Inicialización de los diferentes nodos initCan1 (modulo1can1); initCan1 (modulo2can1); initCan1 (modulo3can1); //Comprobación correctos de que los nodos conectados txCAN1remota (modulo0can1, REMOTA); tramas remotas al bus can están // función para envió de delay(100); // Espera a que el carácter sea entregado rxCAN1remota (); (dentro de esta función // función para recibir tramas remotas // escribe el mensaje si esta activo o no lo esta) Memoria. 102 Controlador modular programable basado en procesador de 32 bits y CAN bus txCAN1remota tramas remotas (modulo1can1, REMOTA);// función para envió de delay(100); // Espera a que el carácter sea entregado rxCAN1remota (); (dentro de esta función // función para recibir tramas remotas // escribe el mensaje si esta activo o no lo esta) txCAN1remota (modulo2can1, REMOTA); tramas remotas // función para envió de delay(100); // Espera a que el carácter sea entregado rxCAN1remota (); (dentro de esta función // función para recibir tramas remotas // escribe el mensaje si esta activo o no lo esta) txCAN1remota tramas remotas (modulo3can1, REMOTA); // función para envió de delay(100); // Espera a que el carácter sea entregado rxCAN1remota ();// función para recibir de esta función tramas remotas (dentro // escribe el mensaje si esta activo o no lo esta) Serial.print(43,BYTE); // Dice cual es el estado de los modulos al panel SCADA Serial.print(43,BYTE); Serial.print(43,BYTE); // FIN BUS CAN Una vez cumplimentados los pasos previos anteriormente descritos, ya se puede comenzar a configurar uno a uno todos los módulos tal y como se expone a continuación. Memoria. 103 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 69) Configuración de los nodos de la red CAN. En el diagrama de flujo superior se observa que este proceso únicamente se ejecutará una vez, ya que cuando todo este correcto, la variable configurado pasará a estado TRUE, impidiendo de esta manera que se pueda volver a ejecutar el ciclo de configuración. A continuación, se expondrá de manera detallada el bloque “Envio trama configuración de módulo 1”, que conceptualmente es exactamente igual que los dos bloques siguientes (“Envio trama configuración de módulo 2” y “Envio trama configuración de módulo 3”). Memoria. 104 Controlador modular programable basado en procesador de 32 bits y CAN bus Figura 70) Subproceso para configuración de módulos. Para que se pueda ejecutar este proceso, previamente el panel SCADA ha debido de programar los arrays que contienen los pines de entradas (tanto digitales como analógicas) con los que debe de trabajar cada módulo. Estos arrays serán consultados dato a dato y se irán mandando a su módulo correspondiente a través de la siguiente trama. FILTRO PIN Figura 71) Trama de configuración de los slaves En el campo filtro se enviará 01XX, el cero codifica el origen del envio, el uno codifica el destino y los dos siguientes informan de que es una trama de configuración en la que se manda el pin que deberá actuar como entrada analógica (01) o como entrada digital (00). En el segundo campo se le manda el dato extraido del array, que es el pin a configurar como entrada analógica o digital. En los dos siguientes pasos básicamente se hace lo mismo que lo expuesto anteriormente, salvo con la diferencia que en este caso se recorre el array que contiene los pines que actuarán como entradas analógicas. Una vez recorridos ambos arrays, se informa al módulo correspondiente de que ya no se va a mandar más datos de configuración. Para ello se envía una trama como esta: Memoria. 105 Controlador modular programable basado en procesador de 32 bits y CAN bus FILTRO 0xFF Figura 72) Trama de fin de datos para configurar. En el campo filtro se enviará 0111, los dos primeros bits indican lo mismo que en el anterior caso y los dos segundos indican que se trata de una trama informativa. El segundo campo es algo fijo y que el chipKIT slave identificará como final de la configuración Una vez enviada esta trama, el módulo cero se mantendrá a la espera de que el módulo 1 le informe de que ya ha sido configurado. El identificador que debe esperar el módulo cero para captar ese dato será 1011, es decir, origen módulo uno, destino módulo cero y dato informativo. El segundo dato que le acompañara será un FF, que significa que todo esta correcto. Si recibe la confirmación continua el ciclo de manera normal, si por el contrario no obtiene respuesta, volverá a intentar configurar el slave cero. Líneas de programación. //CONFIGURACION DE LOS MODULOS INTEGRADOS EN EL BUS CAN. byte tamano; byte punteroCAN; byte intentos; if (CONFIGURADO == false){ otra: punteroCAN = 0; //MODULO 1 tamano = sizeof(PINES_MODULO1_ID)/4; while (punteroCAN <= tamano){ //Le indico cuales son sus pines de entrada digitales txCAN1(FILTROCONFIGURA_M1D,PINES_MODULO1_ID[punteroCAN],0,0); punteroCAN = punteroCAN +1; } tamano = 0; punteroCAN=0; tamano = sizeof(PINES_MODULO1_IA)/4; while (punteroCAN <= tamano){ indico cuales son sus pines de entrada analógicos //Le txCAN1(FILTROCONFIGURA_M1A,PINES_MODULO1_IA[punteroCAN],0,0); punteroCAN = punteroCAN +1; } Memoria. 106 Controlador modular programable basado en procesador de 32 bits y CAN bus txCAN1(FILTROINFORMATIVO_FC_M1,0xFF,0x00,0x00); le he mandado todos los valores para que se configure rxCAN1(DatosMsg); esta configurado //Le indico que ya // Espero a que me confirme que if (DatosMsg[0] == FILTROINFORMATIVO_ACK_M1 && DatosMsg[1] == 0xFF ){ CONFIGURADOM1 = true; goto M2; } else { intentos = intentos +1; if (intentos == 3){ goto M2; } else{ goto otra; } } intentos = 0; M2: punteroCAN = 0; //MODULO 2 tamano = sizeof(PINES_MODULO2_ID)/4; while (punteroCAN <= tamano){ indico cuales son sus pines de entrada digitales //Le txCAN1(FILTROCONFIGURA_M2D,PINES_MODULO2_ID[punteroCAN],0,0); punteroCAN = punteroCAN +1; } tamano = 0; punteroCAN=0; tamano = sizeof(PINES_MODULO2_IA)/4; while (punteroCAN <= tamano){ indico cuales son sus pines de entrada analógicos //Le txCAN1(FILTROCONFIGURA_M1A,PINES_MODULO2_IA[punteroCAN],0,0); punteroCAN = punteroCAN +1; } txCAN1(FILTROINFORMATIVO_FC_M1,0xFF,0xFF,0xFF); le he mandado todos los valores para que se configure //Le indico que ya Memoria. 107 Controlador modular programable basado en procesador de 32 bits y CAN bus rxCAN1(DatosMsg); esta configurado // Espero a que me confirme que if (DatosMsg[0] == FILTROINFORMATIVO_ACK_M2 && DatosMsg[1] == 0xFF){ CONFIGURADOM2 = true; goto M3; } else{ intentos = intentos +1; if (intentos == 10){ goto M3; } else{ lcd.setCursor(0, 1); lcd.print(intentos); goto M2; } } intentos = 0; M3: punteroCAN = 0; //MODULO 3 tamano = sizeof(PINES_MODULO3_ID)/4; while (punteroCAN <= tamano){ indico cuales son sus pines de entrada digitales //Le txCAN1(FILTROCONFIGURA_M3D,PINES_MODULO3_ID[punteroCAN],0,0); punteroCAN = punteroCAN +1; } tamano = 0; punteroCAN=0; tamano = sizeof(PINES_MODULO3_IA)/4; while (punteroCAN <= tamano){ indico cuales son sus pines de entrada analógicos //Le txCAN1(FILTROCONFIGURA_M3A,PINES_MODULO3_IA[punteroCAN],0,0); punteroCAN = punteroCAN +1; } Memoria. 108 Controlador modular programable basado en procesador de 32 bits y CAN bus txCAN1(FILTROINFORMATIVO_FC_M1,0xFF,0xFF,0xFF); //Le indico que ya le he mandado todos los valores para que se configure rxCAN1(DatosMsg); // Espero a que me confirme que esta configurado if (DatosMsg[0] == FILTROINFORMATIVO_ACK_M3 && DatosMsg[1] == 0xFF){ CONFIGURADOM3 = true; goto M4; } else{ intentos = intentos +1; if (intentos == 15){ goto M4; } else{ lcd.setCursor(0, 1); lcd.print(intentos); goto M3; } } M4: CONFIGURADO == true; //En realidad no se pondría configurado a true hasta que todos los modulos estarían OK! } Memoria. 109 Controlador modular programable basado en procesador de 32 bits y CAN bus Breve descripción funcional de la programación que transmite la información desde los módulos slaves hasta el panel SCADA. Dicho de manera sencilla, el módulo cero (en el ámbito del CAN bus), denominado master, es el intermediario entre los slaves y el panel SCADA, ya que su labor (aparte de la ya vista) es transmitir al software de el estado de la planta y enviar a su vez a la planta, las órdenes de control, por medio del bus CAN. En las siguientes líneas, con el apoyo habitual de los diagramas de flujo, se mostrarán cuáles son los pasos para conseguir desarrollar estas funciones. Figura 73) Proceso para recibir datos de módulos Inicialmente, el panel SCADA ha debido programar previamente las tablas: ModuloX_IA y ModuloX_ID (la X puede tomar valores de 1, 2, 3). Más tarde se verá cual es el uso de estas tablas o arrays, cuyo contenido es: el pin y el estado que este presenta, es decir: Modulo1_ID [ ] = {15, 1, 17, 0}; esto significa que el pin numero 15 esta a uno y el pin 17 a 0. Partiendo de que estos arrays han sido creados, el primer paso es comprobar si existe dato para leer, en caso de ser así se lee y se comprueba a partir de su identificador si este dato interesa o no. Interesará todo dato que presente un identificador del tipo (1011XX o 2011XX o 3011XX) es decir, toda trama de tipo informativa. Esta trama presenta las siguientes estructuras. FILTRO PIN ESTADO Figura 74) Trama informativa del estado de un pin digital Memoria. 110 Controlador modular programable basado en procesador de 32 bits y CAN bus FILTRO PIN MILES CENTENAS DECENAS UNIDADES Figura 75) Trama informativa del estado de un pin analógico Si los dos primeros bits del filtro son 00, es un dato digital, si por el contrario es 01, se trata de un dato analógico. Una vez que se sabe el tipo de dato que es, se actualizan los arrays nombrados al principio. El objetivo de estos arrays es el siguiente: el master recibe la información de los distintos módulos, esa información la desgrana y con ella se actualiza el estado (Modulo1_ID [ ] = {15, 1, 17, 0} ) del array, este array será utilizado para enviar el estado de estos pines a través del puerto USB al panel SCADA. Líneas de programación. // ZONA DESTINADA UNICAMENTE AL BUS CAN // -----------------------------------------------------------// Labores de intercambio con el CAN // -----------------------------------------------------------byte dato0; byte dato1; byte dato2; byte dato3; byte dato4; byte dato5; byte dato6; int analogico; int tipo; if (isCAN1MsgReceived == false){ goto PROGRAMA; } rxCAN1(DatosMsg); DatosMsg[0] = dato0; //leo el dato que me ha llegado DatosMsg[1] = dato1; DatosMsg[2] = dato2; DatosMsg[3] = dato3; DatosMsg[4] = dato4; DatosMsg[5] = dato5; Memoria. 111 Controlador modular programable basado en procesador de 32 bits y CAN bus tipo = dato0 & 100000L; tipo = tipo >> 5; if (dato0 == FILTROINFORMATIVO_ESTADO_M3A || dato0 FILTROINFORMATIVO_ESTADO_M2A || dato0 == FILTROINFORMATIVO_ESTADO_M1A //Filtro el mensaje para saber si es un dato que tengo que recoger == ){ //Nos ha llegado un dato analógico analogico = dato2 * 1000 + dato3 * 100 + dato4 * 10 + dato5; switch (tipo){ case 1: tamano = 0; tamano = sizeof(MODULO1_IA)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO1_IA[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO1_IA[punteroCAN] = analogico; } punteroCAN = punteroCAN +1; } break; case 2: tamano = 0; tamano = sizeof(MODULO1_IA)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO2_IA[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO2_IA[punteroCAN] = analogico; } punteroCAN = punteroCAN +1; } break; case 3: Memoria. 112 Controlador modular programable basado en procesador de 32 bits y CAN bus tamano = 0; tamano = sizeof(MODULO3_IA)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO3_IA[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO3_IA[punteroCAN] = analogico; } punteroCAN = punteroCAN +1; } break; break; } } if (dato0 == FILTROINFORMATIVO_ESTADO_M3D || dato0 FILTROINFORMATIVO_ESTADO_M2D || dato0 == FILTROINFORMATIVO_ESTADO_M1D //Nos ha llegado un dato digital == ){ switch (tipo){ case 1: tamano = 0; tamano = sizeof(MODULO1_ID)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO1_ID[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO1_ID[punteroCAN] = dato2; } punteroCAN = punteroCAN +1; } break; case 2: tamano = 0; tamano = sizeof(MODULO1_ID)/4; punteroCAN = 0; Memoria. 113 Controlador modular programable basado en procesador de 32 bits y CAN bus while (punteroCAN <= tamano){ if (MODULO2_ID[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO2_ID[punteroCAN] = dato2; } punteroCAN = punteroCAN +1; } break; case 3: tamano = 0; tamano = sizeof(MODULO1_ID)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO3_ID[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO3_ID[punteroCAN] = dato2; } punteroCAN = punteroCAN +1; } break; } } analogico = 0; Descripción de la programación que transmite la información desde el SCADA hacia los módulos slaves. Como ya se ha dicho desde el punto de vista del CANbus el módulo cero es un intermediario entre los slaves y el panel SCADA. Por lo tanto, la forma de transmitir la información entre el SCADA y los slaves es la siguiente: el SCADA transmite a través del puerto USB la información al módulo cero y este inmediatamente se la transmite al slave correspondiente a través de una trama informativa en la que manda el pin y el valor analógico (comprendido entre 0 y 255, por lo tanto únicamente se requiere de un byte para enviar esta información). FILTRO PIN ESTADO Figura 76) Trama de envio de controles a los módulos slaves. Memoria. 114 Controlador modular programable basado en procesador de 32 bits y CAN bus Líneas de programación. //Declaro variables para controles. unsigned int dato; // variable con la que voy desapilando el buffer. int num_led; //Me indica el LED a encender en los controles int brillo; //Me indica el brillo que le quiero dar al LED en los controles analogicos int estado; // Me indica el estado de los controles digitales //Declaro variables para indicadores int punteroindicadoresdig; int datoindic; // Dato que le mando a VB para informarle de 7 en 7 del estado de los indicadores int datoindic2; // Dato que le mando a VB para informarle de 7 en 7 del estado de los indicadores int datoindic3; int datoindic4; int datoindic5; int datoindic6; int datoindic7; int datoindic8; int datoindic9; int datoindic10; int checksum; //Dato con el que comparo a ver si puedo comenzar a enviar el estado de los indicadores datoindic =0; checksum = 0; datoindic2 = 0; datoindic3 = 0; datoindic4 = 0; datoindic5 = 0; datoindic6 = 0; datoindic7 = 0; datoindic8 = 0; datoindic9 = 0; datoindic10 = 0; Memoria. 115 Controlador modular programable basado en procesador de 32 bits y CAN bus int punteroindicadoresanalog; int checksumanalog; checksumanalog = 0; //MAPA DE MEMORIA int zonas_controles_digitales[80]; //ZONA EN LA QUE ESTA EL ESTADO DE LOS CONTROLES DIGITALES, ORDENADOS POR PINES. EJ 46 VALOR, ESTADO DEL PIN 46 int zonas_controles_analogicos[11]; //ZONA EN LA QUE ESTA EL ESTADO DE LOS CONTROLES ANALOGICOS, SE ORDENAN DE LA MISMA MANERA QUE EN EL ANTERIOR int zonas_indicadores_digitales[80]; //ZONA EN LA QUE SE ENCUENTRA EL ESTADO DE LOS INDICADORES DIGITALES, ORDENADOS POR LOS PINES INDICADOS EN LA VARIABLE ARRAY. EL PRIMER VALOR int i=0; // SERA EL ESTADO DEL PIN 33. for(i=0; i<80; i++){ zonas_indicadores_digitales[i]=0; } int zonas_indicadores_analogicos[16]; DE LOS INDICADORES ANALOGICOS //ZONA EN LA QUE SE ENCUENTRA EL ESTADO //Zona en la que se va a leer el buffer de entrada, para poder actualizar los controles. if(Serial.available()) { while (Serial.available()>0){ dato = Serial.read(); //Modulo 0 //read Serial if (dato == 0){ dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; //delay(1000); dato = Serial.read(); //read Serial brillo = dato; analogWrite(num_led,brillo); zonas_controles_analogicos[num_led] = brillo; } Memoria. 116 Controlador modular programable basado en procesador de 32 bits y CAN bus else{ num_led = (dato & 0x7E) >>1; //delay(1000); estado = (dato & 0x80) >> 7; digitalWrite(num_led,estado); zonas_controles_digitales[num_led] = estado; } } if (dato == 1){ modulo 1 //Envia por bus can los datos al lcd.setCursor(0, 1); lcd.print("MODULO 1"); dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; dato = Serial.read(); //read Serial brillo = dato; txCAN1(FILTROINFORMATIVO_CONTROL_M1A, num_led,brillo,0); } else{ num_led = (dato & 0x7E) >>1; estado = (dato & 0x80) >> 7; txCAN1(FILTROINFORMATIVO_CONTROL_M1D, num_led,estado,0); } } if (dato == 2){ modulo 2 //Envia por bus can los datos al lcd.setCursor(0, 1); lcd.print("MODULO 2"); dato = Serial.read(); //read Serial Memoria. 117 Controlador modular programable basado en procesador de 32 bits y CAN bus if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; dato = Serial.read(); //read Serial brillo = dato; txCAN1(FILTROINFORMATIVO_CONTROL_M2A, num_led,brillo,0); } else{ num_led = (dato & 0x7E) >>1; estado = (dato & 0x80) >> 7; txCAN1(FILTROINFORMATIVO_CONTROL_M2D, num_led,estado,0); } } if (dato == 3){ modulo 3 //Envia por bus can los datos al lcd.setCursor(0, 1); lcd.print("MODULO 3"); dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; dato = Serial.read(); //read Serial brillo = dato; txCAN1(FILTROINFORMATIVO_CONTROL_M3A, num_led,brillo,0); } else{ num_led = (dato & 0x7E) >>1; estado = (dato & 0x80) >> 7; txCAN1(FILTROINFORMATIVO_CONTROL_M3D, num_led,estado,0); } } } } Memoria. 118 Controlador modular programable basado en procesador de 32 bits y CAN bus Descripción de la programación con la que los slaves se configuran. Ya se ha estudiado la forma en la que se envían las tramas de configuración desde el master hasta los slaves. Ahora se expondrá los pasos que permiten al slave recibir esa información y procesarla para configurarse. De nuevo se puede ver que el proceso de recepción de datos es muy idéntico al ya visto para la transmisión slave-­‐master, con la excepción en este caso que una vez descodifica si se trta de una dato de tipo analógico o digital, lo siguiente que hace es configurar ese pin como entrada y además actualizar la tabla Modulo_IA que le servirá al slave para saber que pines debe leer continuamente con el objetivo de reportar esa información al master. Destacar que el slave tomará su valor de módulo (y esto afecta directamente a los datos que le interesan), en función del estado que presenten los switches de su placa principal. Es decir, si sus switches están dispuestos de tal manera que el microprocesador lee un tres, deberá captar aquellos datos cuyo identificador presenta un 03XX. Así mismo es importante tener presente que las líneas de código que aparecen a continuación ya no son generadas por la aplicación SCADA, sino que están generadas previamente por el desarrollador y precargadas en los distintos módulos de la red CAN. Es decir, existen dos tipos de programas, los primeros, generados por el panel SCADA y cargados a través del puerto USB al Memoria. 119 Controlador modular programable basado en procesador de 32 bits y CAN bus módulo cero y los segundos, que ya viene precargado en cada uno de los módulos slaves. Además, en este segundo programa, se destina un espacio para dar la posibilidad al usuario de programar su propio algoritmo de control, que correra únicamente en el módulo que lo haya programado. De darse esta situación, se estaría configurando una red descentralizada de módulos de entrada/salida inteligentes. Programación que permite al slave saber cual es su módulo. int valor_analogico; byte dato; byte datomodulo1; pinMode(11,INPUT); // A estos pines estan conectados los switches pinMode(12,INPUT); pinMode(83,INPUT); pinMode(84,INPUT); pinMode(85,INPUT); dato = digitalRead(11); datomodulo1 = dato << 4; dato = digitalRead(12); datomodulo1 = (dato << 3)+ datomodulo1; dato = 0; dato = digitalRead(83); datomodulo1 = (dato << 2) + datomodulo1; dato = 0; dato = digitalRead(84); datomodulo1 = (dato << 1)+ datomodulo1; dato = 0; dato = digitalRead(85); datomodulo1 = dato + datomodulo1; dato = 0; switch (dato){ case 1: Memoria. 120 Controlador modular programable basado en procesador de 32 bits y CAN bus //FILTROS #define FILTROCONFIGURA_M1D 0x0100L; //Filtro para configurarme #define FILTROCONFIGURA_M1A 0x0101L; //Filtro para configurarme #define FILTROINFORMATIVO_FC_M1 0x0111L; //Filtro con el indica el modulo 0 que ya no me va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x1011L; //Filtro modulo 0 para decirle que ya estoy configurado configurado que que me mando al #define FILTROINFORMATIVOESTADOM1D un pin digital al modulo 0 0x1011L; //Mando el estado de #define FILTROINFORMATIVOESTADOM1A un pin analogico al modulo 0 0x1011L; //Mando el estado de #define FILTROINFORMATIVO_CONTROL_M1A 0x011101L; manda como quiere que ponga un pin analogico #define FILTROINFORMATIVO_CONTROL_M1D manda como quiere que ponga un pin digital 0x011100L; //El modulo 0 me //El modulo 0 me break; case 2: //FILTROS #define FILTROCONFIGURA_M1D 0x0200L; //Filtro para configurarme #define FILTROCONFIGURA_M1A 0x0201L; //Filtro para configurarme #define FILTROINFORMATIVO_FC_M1 0x0211L; //Filtro con el indica el modulo 0 que ya no me va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x2011L; //Filtro modulo 0 para decirle que ya estoy configurado configurado que que me mando al #define FILTROINFORMATIVO_ESTADO_M1D de un pin digital al modulo 0 0x201100L; //Mando el estado #define FILTROINFORMATIVO_ESTADO_M1A de un pin analogico al modulo 0 0x201101L; //Mando el estado #define FILTROINFORMATIVO_CONTROL_M1A 0x021101L; manda como quiere que ponga un pin analogico #define FILTROINFORMATIVO_CONTROL_M1D manda como quiere que ponga un pin digital 0x021100L; //El modulo 0 me //El modulo 0 me break; Memoria. 121 Controlador modular programable basado en procesador de 32 bits y CAN bus case 3: //FILTROS #define FILTROCONFIGURA_M1D 0x0300L; //Filtro para configurarme #define FILTROCONFIGURA_M1A 0x0301L; //Filtro para configurarme #define FILTROINFORMATIVO_FC_M1 0x0311L; //Filtro con el indica el modulo 0 que ya no me va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x3011L; //Filtro modulo 0 para decirle que ya estoy configurado configurado que que me mando al #define FILTROINFORMATIVO_ESTADO_M1D de un pin digital al modulo 0 0x301100L; //Mando el estado #define FILTROINFORMATIVO_ESTADO_M1A de un pin analogico al modulo 0 0x301101L; //Mando el estado #define FILTROINFORMATIVO_CONTROL_M1A 0x031101L; manda como quiere que ponga un pin analogico #define FILTROINFORMATIVO_CONTROL_M1D manda como quiere que ponga un pin digital 0x031100L; //El modulo 0 me //El modulo 0 me break; } Programación que le permite al slave configurarse. // Instalar las rutinas de servicio de interrupción. canMod1.attachInterrupt (doCan1Interrupt); ESPERA1: if (isCAN1MsgReceived == false){ // CAN1 no recibio ningún mensaje para salir de la función, nos mantenemos a la espera goto ESPERA1; } rxCAN1(DatosMsg); dato0 = DatosMsg[0]; // almaceno del dato dato1 = DatosMsg[1]; dato2 = DatosMsg[2]; dato3 = DatosMsg[3]; if (dato0 == 0x01){ // El dato que acaba de llegar me interesa LA VARIABLE A MODIFICAR PARA CADA MODULO!!!! Memoria. ¡¡¡¡¡ESTA ES 122 Controlador modular programable basado en procesador de 32 bits y CAN bus if (dato2 == 0xFF){ se lo remite al modulo0 // Si le llega ese dato es que ya se ha configurado y goto CONFIGURADO; } else{ pinMode(dato1,INPUT); switch(dato2){ case 0: MODULO_ID[punteroID] = dato1; punteroID = punteroID +1; break; case 1: MODULO_IA[punteroIA] = dato1; punteroIA = punteroIA +1; break; } goto ESPERA1; // No ha terminado de configurarse así que debe de leer otra vez } } CONFIGURADO: txCAN1(modulo0, 0xFF,0xFF,modulo1,0x00,0x00,0x00); // YA ESTA CONFIGURADO Y PUEDE COMENZAR A TRABAJAR EN EL LOOP Ahora se expone como reporta la información al master para que se vea monitorizada en el panel SCADA. // Leo entradas digitales y le remito su estado al modulo0 // En primer lugar obtengo el tamaño de MODULO_ID byte valor_analogico; tamano = sizeof(MODULO_ID)/4; punteroID = 0; dato0 = 0; dato1 = 0; dato2 = 0; while (punteroID <= tamano){ // recorro MODULO_ID leyendo el dato de cada uno de los pines y remitiendoselo a modulo0 dato2=digitalRead (MODULO_ID[punteroID]); modulo0 = FILTROINFORMATIVOESTADOM1A; txCAN1(modulo0, MODULO_ID[punteroID],0x00,0x00,0x00,0x00,0x00); Memoria. 123 Controlador modular programable basado en procesador de 32 bits y CAN bus punteroID = punteroID +1; } tamano = sizeof(MODULO_IA)/4; punteroIA = 0; while (punteroIA <= tamano){ // recorro MODULO_IA leyendo el dato de cada uno de los pines y remitiendoselo a modulo0 valor_analogico = analogRead (MODULO_IA[punteroIA]); modulo0 = FILTROINFORMATIVOESTADOM1A; txCAN1(modulo0, MODULO_IA[punteroIA], miles, centenas, decenas, unidades,0x00); punteroIA = punteroIA +1; } Memoria. 124 Controlador modular programable basado en procesador de 32 bits y CAN bus Descripción de las funciones de utilidad CAN, a través de las cuales se puede mandar datos y recibirlos. // -----------------------------------------------------------// Funciones de utilidad CAN // ------------------------------------------------------------ // Descripción: // Inicializa el controlador CAN. void initCan1(uint32_t myaddr) { CAN::BIT_CONFIG canBitConfig; // Paso 1: Activa los switch del modulo CAN y configuración. los switch de modo de // Espera a que este completo. canMod1.enableModule(true); canMod1.setOperatingMode(CAN::CONFIGURATION); while(canMod1.getOperatingMode() != CAN::CONFIGURATION); /* Paso 2: Configura el reloj del modulo CAN. La función CAN::BIT_CONFIG la estructura de datos se utiliza * para este propósito. La propagación, la fase del segmento 1 y segmento 2 están configuradas con 3TQ. * La función CANSetSpeed(), establece la velocidad en baudios.*/ canBitConfig.phaseSeg2Tq = CAN::BIT_3TQ; canBitConfig.phaseSeg1Tq = CAN::BIT_3TQ; canBitConfig.propagationSegTq = CAN::BIT_3TQ; canBitConfig.phaseSeg2TimeSelect = CAN::TRUE; canBitConfig.sample3Time = CAN::TRUE; canBitConfig.syncJumpWidth = CAN::BIT_2TQ; canMod1.setSpeed(&canBitConfig,SYS_FREQ,CAN_BUS_SPEED); /* Paso 3: Asignación del área del buffer al modulo CAN.*/ /* Nota tenga en cuenta el área de cada canal. ** Se trata de 2 (Canales) * 8 (Buffer de mensaje) * 16 (bytes/por buffer de mensaje) bytes. Cada modulo ** CAN debe tener un mensaje propio. */ Memoria. 125 Controlador modular programable basado en procesador de 32 bits y CAN bus canMod1.assignMemoryBuffer(CAN1MessageFifoArea,2 * 8 * 16); /* Paso 4: Configuración del canal 0 para mensajes con prioridad baja media. TX y tamaño de 8 buffer de * Configurar el canal 1 para RX y el tamaño de los 8 buffer de mensaje y recibir el mensaje completo. */ canMod1.configureChannelForTx(CAN::CHANNEL0,8,CAN::TX_RTR_DISABLED,CAN::LOW_ME DIUM_PRIORITY); canMod1.configureChannelForRx(CAN::CHANNEL1,8,CAN::RX_FULL_RECEIVE); // Paso 5 : Configurar filtros y mascaras. Configurar el filtro 0, mensajes a aceptar SID con ID= 0x100, // ID=0x110, ID=0x120, … // Configurar la mascara del filtro 0 y comparar todos los bits del ID y para filtrar el tipo de identificador se // hace en la especificación de la configuración del filtro. Los mensajes aceptados por el filtro son // almacenados en el canal 1. canMod1.configureFilter */ (CAN::FILTER0, myaddr, CAN::SID); canMod1.configureFilterMask CAN::FILTER_MASK_IDE_TYPE); (CAN::FILTER_MASK0, 0xFFF, CAN::SID, canMod1.linkFilterToChannel CAN::CHANNEL1); (CAN::FILTER0, CAN::FILTER_MASK0, canMod1.enableFilter (CAN::FILTER0, true); /* Paso 6: Habilitación interrupciones y eventos. Enable the receive channel not empty event (channel * event ) and the receive channel event (module event). * The interrrupt peripheral library is used to enable the CPU. */ the CAN interrupt to canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); canMod1.enableModuleEvent(CAN::RX_EVENT, true); /* Paso 7: Cambiar el modo de CAN a modo normal. */ canMod1.setOperatingMode(CAN::NORMAL_OPERATION); while(canMod1.getOperatingMode() != CAN::NORMAL_OPERATION); } Memoria. 126 Controlador modular programable basado en procesador de 32 bits y CAN bus /*** txCAN1remota ** ** Descripción: ** Inicializa un buffer de paquetes con la cabecera y carga el paquete. La carga útil no es ninguna por ** en la trama remota es para ver si el nodo esta activo o no (solamente ID, RTR=1, y sin datos)*/ void txCAN1remota(uint32_t rxnode, uint8_t dato) metido el bit que quiero que // en la variable piso va // se ponga a 1 cuando pulsas el piso correspondiente // cada vez.. { CAN::TxMessageBuffer * message; message = canMod1.getTxMessageBuffer(CAN::CHANNEL0); CHANNEL0 por que es el que /*Se coge del /* IMPORTANTE lo que envía cuando se * pulsa hay que meterlo en el CHANEL0 */ if (message != NULL) { // limpiar el buffer message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID que lo recibe, es decir = rxnode; //recepción del nodo (rxnode es el nodo message->msgEID.IDE extendida = 1 = 0; //BIT IDE = trama estándar = 0, trama message->msgEID.RTR = 1; //RTR a recesivo por ser trama remota message->msgEID.DLC = 0; // BIT DLC = longitud de los datos // a quien se lo envió) Memoria. 127 Controlador modular programable basado en procesador de 32 bits y CAN bus //message->data[0] envía nada = 0x00; //message->data[1] = 0x00; //message->data[2] = 0x00; //message->data[3] = 0x00; //message->data[4] = 0x00; //message->data[5] = 0x00; //message->data[6] = 0x00; //message->data[7] = 0x00; // datos, la trama remota no /* Esta función permite que el modulo CAN pueda saber como va el proceso del mensaje y cuando el * mensaje esta listo para ser procesado. */ canMod1.updateChannel(CAN::CHANNEL0); /* Modulo CAN directo para limpiar el canal TX . Esto envía algún mensaje pendiente en el canal TX . */ canMod1.flushTxChannel(CAN::CHANNEL0); } } Memoria. 128 Controlador modular programable basado en procesador de 32 bits y CAN bus /* ------------------------------------------------------------ */ /*** txCAN1 ** ** Descripción: ** Inicializa un buffer de paquetes con la cabecera y carga el paquete. La carga útil en este caso es solo un ** carácter ASCII (0x31 = '1'). Transmite el paquete.*/ void txCAN1(uint32_t rxnode, uint8_t dato0, uint8_t dato1, uint8_t dato2) // en la variable piso va metido el bit que quiero que se ponga a // 1 cuando pulsas el piso correspondiente cada vez. { CAN::TxMessageBuffer * message; message = canMod1.getTxMessageBuffer(CAN::CHANNEL0); CHANNEL0 por que es el que /*Se coge del * hemos configurado para transmitir /* IMPORTANTE lo que envía cuando se * pulsa hay que meterlo en el CHANEL0 */ if (message != NULL) { // limpiar el buffer message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID = rxnode; nodo que lo recibe, es decir // recepción del nodo (rxnode es el // a quien se lo envió) message->msgEID.IDE extendida = 1 = 0; //BIT IDE = trama estándar = 0, trama message->msgEID.RTR = 0; // RTR a dominante message->msgEID.DLC por dato = 3; // BIT DLC = numero de bytes a mandar message->data[0] = dato0; quiero enviar en este caso seria : message->data[1] // dato un solo byte lo que = dato1; Memoria. 129 Controlador modular programable basado en procesador de 32 bits y CAN bus message->data[2] = dato2; //message->data[3] = dato3; //message->data[4] = 0x00; //message->data[5] = 0x00; //message->data[6] = 0x00; //message->data[7] = 0x00; /* Esta función permite que el modulo CAN pueda saber como va el proceso del mensaje y cuando el * mensaje esta listo para ser procesado. */ canMod1.updateChannel(CAN::CHANNEL0); /* Modulo CAN directo para limpiar el canal TX . Esto envía algún mensaje pendiente en el canal TX . */ canMod1.flushTxChannel(CAN::CHANNEL0); } } Memoria. 130 Controlador modular programable basado en procesador de 32 bits y CAN bus //----------------------------------------------------------------------------------------------------------------------------------//** rxCAN1remota ** ** Descripción: //Comprueba si el nodo esta activo o no. Si esta activo imprime un mensaje indicando que esta correcto ** y sino es así imprime mensaje indicando de que es incorrecto por el monitor serie.*/ void rxCAN1remota(void) { CAN::RxMessageBuffer * message; if (isCAN1MsgReceived == false){ return; } //compruebo que si que ha llegado mensaje // si no ha llegado mensaje pongo NODO INACTIVO /* Mensaje ha sido recibido. Resetear los flags de isCAN1MsgReceived para recibir el siguiente mensaje. */ isCAN1MsgReceived = false; message = canMod1.getRxMessage(CAN::CHANNEL1); /* Llamar a la función CAN::updateChannel() para que el modulo CAN pueda saberlo que se hace en el * proceso del mensaje. Habilitar el evento para que cuando el modulo CAN genere una interrupción cuando * ocurre el evento.*/ canMod1.updateChannel(CAN::CHANNEL1); canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); } Memoria. 131 Controlador modular programable basado en procesador de 32 bits y CAN bus /* ----------------------------------------------------------------------------------------------------------------------------------------------- * / /*** rxCAN1 ** ** Descripción: ** Comprueba si el paquete ha sido recibido. Si es así leer el paquete recibido e imprimir la carga del ** paquete por el monitor seria.*/ void rxCAN1(byte DatosMsg[ ]) { CAN::RxMessageBuffer * message; if (isCAN1MsgReceived == false) { /* CAN1 no recibió ningún mensaje para salir de la función. Saltamos a ERRORCAN*/ //Seguridad_mal=1; DatosMsg[0]= 0; DatosMsg[1]= 0; return ; } /* Mensaje ha sido recibido. Resetear los flags de isCAN1MsgReceived para recibir el siguiente mensaje. */ isCAN1MsgReceived = false; message = canMod1.getRxMessage(CAN::CHANNEL1); /* Imprime el primer byte del área del paquete cargado como un carácter ASCII por el monitor serie. */ Serial.print( DatosMsg [0]); /* Llamar a la función CAN::updateChannel() para que el modulo CAN pueda saberlo que se hace en el * proceso del mensaje. Habilitar el evento para que cuando el modulo CAN genere una interrupción cuando * ocurre el evento.*/ canMod1.updateChannel(CAN::CHANNEL1); canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); DatosMsg[0]= (message->data[0]); DatosMsg[1]= (message->data[1]); DatosMsg[2]= (message->data[2]); DatosMsg[3]= (message->data[3]); DatosMsg[4]= (message->data[4]); DatosMsg[5]= (message->data[5]); DatosMsg[6]= (message->data[6]); DatosMsg[7]= (message->data[7]); return ; } Memoria. 132 Controlador modular programable basado en procesador de 32 bits y CAN bus /* --------------------------------------------------------------------------*/ /* Manejador de las funciones de interrupción */ /* --------------------------------------------------------------------------*/ /*** doCan1Interrupt ** ** Descripción: ** Rutina de servicio de interrupción para manejar el nivel de los eventos de interrupción para el modulo ** CAN1.*/ void doCan1Interrupt() { /* Este es el controlador de las interrupciones CAN1. Esto no es la rutina actual de interrupción, sino que es * el manejador de interrupciones de usuario instalado por CAN::attachInterrupt. Esto es llamado por el ISR. * Ten en cuenta que hay muchos eventos en el modulo CAN1 que pueden causar esta interrupción. Estos * eventos son activados por la función CAN::enableModuleEvent() . * En este ejemplo solo CAN::RX_EVENT esta habilitado. */ /* Comprobar si el origen de la interrupción es la función CAN::RX_EVENT. * Esto es redundante ya que solo este evento esta habilitado en este ejemplo, pero esto muestra un * esquema para la manipulación de las interrupciones. */ if ((canMod1.getModuleEvent() & CAN::RX_EVENT) != 0) { /* En este marco, se pueden comprobar los hechos que ocasionaron la interrupción con la función * CAN::getPendingEventCode() para obtener alta prioridad del evento activo.*/ if(canMod1.getPendingEventCode() == CAN::CHANNEL1_EVENT) { /* Esto significa que el canal 1 ha causado un evento. * El CAN::RX_CHANNEL_NOT_EMPTY es un evento persistente. Tu puedes leer el canal en el ISR para Memoria. 133 Controlador modular programable basado en procesador de 32 bits y CAN bus * borrar la condición establecer una bandera para del evento o deshabilitar el origen del evento y * indicar que un mensaje se ha recibido. El evento puede ser habilitado por la aplicación cuando se ha * procesado un mensaje. * Ten en cuenta que la salida del evento habilitado podría causar que la CPU mantenga la ejecución de la * ISR ya que CAN::RX_CHANNEL_NOT_EMPTY es un evento persistente. (a menos que la condición no * este vacía, se borra.) */ canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, false); isCAN1MsgReceived = true; } } /* La bandera de interrupción del CAN1 se limpia por la rutina de servicio de la interrupción después lo * devuelve la función. Esto sucederá porque la causa del evento de la interrupción * (CAN::RX_CHANNEL_NOT_EMPTY) esta deshabilitado . * El intento del ISR's de borrar el flag de interrupción seria un error en el caso de que * CAN::RX_CHANNEL_NOT_EMPTY este habilitado, porque el evento todavía esta presente. En este caso * otra interrupción podría ocurrir inmediatamente */ } Memoria. 134 Controlador modular programable basado en procesador de 32 bits y CAN bus 9. Posibles vías de ampliación. Como se ha dicho al principio del presente documento se pretende obtener una aplicación software de código abierto, para el desarrollo de aplicaciones de control y monitorización industrial, como alternativa abierta de bajo coste. Por ello, se contempla como una línea de ampliación imprescindible adaptar este software a otros sistemas operativos. Sería interesante desarrollar esta aplicación para Linux, de esta manera se conseguería una solución full open. Además, esta línea de desarrollo es totalmente viable, ya que existe un software, KBasic, de código abierto que trabaja en Linux y OS X Lion. Debido a que KBasic ha mantenido la similitud con visual basic en la mayoría de los aspectos, no sería muy costoso en tiempo, hacer el cambio. Visto esto puede parecer que haya sido un error desarrollar la aplicación para Windows, sin embargo, el SO Windows es el que mayor número de usuarios presenta y esta es la razón principal de porque ha sido desarrollado en esta plataforma. Memoria. 135 Controlador modular programable basado en procesador de 32 bits y CAN bus Logroño, a 3 de Septiembre de 2013. Fdo: Alberto Martínez Inchusta. Memoria. 136 Anexos Índice de Anexos. 1. Anexo 1. Características técnicas de los componentes electrónicos usados en el hardware de las placas. .................................................................................................................... 1 1.1. ADG 5412. ................................................................................................................................. 1 1.2. Amplificador LM358. ........................................................................................................... 3 1.3. Amplificador MC7915. ........................................................................................................ 5 1.4. Amplificador LM7815. ........................................................................................................ 6 1.5. Convertidor RCV 420. .......................................................................................................... 7 1.6. Optoacoplador 4N25. .......................................................................................................... 8 1.7. Zener 1N4733A. ..................................................................................................................... 9 1.8. Driver FOD 8321. ............................................................................................................... 10 1.9. Optotriac MOC 3021. ........................................................................................................ 12 2. Anexo 2. Hardware y software del CAN bus. .................................................................. 14 2.1. chipKIT MAX32. .................................................................................................................. 16 2.2. Transceiver MCP2551. ..................................................................................................... 16 2.3. Código del módulo 0. ........................................................................................................ 17 2.4. Código del resto de módulos. ........................................................................................ 56 3. Anexo 3. Código de la aplicación SCADA. ......................................................................... 73 4. Anexo 4. Contenido del cd adjunto. .................................................................................... 74 Nota. Los anexos que aparecerán a continuación contienen características técnicas de todos los componentes electrónicos. Las características técnicas aquí expuestas, son aquellas que se han considerado más importantes. Si se desea aumentar esta información consúltese la carpeta “Datasheets del hardware” incluida en el CD adjunto. Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1. Anexo 1. Características técnicas de los componentes electrónicos usados en el hardware de las placas. 1.1. ADG 5412. El ADG5412/ADG5413 contiene cuatro interruptores independientes single-­‐pole/single-­‐throw (SPST). Los conmutadores ADG5412 se activan con lógica positiva, mientras que el ADG5413 presenta dos interruptores con lógica positiva y otros dos con lógica negativa, ideal para este proyecto. Cada switch puede trabajar en ambas direcciones cuando está encendido, y cada interruptor tiene un rango de señal de entrada que se extiende a la salida. En el estado de apagado, no llega ninguna tensión a la otra parte.. Diagrama de bloques funcionales. Figura 1) Figura explicativa de cómo trabaja el ADG 5412. Anexos 1 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Valores máximos. Figura 2) Valores máximo Anexos 2 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Configuración de los pines. 1.2. Amplificador LM358. Amplificador operacional doble, que permite trabajar desde rangos tan bajos como 3 voltios hasta 32 voltios. Este tipo de componentes pueden trabajar con los populares MC1558 entre otros o con el MC7915 como en el presente proyecto. Distribución de los pines. Figura 3) Distribución de pines Anexos 3 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Tipos de encapsulados que presenta. Figura 4) Tipos de encapsulados Valores máximos. Figura 5) Máximos rangos en los que puede trabajar. Anexos 4 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1.3. Amplificador MC7915. Regulador de tensión utilizado para adecuar voltajes. En el presente proyecto es usado junto al MC7915 para adaptar los 24 y -­‐24 voltios que entran a la placa principal a +/-­‐ 15 voltios, que alimentará a muchos de los módulos. Aplicación de nota, usada en la fuente de alimentación de la placa principal. Figura 6) Conversión de 24 voltios a 15 voltios tanto positivos como negativos. Esquema de sus pines y encapsulados. Figura 7) Encapsulados. Anexos 5 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Valores máximos. 1.4. Amplificador LM7815. Como ya se ha dicho más arriba la funcionalidad de este elemento es idéntica al MC7915. Pines y encapsulado. Figura 8) Configuración de los pines y encapsulados. Valores máximos. Figura 9) Valores máximos. Anexos 6 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1.5. Convertidor RCV 420. Este componente convierte intensidad en tensión, en concreto convierte valores de entrada comprendidos entre los 4 y 20 mA a 0 o 5 voltios a la salida. Distribución de los pines. Figura 10) Distribución de los pines del RCV 420 A continuación se exponen varios datos como son, valores máximos, encapsulados y la configuración de los pines. Figura 11) Datos más destacables del presente componente. Anexos 7 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1.6. Optoacoplador 4N25. El siguiente componente es utilizado en los módulos de entradas digitales con el objetivo de aislar a la placa chipKIT MAX 32, a continuación se van a analizar sus características, ya que junto con el zener es el componente que marca las limitaciones de los módulos ya citados. opto. Diagrama en el que se muestra las diferentes partes que componen el Figura 12) Diagrama en el que se muestran los pines y otro en el que se observa el funcionamiento. Valores máximos. Figura 13) Valores máximos a tener en cuenta. Anexos 8 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1.7. Zener 1N4733A. Pieza clave en los módulos de las entradas digitales ya que trabaja como regulador, consiguiendo de esta manera que si no existe una tensión mayor que 5.1 voltios en los borneros de entradas, no permite que el optoacoplador antes mencionado conduzca y por lo tanto no llega tensión al pin del chipKIT MAX32. Valores máximos a los que puede trabajar. Figura 14) Valores máximos Características eléctricas. Figura 15) Datos importantes para hacer trabajar al zener. Anexos 9 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1.8. Driver FOD 8321. El driver FOD 8321, eleva la tensión que recibe en sus pines de entrada, además aporta hasta 2.5 A y todo esto con grandes tiempos de conmutación. Es por ello, por lo que se denominan módulos de salidas digitales máximas. A continuación se expondrán datos que corroborarán el gran potencial de este driver, que ha sido utilizado también en las salidas analógicas, que como se saben son PWM y por lo tanto si se trabaja con una frecuencia de onda cuadrada muy rápida no se tendría ningún problema. Esquema funcional. Figura 16) Esquema funcional. Configuración de pines. Figura 17) Configuración de pines. Anexos 10 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Valores máximos. Figura 18) Rangos máximos. Aplicación de nota empleada para diseñar las salidas digitales rápidas. Figura 19) Application Note. Anexos 11 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 1.9. Optotriac MOC 3021. Este elemento tiene como misión principal permitir al usuario trabajar también con tensiones alternas. Así mismo requiere del apoyo de un triac, para poder elevar la tensión de trabajo que como se va a exponer a continuación son bastante elevadas. Encapsulado y pines. Figura 20) Tipo de encapsulado y el esquema del componente. Anexos 12 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Máximos valores. Figura 21) Valores máximos.. Anexos 13 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 2. Anexo 2. Hardware y software del CAN bus. CAN (“Controller Area Network), bus serie patentado por la compañía Robert Bosch (1982). Inicialmente se pensó en el como bus de campo, pero donde realmente encontró utilidad fue en el sector del automóvil y la industria, para interconectar el bus de confort, seguridad, etc. El Mercedes Clase E fue el primer coche en incorporar el bus CAN, 10 años después(1992). Fue diseñado para permitir la comunicación fiable entre centralitas electrónicas basadas en microcontrolador, ECUs (“Electronic Control Unit”) y reducir cableado. En Europa se ha convertido en un estándar “de facto”, con carácter internacional y documentado por normas ISO (ISO11898). Ventajas: reducción de costes, mejora flexibilidad. El bus CAN es un protocolo serie asíncrono del tipo CSMA/CD (“Carrier Sense Múltiple Access hit Collision Detection”). El bus es un medio compartido (multiplexado). Se trata de un protocolo “Multicast”, es decir, todo el mundo puede hablar (de uno en uno) y escuchar. “CSMA”: cada nodo de la red debe monitorizar el bus y si detecta que no hay actividad, puede enviar un mensaje. “CD”: si 2 nodos de la red comienzan a transmitir un mensaje, ambos detectan la colisión. Un método de arbitración basado en prioridades resuelve el conflicto. Se utiliza un par de cables trenzados (bus diferencial) para conseguir alta inmunidad a las interferencias electromagnéticas (EMIs). En algunos casos puede ir apantallado. La impedancia característica de esta línea es del orden de 120Ω por lo que se emplean impedancias (resistencias) de este valor para en ambos extremos del bus para evitar ondas reflejadas y que el bus se convierta en una antena. Longitud máxima de 1000m (a 40Kbps). Velocidad máxima de 1Mbps (con una longitud de 40m). En los coches se utiliza a 125kbit/s y a 500kbit/s. Anexos 14 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Capas modelo OSI. Figura 22) Modelo OSI Capa física. La capa física es la responsable de la transferencia de bits entre distintos módulos que componen la red. Definen aspectos como niveles de señal, codificación, sincronización, etc... Las características de las señales eléctricas en el bus fueron establecidas por el Standard ISO 11898. Los módulos conectados al bus interpretan dos niveles lógicos: Dominante: la tensión diferencial (CAN_H = 3,5V – CAN_L = 1,5V) es del orden de 2 voltios. Recesivo: la tensión diferencial (CAN_H = CAN_L = 2,5 V) es del orden de 0 voltios. Otra de las partes a destacar el la velocidad a la que se transmiten los mensajes en la red, en la tabla se muestran las velocidades según las distancias (son orientativos): Anexos 15 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Capa enlace. Una de las características que distingue a CAN de otras normas es su técnica de acceso al medio que se denomina CSMA/CD, técnica de contienda. El acceso al medio por medio de técnicas de acceso múltiple y detección de conflicto evolucionaron y ahora CAN añade la resolución de colisión, CAN resuelve la colisión con la supervivencia de una de las tramas que es la de mayor prioridad. La resolución se hace aplicando una función lógica determinista a cada bit, que se resuelve con la prioridad del nivel definido como bit de tipo dominante y se hace realizando una función AND de todos los bits transmitidos simultáneamente. Cada transmisor escucha continuamente el valor que hay en el bus y se retira cuando dicho valor no coincide con el que dicho transmisor a forzado, si hay coincidencia continúa. Sobrevive el de mayor prioridad. 2.1. chipKIT MAX32. La placa chipKIT MAX32 se encuentra presente en todos los módulos de la red CAN y existe poco más que añadir sobre ella. 2.2. Transceiver MCP2551. chipKIT 32MAX, presenta entre sus funcionalidades la posibilidad de implementar dos CAN bus. Para ello, se encuentra dotada de dos controladores CAN, no así de transceiver. En este caso se empleará el MCP 2551, cuyas principales características son: Bloque de diagramas. Figura 23) Bloque de diagramas. Anexos 16 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Pines. Figura 24) Pines del MCP 2551 Valores máximos. 2.3. Código del módulo 0. // Incluir librerías: #include <WProgram.h> #include "chipKITCAN.h" #include <LiquidCrystal.h> // inicializar la libreria con el numero de pins del interfaz LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // -----------------------------------------------------------------------// Definición de constantes y variables locales // -----------------------------------------------------------------------// Direcciones de red de los nodos Anexos 17 Controlador modular programable basado en procesadores de 32 bits y CAN bus. //FILTROS #define FILTROCONFIGURA_M1D 0x0100L //Filtro para configurar slave1 #define FILTROCONFIGURA_M1A 0x0101L //Filtro para configurar slave1 #define FILTROCONFIGURA_M2D 0x0200L //Filtro para configurar slave2 #define FILTROCONFIGURA_M2A 0x0201L //Filtro para configurar slave2 #define FILTROCONFIGURA_M3D 0x0300L //Filtro para configurar slave3 #define FILTROCONFIGURA_M3A 0x0301L //Filtro para configurar slave3 #define FILTROINFORMATIVO_FC_M1 0x0111L le va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 modulo 0 que ya esta configurado //Filtro indicar al módulo 1 que ya no 0x1011L //Filtro que manda modulo 1 indicando al #define FILTROINFORMATIVO_FC_M2 0x0211L le va a enviar más datos de configuración //Filtro indicar al módulo 2 que ya no #define FILTROINFORMATIVO_ACK_M2 modulo 0 que ya esta configurado 0x2011L //Filtro que manda modulo 2 indicando al #define FILTROINFORMATIVO_FC_M2 0x0311L le va a enviar más datos de configuración //Filtro indicar al módulo 3 que ya no #define FILTROINFORMATIVO_ACK_M3 modulo 0 que ya esta configurado 0x3011L //Filtro que manda modulo 3 indicando al #define FILTROINFORMATIVO_ESTADO_M1D 0x101100L pin digital //El modulo 1 me manda el estado de un #define FILTROINFORMATIVO_ESTADO_M2D 0x201100L pin digital //El modulo 2 me manda el estado de un #define FILTROINFORMATIVO_ESTADO_M3D 0x301100L pin digital //El modulo 3 me manda el estado de un #define FILTROINFORMATIVO_ESTADO_M1A 0x101101L pin analogico //El modulo 1 me manda el estado de un #define FILTROINFORMATIVO_ESTADO_M2A 0x201101L pin analogico //El modulo 2 me manda el estado de un #define FILTROINFORMATIVO_ESTADO_M3A 0x301101L pin analogico //El modulo 3 me manda el estado de un #define FILTROINFORMATIVO_CONTROL_M1A que ponga un pin analogico en el modulo 1 0x011101L //El modulo 0 manda como quiere #define FILTROINFORMATIVO_CONTROL_M2A que ponga un pin analogico en el modulo 2 0x021101L //El modulo 0 manda como quiere #define FILTROINFORMATIVO_CONTROL_M3A que ponga un pin analogico en el modulo 3 0x031101L //El modulo 0 manda como quiere #define FILTROINFORMATIVO_CONTROL_M1D que ponga un pin digital en el modulo 1 0x011100L //El modulo 0 manda como quiere #define FILTROINFORMATIVO_CONTROL_M2D que ponga un pin digital en el modulo 2 0x021100L //El modulo 0 manda como quiere #define FILTROINFORMATIVO_CONTROL_M3D que ponga un pin digital en el modulo 3 0x031100L //El modulo 0 manda como quiere #define modulo1can1 0x110L #define modulo2can1 0x120L Anexos 18 Controlador modular programable basado en procesadores de 32 bits y CAN bus. #define modulo3can1 0x130L #define modulo0can1 0x110L // Definición de la frecuencia y de la velocidad #define SYS_FREQ (80000000L) #define CAN_BUS_SPEED 250000 // velocidad CAN // -----------------------------------------------------------// Variables globales // -----------------------------------------------------------// Interfaz de instancias del nodo controlador CAN CAN canMod1(CAN::CAN1); // este objeto lo usa el modulo CAN1 CAN canMod2(CAN::CAN2); // este objeto lo usa el modulo CAN2 byte DatosMsg[7]; // -----------------------------------------------------------// Variables locales // -----------------------------------------------------------uint8_t REMOTA = 0x0C; // Indico si esta correcto el modulo // Buffer de mensajes CAN uint8_t CAN1MessageFifoArea [2 * 8 * 16]; uint8_t CAN2MessageFifoArea [2 * 8 * 16]; // Flags indicadores de eventos de las rutinas de interrupción. static volatile bool isCAN1MsgReceived = false; static volatile bool isCAN2MsgReceived = false; // -----------------------------------------------------------// Declaraciones directas // -----------------------------------------------------------void initCan1 (uint32_t myaddr); void doCan1Interrupt(); void txCAN1remota(uint32_t rxnode, uint8_t dato); remotas // función para envió de tramas void txCAN1(uint32_t rxnode, uint8_t dato0, uint8_t dato1, uint8_t dato2, uint8_t dato ); void rxCAN1remota(void); // función para recibir las tramas remotas void rxCAN1(void); // -----------------------------------------------------------// Definición de procedimientos // ------------------------------------------------------------ Anexos 19 Controlador modular programable basado en procesadores de 32 bits y CAN bus. void setup(){ lcd.begin(16, 2); lcd.print("PROYECTO"); Serial.begin(9600); // inicializar LCD // Escribir un mensaje en LCD //Puerto serie, configuración // -------------------------Inicializar cada controlador CAN que va a ser usado. (En este caso solo se utiliza el CAN1) // Instalar las rutinas de servicio de interrupción. canMod1.attachInterrupt (doCan1Interrupt); // Inicializar cada controlador CAN que va a ser usado. (En este caso solo se utiliza el CAN1) initCan1 (modulo0can1); //Inicialización de los diferentes nodos initCan1 (modulo1can1); initCan1 (modulo2can1); initCan1 (modulo3can1); // -------------------------Comprobación de que los nodos conectados al bus can están correctos txCAN1remota (modulo0can1, REMOTA); remotas delay(100); rxCAN1remota (); esta función // función para envió de tramas // Espera a que el carácter sea entregado // función para recibir tramas remotas (dentro de // escribe el mensaje si esta activo o no lo esta) txCAN1remota (modulo1can1, REMOTA); remotas delay(100); rxCAN1remota (); esta función // función para envió de tramas // Espera a que el carácter sea entregado // función para recibir tramas remotas (dentro de // escribe el mensaje si esta activo o no lo esta) txCAN1remota (modulo2can1, REMOTA); remotas delay(100); // función para envió de tramas // Espera a que el carácter sea entregado Anexos 20 Controlador modular programable basado en procesadores de 32 bits y CAN bus. rxCAN1remota (); esta función // función para recibir tramas remotas (dentro de // escribe el mensaje si esta activo o no lo esta) txCAN1remota (modulo3can1, REMOTA); remotas // delay(100); función para envió de tramas // Espera a que el carácter sea entregado rxCAN1remota (); esta función // función para recibir tramas remotas (dentro de // escribe el mensaje si esta activo o no lo esta) Serial.print(43,BYTE); // Dice cual es el estado de los modulos al panel SCADA Serial.print(43,BYTE); Serial.print(43,BYTE); // FIN BUS CAN //----------------------------------------------------------------------------------// ZONA DE ENTRADAS Y SALIDAS //------------------------------------------------------------------------------------ pinMode(10,OUTPUT); //Control analogico analogWrite(10,0); pinMode(6,OUTPUT); //Control analogico analogWrite(6,0); pinMode(6,OUTPUT); //Control analogico analogWrite(6,0); pinMode(0,INPUT); //Indicador analogico pinMode(1,INPUT); //Indicador analogico pinMode(1,INPUT); //Indicador analogico pinMode(33,INPUT); //Indicador digital pinMode(35,INPUT); //Indicador digital pinMode(35,INPUT); //Indicador digital pinMode(25,OUTPUT); //Control digital digitalWrite(25,0); pinMode(25,OUTPUT); //Control digital digitalWrite(25,0); pinMode(30,OUTPUT); //Control digital Anexos 21 Controlador modular programable basado en procesadores de 32 bits y CAN bus. digitalWrite(30,0); } void loop(){ unsigned int MODULO1_ID[] = {35,0}; // Array de indicadores digitales del modulo 1 unsigned int PINES_MODULO1_ID[] = {35}; unsigned int MODULO2_ID[] = {}; // Array de indicadores digitales del modulo 2 unsigned int PINES_MODULO2_ID[] = {}; unsigned int MODULO3_ID[] = {}; unsigned int MODULO1_IA[] = {1,0}; // Array de indicadores analogicos del modulo 1 // Array de indicadores analogicos del modulo 2 unsigned int PINES_MODULO2_IA[] = {}; // Array de indicadores analogicos del modulo 2 // Array de indicadores analogicos del modulo 3 unsigned int PINES_MODULO3_IA[] = {}; unsigned int cantidad =3; // Array de indicadores digitales del modulo 3 // Array de indicadores analogicos del modulo 1 unsigned int PINES_MODULO1_IA[] = {1}; unsigned int MODULO3_IA[] = {}; // Array de indicadores digitales del modulo 2 // Array de indicadores digitales del modulo 3 unsigned int PINES_MODULO3_ID[] = {}; unsigned int MODULO2_IA[] = {}; // Array de indicadores digitales del modulo 1 // Array de indicadores analogicos del modulo 3 // Cantidad de indicadores digitales unsigned int cantidadanalog =3; // Cantidad de indicadores analogicos unsigned int pines_digi_entrada[] = {33,0,35,0,35,1}; unsigned int pines_analog_entrada[] = {0,0,1,0,1,1}; // Array de indicadores digitales // Array de indicadores analogicos //-----------------------------------------------------------------------------------------------------------------//ZONA DE COMUNICACIONES. NO REALIZE NINGÚN CAMBIO POR FAVOR. //-----------------------------------------------------------------------------------------------------------------//Declaro variables para BUS CAN boolean CONFIGURADO; boolean CONFIGURADOM1; boolean CONFIGURADOM2; boolean CONFIGURADOM3; int PIN; int MODULO; //-------------------CONFIGURACION DE LOS MODULOS INTEGRADOS EN EL BUS CAN. byte tamano; byte punteroCAN; byte intentos; if (CONFIGURADO == false){ Anexos 22 Controlador modular programable basado en procesadores de 32 bits y CAN bus. otra: punteroCAN = 0; //MODULO 1 tamano = sizeof(PINES_MODULO1_ID)/4; while (punteroCAN <= tamano){ sus pines de entrada digitales //Le indico cuales son txCAN1(FILTROCONFIGURA_M1D,PINES_MODULO1_ID[punteroCAN],0,0); punteroCAN = punteroCAN +1; } tamano = 0; punteroCAN=0; tamano = sizeof(PINES_MODULO1_IA)/4; while (punteroCAN <= tamano){ sus pines de entrada analógicos //Le indico cuales son txCAN1(FILTROCONFIGURA_M1A,PINES_MODULO1_IA[punteroCAN],0,0); punteroCAN = punteroCAN +1; } txCAN1(FILTROINFORMATIVO_FC_M1,0xFF,0x00,0x00); todos los valores para que se configure rxCAN1(DatosMsg); configurado //Le indico que ya le he mandado // Espero a que me confirme que esta if (DatosMsg[0] == FILTROINFORMATIVO_ACK_M1 && DatosMsg[1] == 0xFF ){ CONFIGURADOM1 = true; goto M2; } else { intentos = intentos +1; if (intentos == 3){ goto M2; } else{ goto otra; } } intentos = 0; M2: punteroCAN = 0; //MODULO 2 tamano = sizeof(PINES_MODULO2_ID)/4; while (punteroCAN <= tamano){ sus pines de entrada digitales //Le indico cuales son txCAN1(FILTROCONFIGURA_M2D,PINES_MODULO2_ID[punteroCAN],0,0); punteroCAN = punteroCAN +1; Anexos 23 Controlador modular programable basado en procesadores de 32 bits y CAN bus. } tamano = 0; punteroCAN=0; tamano = sizeof(PINES_MODULO2_IA)/4; while (punteroCAN <= tamano){ sus pines de entrada analógicos //Le indico cuales son txCAN1(FILTROCONFIGURA_M1A,PINES_MODULO2_IA[punteroCAN],0,0); punteroCAN = punteroCAN +1; } txCAN1(FILTROINFORMATIVO_FC_M1,0xFF,0xFF,0xFF); todos los valores para que se configure rxCAN1(DatosMsg); configurado //Le indico que ya le he mandado // Espero a que me confirme que esta if (DatosMsg[0] == FILTROINFORMATIVO_ACK_M2 && DatosMsg[1] == 0xFF){ CONFIGURADOM2 = true; goto M3; } else{ intentos = intentos +1; if (intentos == 10){ goto M3; } else{ lcd.setCursor(0, 1); lcd.print(intentos); goto M2; } } intentos = 0; M3: punteroCAN = 0; //MODULO 3 tamano = sizeof(PINES_MODULO3_ID)/4; while (punteroCAN <= tamano){ sus pines de entrada digitales //Le indico cuales son txCAN1(FILTROCONFIGURA_M3D,PINES_MODULO3_ID[punteroCAN],0,0); punteroCAN = punteroCAN +1; } tamano = 0; punteroCAN=0; Anexos 24 Controlador modular programable basado en procesadores de 32 bits y CAN bus. tamano = sizeof(PINES_MODULO3_IA)/4; while (punteroCAN <= tamano){ sus pines de entrada analógicos //Le indico cuales son txCAN1(FILTROCONFIGURA_M3A,PINES_MODULO3_IA[punteroCAN],0,0); punteroCAN = punteroCAN +1; } txCAN1(FILTROINFORMATIVO_FC_M1,0xFF,0xFF,0xFF); todos los valores para que se configure rxCAN1(DatosMsg); configurado //Le indico que ya le he mandado // Espero a que me confirme que esta if (DatosMsg[0] == FILTROINFORMATIVO_ACK_M3 && DatosMsg[1] == 0xFF){ CONFIGURADOM3 = true; goto M4; } else{ intentos = intentos +1; if (intentos == 15){ goto M4; } else{ lcd.setCursor(0, 1); lcd.print(intentos); goto M3; } } M4: CONFIGURADO == true; //En realidad no se pondría configurado a true hasta que todos los modulos estarían OK! } Anexos 25 Controlador modular programable basado en procesadores de 32 bits y CAN bus. //--------------------------------------------------------------------------------------------------------------------------//Declaro variables para controles. unsigned int dato; // variable con la que voy desapilando el buffer. int num_led; //Me indica el LED a encender en los controles int brillo; analogicos int estado; //Me indica el brillo que le quiero dar al LED en los controles // Me indica el estado de los controles digitales //Declaro variables para indicadores int punteroindicadoresdig; int datoindic; indicadores // Dato que le mando a VB para informarle de 7 en 7 del estado de los int datoindic2; indicadores // Dato que le mando a VB para informarle de 7 en 7 del estado de los int datoindic3; int datoindic4; int datoindic5; int datoindic6; int datoindic7; int datoindic8; int datoindic9; int datoindic10; int checksum; //Dato con el que comparo a ver si puedo comenzar a enviar el estado de los indicadores datoindic =0; checksum = 0; datoindic2 = 0; datoindic3 = 0; datoindic4 = 0; datoindic5 = 0; datoindic6 = 0; datoindic7 = 0; datoindic8 = 0; datoindic9 = 0; datoindic10 = 0; int punteroindicadoresanalog; Anexos 26 Controlador modular programable basado en procesadores de 32 bits y CAN bus. int checksumanalog; checksumanalog = 0; //MAPA DE MEMORIA int zonas_controles_digitales[80]; //ZONA EN LA QUE ESTA EL ESTADO DE LOS CONTROLES DIGITALES, ORDENADOS POR PINES. EJ 46 VALOR, ESTADO DEL PIN 46 int zonas_controles_analogicos[11]; //ZONA EN LA QUE ESTA EL ESTADO DE LOS CONTROLES ANALOGICOS, SE ORDENAN DE LA MISMA MANERA QUE EN EL ANTERIOR int zonas_indicadores_digitales[80]; //ZONA EN LA QUE SE ENCUENTRA EL ESTADO DE LOS INDICADORES DIGITALES, ORDENADOS POR LOS PINES INDICADOS EN LA VARIABLE ARRAY. EL PRIMER VALOR int i=0; // SERA EL ESTADO DEL PIN 33. for(i=0; i<80; i++){ zonas_indicadores_digitales[i]=0; } int zonas_indicadores_analogicos[16]; INDICADORES ANALOGICOS //ZONA EN LA QUE SE ENCUENTRA EL ESTADO DE LOS //Zona en la que se va a enviar la configuración de los pines a cada módulo //Zona en la que se va a leer el buffer de entrada, para poder actualizar los controles. if(Serial.available()) { while (Serial.available()>0){ //Modulo 0 dato = Serial.read(); //read Serial if (dato == 0){ dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; //delay(1000); dato = Serial.read(); //read Serial brillo = dato; analogWrite(num_led,brillo); zonas_controles_analogicos[num_led] = brillo; } else{ num_led = (dato & 0x7E) >>1; Anexos 27 Controlador modular programable basado en procesadores de 32 bits y CAN bus. //delay(1000); estado = (dato & 0x80) >> 7; digitalWrite(num_led,estado); zonas_controles_digitales[num_led] = estado; } } if (dato == 1){ //Envia por bus can los datos al modulo 1 lcd.setCursor(0, 1); lcd.print("MODULO 1"); dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; dato = Serial.read(); //read Serial brillo = dato; txCAN1(FILTROINFORMATIVO_CONTROL_M1A, num_led,brillo,0); } else{ num_led = (dato & 0x7E) >>1; estado = (dato & 0x80) >> 7; txCAN1(FILTROINFORMATIVO_CONTROL_M1D, num_led,estado,0); } } if (dato == 2){ //Envia por bus can los datos al modulo 2 lcd.setCursor(0, 1); lcd.print("MODULO 2"); dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; dato = Serial.read(); //read Serial brillo = dato; txCAN1(FILTROINFORMATIVO_CONTROL_M2A, num_led,brillo,0); } Anexos 28 Controlador modular programable basado en procesadores de 32 bits y CAN bus. else{ num_led = (dato & 0x7E) >>1; estado = (dato & 0x80) >> 7; txCAN1(FILTROINFORMATIVO_CONTROL_M2D, num_led,estado,0); } } if (dato == 3){ //Envia por bus can los datos al modulo 3 lcd.setCursor(0, 1); lcd.print("MODULO 3"); dato = Serial.read(); //read Serial if ((dato & 0x01)== 1){ num_led = (dato & 0x7E)>>1; dato = Serial.read(); //read Serial brillo = dato; txCAN1(FILTROINFORMATIVO_CONTROL_M3A, num_led,brillo,0); } else{ num_led = (dato & 0x7E) >>1; estado = (dato & 0x80) >> 7; txCAN1(FILTROINFORMATIVO_CONTROL_M3D, num_led,estado,0); } } } } //Zona en la que se va a enviar la tabla de indicadores, para que los lea VB. int punteroauxiliar; // Con este recorro la tabla de pines indicadores digitales int punteroM1ID; punteroindicadoresdig = 0; //Indicadores DIGITALES punteroauxiliar =0; punteroM1ID = 0; while (punteroindicadoresdig != cantidad * 2){ Anexos 29 Controlador modular programable basado en procesadores de 32 bits y CAN bus. PIN = pines_digi_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; MODULO = pines_digi_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; switch (MODULO){ case 0: //MODULO 0 zonas_indicadores_digitales[punteroindicadoresdig] = digitalRead (PIN); punteroindicadoresdig = punteroindicadoresdig +1 ; break; case 1: //MODULO 1 while (PIN != MODULO1_ID[punteroM1ID]){ punteroM1ID = punteroM1ID + 2; } punteroM1ID = punteroM1ID + 1; zonas_indicadores_digitales[punteroindicadoresdig] MODULO1_ID[punteroM1ID]; = punteroM1ID = 0; punteroindicadoresdig = punteroindicadoresdig +1 ; break; case 2: //MODULO 2 while (PIN != MODULO2_ID[punteroM1ID]){ punteroM1ID = punteroM1ID + 2; } punteroM1ID = punteroM1ID + 1; zonas_indicadores_digitales[punteroindicadoresdig] MODULO2_ID[punteroM1ID]; = punteroM1ID = 0; punteroindicadoresdig = punteroindicadoresdig +1 ; break; case 3: //MODULO 3 while (PIN != MODULO3_ID[punteroM1ID]){ punteroM1ID = punteroM1ID + 2; } punteroM1ID = punteroM1ID + 1; zonas_indicadores_digitales[punteroindicadoresdig] MODULO3_ID[punteroM1ID]; Anexos 30 = Controlador modular programable basado en procesadores de 32 bits y CAN bus. punteroM1ID = 0; punteroindicadoresdig = punteroindicadoresdig +1 ; break; } } punteroindicadoresdig = 0; switch (cantidad) { case 1 ... 8: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic zonas_indicadores_digitales[punteroindicadoresdig]; + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = datoindic ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(checksum,BYTE); break; case 9 ... 16: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = datoindic + zonas_indicadores_digitales[punteroindicadoresdig]; punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2) ^17; Serial.print(58,BYTE); Anexos 31 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(checksum,BYTE); break; case 17 ... 24: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(checksum,BYTE); break; case 25 ... 32: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; Anexos 32 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^datoindic4) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(checksum,BYTE); break; case 33 ... 40: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; Anexos 33 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic5 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^datoindic4 ^datoindic5) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(checksum,BYTE); break; case 41 ... 48: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ Anexos 34 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. datoindic3 = datoindic3 <<1; datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic5 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic6 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = ^datoindic5^datoindic6) ^17; (datoindic ^ datoindic2 ^ datoindic3 ^datoindic4 Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(checksum,BYTE); break; case 49 ... 56: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic punteroindicadoresdig = punteroindicadoresdig +1; Anexos 35 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic5 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic6 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic7 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7) ^17; Serial.print(58,BYTE); Anexos 36 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(checksum,BYTE); break; case 57 ... 64: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic5 punteroindicadoresdig = punteroindicadoresdig +1; Anexos 37 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic6 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic7 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic8 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic8 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7 ^ datoindic8) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(datoindic8,BYTE); Serial.print(checksum,BYTE); break; case 65 ... 72: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic punteroindicadoresdig = punteroindicadoresdig +1; } Anexos 38 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic5 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic6 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic7 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic8 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic8 Anexos 39 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic9 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic9 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7 ^ datoindic8 ^ datoindic9) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(datoindic8,BYTE); Serial.print(datoindic9,BYTE); Serial.print(checksum,BYTE); break; case 73 ... 80: while (punteroindicadoresdig != 8){ datoindic = datoindic <<1; datoindic = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 16){ datoindic2 = datoindic2 <<1; datoindic2 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic2 punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 24){ datoindic3 = datoindic3 <<1; Anexos 40 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. datoindic3 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic3 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 32){ datoindic4 = datoindic4 <<1; datoindic4 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic4 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 40){ datoindic5 = datoindic5 <<1; datoindic5 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic5 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 48){ datoindic6 = datoindic6 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic6 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 56){ datoindic6 = datoindic7 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic7 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic8 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic8 + punteroindicadoresdig = punteroindicadoresdig +1; } while (punteroindicadoresdig != 64){ datoindic6 = datoindic9 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic9 punteroindicadoresdig = punteroindicadoresdig +1; } Anexos 41 + Controlador modular programable basado en procesadores de 32 bits y CAN bus. while (punteroindicadoresdig != 64){ datoindic6 = datoindic10 <<1; datoindic6 = zonas_indicadores_digitales[punteroindicadoresdig]; datoindic10 + punteroindicadoresdig = punteroindicadoresdig +1; } checksum = (datoindic ^ datoindic2 ^ datoindic3 ^ datoindic4 ^ datoindic5 ^ datoindic6 ^ datoindic7 ^ datoindic8 ^ datoindic9 ^ datoindic10) ^17; Serial.print(58,BYTE); Serial.print(datoindic,BYTE); Serial.print(datoindic2,BYTE); Serial.print(datoindic3,BYTE); Serial.print(datoindic4,BYTE); Serial.print(datoindic5,BYTE); Serial.print(datoindic6,BYTE); Serial.print(datoindic7,BYTE); Serial.print(datoindic8,BYTE); Serial.print(datoindic9,BYTE); Serial.print(datoindic10,BYTE); Serial.print(checksum,BYTE); break; } int punteroM1IA; //Indicadores ANALOGICOS punteroindicadoresanalog = 0; punteroauxiliar =0; punteroM1IA = 0; PIN = 0; MODULO = 0; while (punteroindicadoresanalog != cantidadanalog * 2){ PIN = pines_analog_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; MODULO = pines_analog_entrada[punteroauxiliar]; punteroauxiliar = punteroauxiliar +1 ; switch (MODULO){ case 0: //MODULO 0 zonas_indicadores_analogicos[punteroindicadoresanalog] = analogRead (PIN); Anexos 42 Controlador modular programable basado en procesadores de 32 bits y CAN bus. punteroindicadoresanalog = punteroindicadoresanalog +1 ; break; case 1: //MODULO 1 while (PIN != MODULO1_IA[punteroM1IA]){ punteroM1IA = punteroM1IA + 2; } punteroM1IA = punteroM1IA + 1; zonas_indicadores_analogicos[punteroindicadoresanalog] MODULO1_IA[punteroM1IA]; = punteroM1IA = 0; punteroindicadoresanalog = punteroindicadoresanalog +1 ; break; case 2: //MODULO 2 while (PIN != MODULO2_IA[punteroM1IA]){ punteroM1IA = punteroM1IA + 2; } punteroM1IA = punteroM1IA + 1; zonas_indicadores_analogicos[punteroindicadoresanalog] MODULO2_IA[punteroM1IA]; = punteroM1IA = 0; punteroindicadoresanalog = punteroindicadoresanalog +1 ; break; case 3: //MODULO 3 while (PIN != MODULO3_IA[punteroM1IA]){ punteroM1IA = punteroM1IA + 2; } punteroM1IA = punteroM1IA + 1; zonas_indicadores_analogicos[punteroindicadoresanalog] MODULO3_IA[punteroM1IA]; punteroM1IA = 0; punteroindicadoresanalog = punteroindicadoresanalog +1 ; break; } } punteroindicadoresanalog = 0; checksumanalog = 0; while (punteroindicadoresanalog != cantidadanalog){ Anexos 43 = Controlador modular programable basado en procesadores de 32 bits y CAN bus. Serial.print(zonas_indicadores_analogicos[punteroindicadoresanalog]); checksumanalog = zonas_indicadores_analogicos[punteroindicadoresanalog] ; checksumanalog ^ punteroindicadoresanalog = punteroindicadoresanalog +1 ; Serial.print (47,BYTE); } checksumanalog = checksumanalog ^17; Serial.print (checksumanalog); Serial.print (46,BYTE); // -------------------------------------ZONA DESTINADA UNICAMENTE AL BUS CAN ------------------------------------------------ // -----------------------------------------------------------// Labores de intercambio con el CAN // -----------------------------------------------------------byte dato0; byte dato1; byte dato2; byte dato3; byte dato4; byte dato5; byte dato6; int analogico; int tipo; if (isCAN1MsgReceived == false){ goto PROGRAMA; } rxCAN1(DatosMsg); DatosMsg[0] = dato0; //leo el dato que me ha llegado DatosMsg[1] = dato1; DatosMsg[2] = dato2; DatosMsg[3] = dato3; DatosMsg[4] = dato4; DatosMsg[5] = dato5; tipo = dato0 & 100000L; Anexos 44 Controlador modular programable basado en procesadores de 32 bits y CAN bus. tipo = tipo >> 5; if (dato0 == FILTROINFORMATIVO_ESTADO_M3A || dato0 == FILTROINFORMATIVO_ESTADO_M2A || dato0 == FILTROINFORMATIVO_ESTADO_M1A ){ //Filtro el mensaje para saber si es un dato que tengo que recoger //Nos ha llegado un dato analógico analogico = dato2 * 1000 + dato3 * 100 + dato4 * 10 + dato5; switch (tipo){ case 1: tamano = 0; tamano = sizeof(MODULO1_IA)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO1_IA[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO1_IA[punteroCAN] = analogico; } punteroCAN = punteroCAN +1; } break; case 2: tamano = 0; tamano = sizeof(MODULO1_IA)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO2_IA[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO2_IA[punteroCAN] = analogico; } punteroCAN = punteroCAN +1; } break; case 3: tamano = 0; tamano = sizeof(MODULO3_IA)/4; punteroCAN = 0; Anexos 45 Controlador modular programable basado en procesadores de 32 bits y CAN bus. while (punteroCAN <= tamano){ if (MODULO3_IA[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO3_IA[punteroCAN] = analogico; } punteroCAN = punteroCAN +1; } break; break; } } if (dato0 == FILTROINFORMATIVO_ESTADO_M3D || dato0 == FILTROINFORMATIVO_ESTADO_M2D || dato0 == FILTROINFORMATIVO_ESTADO_M1D ){ //Nos ha llegado un dato digital switch (tipo){ case 1: tamano = 0; tamano = sizeof(MODULO1_ID)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO1_ID[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO1_ID[punteroCAN] = dato2; } punteroCAN = punteroCAN +1; } break; case 2: tamano = 0; tamano = sizeof(MODULO1_ID)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO2_ID[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO2_ID[punteroCAN] = dato2; } punteroCAN = punteroCAN +1; Anexos 46 Controlador modular programable basado en procesadores de 32 bits y CAN bus. } break; case 3: tamano = 0; tamano = sizeof(MODULO1_ID)/4; punteroCAN = 0; while (punteroCAN <= tamano){ if (MODULO3_ID[punteroCAN] == dato1){ punteroCAN = punteroCAN +1; MODULO3_ID[punteroCAN] = dato2; } punteroCAN = punteroCAN +1; } break; } } analogico = 0; //-----------------------------------------------------------------------------------------------------------------------------------------// ESCRIBA EL CODIGO PROGRAMA A PARTIR DE ESTA ZONA. //´----------------------------------------------------------------------------------------------------------------------------------------PROGRAMA: delay (20); //-----------------------------------------------------------------------------------------------------------------------------------------// FIN. //´----------------------------------------------------------------------------------------------------------------------------------------} // -----------------------------------------------------------// Funciones de utilidad CAN // ------------------------------------------------------------ Anexos 47 Controlador modular programable basado en procesadores de 32 bits y CAN bus. // Descripción: // Inicializa el controlador CAN. void initCan1(uint32_t myaddr) { CAN::BIT_CONFIG canBitConfig; // Paso 1: Activa los switch del modulo CAN y los switch de modo de configuración. // Espera a que este completo. canMod1.enableModule(true); canMod1.setOperatingMode(CAN::CONFIGURATION); while(canMod1.getOperatingMode() != CAN::CONFIGURATION); /* Paso 2: Configura el reloj del modulo CAN. La función CAN::BIT_CONFIG la estructura de datos se utiliza * para este propósito. La propagación, la fase del segmento 1 y segmento 2 están configuradas con 3TQ. * La función CANSetSpeed(), establece la velocidad en baudios.*/ canBitConfig.phaseSeg2Tq = CAN::BIT_3TQ; canBitConfig.phaseSeg1Tq = CAN::BIT_3TQ; canBitConfig.propagationSegTq = CAN::BIT_3TQ; canBitConfig.phaseSeg2TimeSelect = CAN::TRUE; canBitConfig.sample3Time = CAN::TRUE; canBitConfig.syncJumpWidth = CAN::BIT_2TQ; canMod1.setSpeed(&canBitConfig,SYS_FREQ,CAN_BUS_SPEED); /* Paso 3: Asignación del área del buffer al modulo CAN.*/ /* Nota tenga en cuenta el área de cada canal. ** Se trata de 2 (Canales) * 8 (Buffer de mensaje) * 16 (bytes/por buffer de mensaje) bytes. Cada modulo ** CAN debe tener un mensaje propio. */ Anexos 48 Controlador modular programable basado en procesadores de 32 bits y CAN bus. canMod1.assignMemoryBuffer(CAN1MessageFifoArea,2 * 8 * 16); /* Paso 4: Configuración del canal 0 para prioridad baja media. TX y tamaño de 8 buffer de mensajes con * Configurar el canal 1 para RX y el tamaño de los 8 buffer de mensaje y recibir el mensaje completo. */ canMod1.configureChannelForTx(CAN::CHANNEL0,8,CAN::TX_RTR_DISABLED,CAN::LOW_MEDIUM_PRIOR ITY); canMod1.configureChannelForRx(CAN::CHANNEL1,8,CAN::RX_FULL_RECEIVE); // Paso 5 : Configurar filtros y mascaras. Configurar el filtro 0, mensajes a aceptar SID con ID= 0x100, // ID=0x110, ID=0x120, … // Configurar la mascara del filtro 0 y comparar todos los bits del ID y para filtrar el tipo de identificador se // hace en la especificación de la configuración del filtro. Los mensajes aceptados por el filtro son // almacenados en el canal 1. canMod1.configureFilter canMod1.configureFilterMask CAN::FILTER_MASK_IDE_TYPE); */ (CAN::FILTER0, myaddr, CAN::SID); (CAN::FILTER_MASK0, 0xFFF, CAN::SID, canMod1.linkFilterToChannel (CAN::FILTER0, CAN::FILTER_MASK0, CAN::CHANNEL1); canMod1.enableFilter (CAN::FILTER0, true); /* Paso 6: Habilitación interrupciones y eventos. Enable the receive channel not empty event (channel * event ) and the receive channel event (module event). * The interrrupt peripheral library is used to enable the CAN interrupt to the CPU. */ canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); canMod1.enableModuleEvent(CAN::RX_EVENT, true); /* Paso 7: Cambiar el modo de CAN a modo normal. */ canMod1.setOperatingMode(CAN::NORMAL_OPERATION); while(canMod1.getOperatingMode() != CAN::NORMAL_OPERATION); } Anexos 49 Controlador modular programable basado en procesadores de 32 bits y CAN bus. /*** txCAN1remota ** ** Descripción: ** Inicializa un buffer de paquetes con la cabecera y carga el paquete. La carga útil no es ninguna por ** en la trama remota es para ver si el nodo esta activo o no (solamente ID, RTR=1, y sin datos)*/ void txCAN1remota(uint32_t rxnode, uint8_t dato) bit que quiero que // en la variable piso va metido el // se ponga a 1 cuando pulsas el piso correspondiente // cada vez.. { CAN::TxMessageBuffer * message; message = canMod1.getTxMessageBuffer(CAN::CHANNEL0); que es el que /*Se coge del CHANNEL0 por * hemos configurado para transmitir *tengo que meter en el otro programa de *la nota de aplicación lo que tiene que *transmitir cada pulsador por el chanel0 */ /* IMPORTANTE lo que envía cuando se * pulsa hay que meterlo en el CHANEL0 */ if (message != NULL) { // limpiar el buffer message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID recibe, es decir = rxnode; //recepción del nodo (rxnode es el nodo que lo // a quien se lo envió) message->msgEID.IDE extendida = 1 = 0; //BIT IDE = trama estándar = 0, message->msgEID.RTR = 1; //RTR a recesivo por ser trama remota trama Anexos 50 Controlador modular programable basado en procesadores de 32 bits y CAN bus. message->msgEID.DLC = 0; // BIT DLC = longitud de los datos //message->data[0] = 0x00; //message->data[1] = 0x00; //message->data[2] = 0x00; //message->data[3] = 0x00; //message->data[4] = 0x00; //message->data[5] = 0x00; //message->data[6] = 0x00; //message->data[7] = 0x00; // datos, la trama remota no envía nada /* Esta función permite que el modulo CAN pueda saber como va el proceso del mensaje y cuando el * mensaje esta listo para ser procesado. */ canMod1.updateChannel(CAN::CHANNEL0); /* Modulo CAN directo para limpiar el canal TX . Esto envía algún mensaje pendiente en el canal TX . */ canMod1.flushTxChannel(CAN::CHANNEL0); } } /*______________________________________________________________________________________ ________________________________________________________________________________________ ________________________________________________________________________________________ _______________*/ /* ------------------------------------------------------------ */ /*** txCAN1 ** ** Descripción: ** Inicializa un buffer de paquetes con la cabecera y carga el paquete. La carga útil en este caso es solo un ** carácter ASCII (0x31 = '1'). Transmite el paquete.*/ Anexos 51 Controlador modular programable basado en procesadores de 32 bits y CAN bus. void txCAN1(uint32_t rxnode, uint8_t dato0, uint8_t dato1, uint8_t dato2) la variable piso va metido el bit que quiero que se ponga a // en // 1 cuando pulsas el piso correspondiente cada vez. { CAN::TxMessageBuffer * message; message = canMod1.getTxMessageBuffer(CAN::CHANNEL0); que es el que /*Se coge del CHANNEL0 por * hemos configurado para transmitir /* IMPORTANTE lo que envía cuando se * pulsa hay que meterlo en el CHANEL0 */ if (message != NULL) { // limpiar el buffer message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID recibe, es decir = rxnode; // recepción del nodo (rxnode es el nodo que lo // a quien se lo envió) message->msgEID.IDE extendida = 1 = 0; //BIT IDE = trama estándar = 0, trama message->msgEID.RTR = 0; // RTR a dominante message->msgEID.DLC = 3; // BIT DLC = numero de bytes a mandar por = dato0; // dato un solo byte dato message->data[0] en este caso seria : message->data[1] = dato1; message->data[2] = dato2; //message->data[3] = dato3; //message->data[4] = 0x00; //message->data[5] = 0x00; //message->data[6] = 0x00; //message->data[7] = 0x00; lo que quiero enviar Anexos 52 Controlador modular programable basado en procesadores de 32 bits y CAN bus. /* Esta función permite que el modulo CAN pueda saber como va el proceso del mensaje y cuando el * mensaje esta listo para ser procesado. */ canMod1.updateChannel(CAN::CHANNEL0); /* Modulo CAN directo para limpiar el canal TX . Esto envía algún mensaje pendiente en el canal TX . */ canMod1.flushTxChannel(CAN::CHANNEL0); } } //----------------------------------------------------------------------------------------------------------------------------------//** rxCAN1remota ** ** Descripción: //Comprueba si el nodo esta activo o no. Si esta activo imprime un mensaje indicando que esta correcto ** y sino es así imprime mensaje indicando de que es incorrecto por el monitor serie.*/ void rxCAN1remota(void) { CAN::RxMessageBuffer * message; if (isCAN1MsgReceived == false){ return; } //compruebo que si que ha llegado mensaje // si no ha llegado mensaje pongo NODO INACTIVO /* Mensaje ha sido recibido. Resetear los flags de isCAN1MsgReceived para recibir el siguiente mensaje. */ isCAN1MsgReceived = false; message = canMod1.getRxMessage(CAN::CHANNEL1); /* Llamar a la función CAN::updateChannel() para que el modulo CAN pueda saberlo que se hace en el * proceso del mensaje. Habilitar el evento para que cuando el modulo CAN genere una interrupción cuando * ocurre el evento.*/ canMod1.updateChannel(CAN::CHANNEL1); Anexos 53 Controlador modular programable basado en procesadores de 32 bits y CAN bus. canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); } /* ----------------------------------------------------------------------------------------------------------------------------------------------- * / /*** rxCAN1 ** ** Descripción: ** Comprueba si el paquete ha sido recibido. Si es así leer el paquete recibido e imprimir la carga del ** paquete por el monitor seria.*/ void rxCAN1(byte DatosMsg[ ]) { CAN::RxMessageBuffer * message; if (isCAN1MsgReceived == false) { /* CAN1 no recibió ningún mensaje para salir de la función. Saltamos a ERRORCAN*/ //Seguridad_mal=1; DatosMsg[0]= 0; DatosMsg[1]= 0; return ; } /* Mensaje ha sido recibido. Resetear los flags de isCAN1MsgReceived para recibir el siguiente mensaje. */ isCAN1MsgReceived = false; message = canMod1.getRxMessage(CAN::CHANNEL1); /* Imprime el primer byte del área del paquete cargado como un carácter ASCII por el monitor serie. */ Serial.print( DatosMsg [0]); /* Llamar a la función CAN::updateChannel() para que el modulo CAN pueda saberlo que se hace en el * proceso del mensaje. Habilitar el evento para que cuando el modulo CAN genere una interrupción cuando * ocurre el evento.*/ canMod1.updateChannel(CAN::CHANNEL1); canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); DatosMsg[0]= (message->data[0]); DatosMsg[1]= (message->data[1]); DatosMsg[2]= (message->data[2]); DatosMsg[3]= (message->data[3]); DatosMsg[4]= (message->data[4]); DatosMsg[5]= (message->data[5]); DatosMsg[6]= (message->data[6]); DatosMsg[7]= (message->data[7]); return ; } /* --------------------------------------------------------------------------- */ /* Manejador de las funciones de interrupción */ /* --------------------------------------------------------------------------- */ Anexos 54 Controlador modular programable basado en procesadores de 32 bits y CAN bus. /*** doCan1Interrupt ** ** Descripción: ** Rutina de servicio de interrupción para manejar el nivel de los eventos de interrupción para el modulo ** CAN1.*/ void doCan1Interrupt() { /* Este es el controlador de las interrupciones CAN1. Esto no es la rutina actual de interrupción, sino que es * el manejador de interrupciones de usuario instalado por CAN::attachInterrupt. Esto es llamado por el ISR. * Ten en cuenta que hay muchos eventos en el modulo CAN1 que pueden causar esta interrupción. Estos * eventos son activados por la función CAN::enableModuleEvent() . * En este ejemplo solo CAN::RX_EVENT esta habilitado. */ /* Comprobar si el origen de la interrupción es la función CAN::RX_EVENT. * Esto es redundante ya que solo este evento esta habilitado en este ejemplo, pero esto muestra un * esquema para la manipulación de las interrupciones. */ if ((canMod1.getModuleEvent() & CAN::RX_EVENT) != 0) { /* En este marco, se pueden comprobar los hechos que ocasionaron la interrupción con la función * CAN::getPendingEventCode() para obtener alta prioridad del evento activo.*/ if(canMod1.getPendingEventCode() == CAN::CHANNEL1_EVENT) { /* Esto significa que el canal 1 ha causado un evento. * El CAN::RX_CHANNEL_NOT_EMPTY es un evento persistente. Tu puedes leer el canal en el ISR para * borrar la condición establecer una bandera para del evento o deshabilitar el origen del evento y * indicar que un mensaje se ha recibido. El evento puede ser habilitado por la aplicación cuando se ha Anexos 55 Controlador modular programable basado en procesadores de 32 bits y CAN bus. * procesado un mensaje. * Ten en cuenta que la salida del evento habilitado podría causar que la CPU mantenga la ejecución de la * ISR ya que CAN::RX_CHANNEL_NOT_EMPTY es un evento persistente. (a menos que la condición no * este vacía, se borra.) */ canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, false); isCAN1MsgReceived = true; } } /* La bandera de interrupción del CAN1 se limpia por la rutina de servicio de la interrupción después lo * devuelve la función. Esto sucederá porque la causa del evento de la interrupción * (CAN::RX_CHANNEL_NOT_EMPTY) esta deshabilitado . * El intento del ISR's de borrar el flag de interrupción seria un error en el caso de que * CAN::RX_CHANNEL_NOT_EMPTY este habilitado, porque el evento todavía esta presente. En este caso * otra interrupción podría ocurrir inmediatamente */ } 2.4. Código del resto de módulos. // Incluir librerías: #include <WProgram.h> #include "chipKITCAN.h" #include <LiquidCrystal.h> // inicializar la libreria con el numero de pins del interfaz LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // -----------------------------------------------------------------------// Definición de constantes y variables locales // ------------------------------------------------------------------------ Anexos 56 Controlador modular programable basado en procesadores de 32 bits y CAN bus. // Direcciones de red de los nodos //Nodos de los modulos // Definición de la frecuencia y de la velocidad #define SYS_FREQ (80000000L) #define CAN_BUS_SPEED 250000 // velocidad CAN // -----------------------------------------------------------// Variables globales // ------------------------------------------------------------ // Interfaz de instancias del nodo controlador CAN CAN canMod1(CAN::CAN1); // este objeto lo usa el modulo CAN1 CAN canMod2(CAN::CAN2); // este objeto lo usa el modulo CAN2 byte DatosMsg[7]; // -----------------------------------------------------------// Variables locales // -----------------------------------------------------------uint8_t REMOTA = 0x0C; // Indico si esta correcto el modulo // Buffer de mensajes CAN uint8_t CAN1MessageFifoArea [2 * 8 * 16]; uint8_t CAN2MessageFifoArea [2 * 8 * 16]; // Flags indicadores de eventos de las rutinas de interrupción. static volatile bool isCAN1MsgReceived = false; static volatile bool isCAN2MsgReceived = false; Anexos 57 Controlador modular programable basado en procesadores de 32 bits y CAN bus. // -----------------------------------------------------------// Declaraciones directas // ------------------------------------------------------------ void initCan1 (uint32_t myaddr); void doCan1Interrupt(); void txCAN1remota(uint32_t rxnode, uint8_t dato); remotas // función para envió de tramas void txCAN1(uint32_t rxnode, uint8_t dato0, uint8_t dato1, uint8_t dato2, uint8_t dato ); void rxCAN1remota(void); // función para recibir las tramas remotas void rxCAN1(void); // -----------------------------------------------------------// Definición de variables globales // ------------------------------------------------------------ uint8_t modulo0 = 0x00; uint8_t modulo1 = 0x01; byte dato0; byte dato1; byte dato2; byte dato3; byte dato6; byte miles; byte centenas; byte decenas; byte unidades; byte punteroID; byte punteroIA; unsigned int MODULO_ID[] = {} ; unsigned int MODULO_IA[] = {}; // Array de pines entradas digitales del modulo // Array de pines entradas analogicas del modulo byte tamano; void setup(){ Anexos 58 Controlador modular programable basado en procesadores de 32 bits y CAN bus. int valor_analogico; byte dato; byte datomodulo1; pinMode(11,INPUT); // A estos pines estan conectados los switches pinMode(12,INPUT); pinMode(83,INPUT); pinMode(84,INPUT); pinMode(85,INPUT); dato = digitalRead(11); datomodulo1 = dato << 4; dato = digitalRead(12); datomodulo1 = (dato << 3)+ datomodulo1; dato = 0; dato = digitalRead(83); datomodulo1 = (dato << 2) + datomodulo1; dato = 0; dato = digitalRead(84); datomodulo1 = (dato << 1)+ datomodulo1; dato = 0; dato = digitalRead(85); datomodulo1 = dato + datomodulo1; dato = 0; switch (dato){ case 1: //FILTROS #define FILTROCONFIGURA_M1D 0x0100L; //Filtro para configurarme #define FILTROCONFIGURA_M1A 0x0101L; //Filtro para configurarme #define FILTROINFORMATIVO_FC_M1 0x0111L; //Filtro con el que me indica el modulo 0 que ya no me va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x1011L; decirle que ya estoy configurado configurado //Filtro que mando al modulo 0 para Anexos 59 Controlador modular programable basado en procesadores de 32 bits y CAN bus. #define FILTROINFORMATIVOESTADOM1D modulo 0 0x1011L; //Mando el estado de un pin digital al #define FILTROINFORMATIVOESTADOM1A al modulo 0 0x1011L; //Mando el estado de un pin analogico #define FILTROINFORMATIVO_CONTROL_M1A quiere que ponga un pin analogico 0x011101L; #define FILTROINFORMATIVO_CONTROL_M1D quiere que ponga un pin digital 0x011100L; //El modulo 0 me manda como //El modulo 0 me manda como break; case 2: //FILTROS #define FILTROCONFIGURA_M1D 0x0200L; //Filtro para configurarme #define FILTROCONFIGURA_M1A 0x0201L; //Filtro para configurarme #define FILTROINFORMATIVO_FC_M1 0x0211L; //Filtro con el que me indica el modulo 0 que ya no me va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x2011L; decirle que ya estoy configurado configurado //Filtro que mando al modulo 0 para #define FILTROINFORMATIVO_ESTADO_M1D 0x201100L; al modulo 0 //Mando el estado de un pin digital #define FILTROINFORMATIVO_ESTADO_M1A 0x201101L; al modulo 0 //Mando el estado de un pin analogico #define FILTROINFORMATIVO_CONTROL_M1A quiere que ponga un pin analogico 0x021101L; #define FILTROINFORMATIVO_CONTROL_M1D quiere que ponga un pin digital 0x021100L; //El modulo 0 me manda como //El modulo 0 me manda como break; case 3: //FILTROS #define FILTROCONFIGURA_M1D 0x0300L; //Filtro para configurarme #define FILTROCONFIGURA_M1A 0x0301L; //Filtro para configurarme #define FILTROINFORMATIVO_FC_M1 0x0311L; //Filtro con el que me indica el modulo 0 que ya no me va a enviar más datos de configuración #define FILTROINFORMATIVO_ACK_M1 0x3011L; decirle que ya estoy configurado configurado #define FILTROINFORMATIVO_ESTADO_M1D 0x301100L; al modulo 0 //Filtro que mando al modulo 0 para //Mando el estado de un pin digital Anexos 60 Controlador modular programable basado en procesadores de 32 bits y CAN bus. #define FILTROINFORMATIVO_ESTADO_M1A 0x301101L; al modulo 0 //Mando el estado de un pin analogico #define FILTROINFORMATIVO_CONTROL_M1A quiere que ponga un pin analogico 0x031101L; #define FILTROINFORMATIVO_CONTROL_M1D quiere que ponga un pin digital 0x031100L; //El modulo 0 me manda como //El modulo 0 me manda como break; } lcd.begin(16, 2); lcd.print("PROYECTO"); Serial.begin(9600); // inicializar LCD // Escribir un mensaje en LCD //Puerto serie, configuración // Instalar las rutinas de servicio de interrupción. canMod1.attachInterrupt (doCan1Interrupt); ESPERA1: if (isCAN1MsgReceived == false){ // CAN1 no recibio ningún mensaje para salir de la función, nos mantenemos a la espera goto ESPERA1; } rxCAN1(DatosMsg); dato0 = DatosMsg[0]; // almaceno del dato dato1 = DatosMsg[1]; dato2 = DatosMsg[2]; dato3 = DatosMsg[3]; if (dato0 == 0x01){ // El dato que acaba de llegar me interesa VARIABLE A MODIFICAR PARA CADA MODULO!!!! if (dato2 == 0xFF){ remite al modulo0 ¡¡¡¡¡ESTA ES LA // Si le llega ese dato es que ya se ha configurado y se lo goto CONFIGURADO; } else{ pinMode(dato1,INPUT); switch(dato2){ case 0: Anexos 61 Controlador modular programable basado en procesadores de 32 bits y CAN bus. MODULO_ID[punteroID] = dato1; punteroID = punteroID +1; break; case 1: MODULO_IA[punteroIA] = dato1; punteroIA = punteroIA +1; break; } goto ESPERA1; // No ha terminado de configurarse así que debe de leer otra vez } } CONFIGURADO: txCAN1(modulo0, 0xFF,0xFF,modulo1,0x00,0x00,0x00); // YA ESTA CONFIGURADO Y PUEDE COMENZAR A TRABAJAR EN EL LOOP } void loop(){ // Leo entradas digitales y le remito su estado al modulo0 // En primer lugar obtengo el tamaño de MODULO_ID byte valor_analogico; tamano = sizeof(MODULO_ID)/4; punteroID = 0; dato0 = 0; dato1 = 0; dato2 = 0; while (punteroID <= tamano){ // recorro MODULO_ID leyendo el dato de cada uno de los pines y remitiendoselo a modulo0 dato2=digitalRead (MODULO_ID[punteroID]); modulo0 = FILTROINFORMATIVOESTADOM1A; txCAN1(modulo0, MODULO_ID[punteroID],0x00,0x00,0x00,0x00,0x00); punteroID = punteroID +1; } tamano = sizeof(MODULO_IA)/4; punteroIA = 0; Anexos 62 Controlador modular programable basado en procesadores de 32 bits y CAN bus. while (punteroIA <= tamano){ // recorro MODULO_IA leyendo el dato de cada uno de los pines y remitiendoselo a modulo0 valor_analogico = analogRead (MODULO_IA[punteroIA]); modulo0 = FILTROINFORMATIVOESTADOM1A; txCAN1(modulo0, MODULO_IA[punteroIA], miles, centenas, decenas, unidades,0x00); punteroIA = punteroIA +1; } //-----------------------------------------------------------------------------------------------------------------------------------------// ESCRIBA EL CODIGO PROGRAMA A PARTIR DE ESTA ZONA. //´----------------------------------------------------------------------------------------------------------------------------------------delay (20); //-----------------------------------------------------------------------------------------------------------------------------------------// FIN. //´----------------------------------------------------------------------------------------------------------------------------------------} // -----------------------------------------------------------// Funciones de utilidad CAN // ------------------------------------------------------------ // // Descripción: Inicializa el controlador CAN. void initCan1(uint32_t myaddr) { CAN::BIT_CONFIG canBitConfig; // Paso 1: Activa los switch del modulo CAN y los switch de modo de configuración. // Espera a que este completo. Anexos 63 Controlador modular programable basado en procesadores de 32 bits y CAN bus. canMod1.enableModule(true); canMod1.setOperatingMode(CAN::CONFIGURATION); while(canMod1.getOperatingMode() != CAN::CONFIGURATION); /* Paso 2: Configura el reloj del modulo CAN. La función CAN::BIT_CONFIG la estructura de datos se utiliza * para este propósito. La propagación, la fase del segmento 1 y segmento 2 están configuradas con 3TQ. * La función CANSetSpeed(), establece la velocidad en baudios.*/ canBitConfig.phaseSeg2Tq = CAN::BIT_3TQ; canBitConfig.phaseSeg1Tq = CAN::BIT_3TQ; canBitConfig.propagationSegTq = CAN::BIT_3TQ; canBitConfig.phaseSeg2TimeSelect = CAN::TRUE; canBitConfig.sample3Time = CAN::TRUE; canBitConfig.syncJumpWidth = CAN::BIT_2TQ; canMod1.setSpeed(&canBitConfig,SYS_FREQ,CAN_BUS_SPEED); /* Paso 3: Asignación del área del buffer al modulo CAN.*/ /* Nota tenga en cuenta el área de cada canal. ** Se trata de 2 (Canales) * 8 (Buffer de mensaje) * 16 (bytes/por buffer de mensaje) bytes. Cada modulo ** CAN debe tener un mensaje propio. */ canMod1.assignMemoryBuffer(CAN1MessageFifoArea,2 * 8 * 16); /* Paso 4: Configuración del canal 0 para prioridad baja media. TX y tamaño de 8 buffer de mensajes con * Configurar el canal 1 para RX y el tamaño de los 8 buffer de mensaje y recibir el mensaje completo. */ canMod1.configureChannelForTx(CAN::CHANNEL0,8,CAN::TX_RTR_DISABLED,CAN::LOW_MEDIUM_PRIOR ITY); canMod1.configureChannelForRx(CAN::CHANNEL1,8,CAN::RX_FULL_RECEIVE); Anexos 64 Controlador modular programable basado en procesadores de 32 bits y CAN bus. // Paso 5 : Configurar filtros y mascaras. Configurar el filtro 0, mensajes a aceptar SID con ID= 0x100, // ID=0x110, ID=0x120, … // Configurar la mascara del filtro 0 y comparar todos los bits del ID y para filtrar el tipo de identificador se // hace en la especificación de la configuración del filtro. Los mensajes aceptados por el filtro son // almacenados en el canal 1. canMod1.configureFilter canMod1.configureFilterMask CAN::FILTER_MASK_IDE_TYPE); */ (CAN::FILTER0, myaddr, CAN::SID); (CAN::FILTER_MASK0, 0xFFF, CAN::SID, canMod1.linkFilterToChannel (CAN::FILTER0, CAN::FILTER_MASK0, CAN::CHANNEL1); canMod1.enableFilter (CAN::FILTER0, true); /* Paso 6: Habilitación interrupciones y eventos. Enable the receive channel not empty event (channel * event ) and the receive channel event (module event). * The interrrupt peripheral library is used to enable the CAN interrupt to the CPU. */ canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); canMod1.enableModuleEvent(CAN::RX_EVENT, true); /* Paso 7: Cambiar el modo de CAN a modo normal. */ canMod1.setOperatingMode(CAN::NORMAL_OPERATION); while(canMod1.getOperatingMode() != CAN::NORMAL_OPERATION); } /*** txCAN1remota ** ** Descripción: ** Inicializa un buffer de paquetes con la cabecera y carga el paquete. La carga útil no es ninguna por ** en la trama remota es para ver si el nodo esta activo o no (solamente ID, RTR=1, y sin datos)*/ void txCAN1remota(uint32_t rxnode, uint8_t dato) bit que quiero que // en la variable piso va metido el // se ponga a 1 cuando pulsas el piso correspondiente // cada vez.. Anexos 65 Controlador modular programable basado en procesadores de 32 bits y CAN bus. { CAN::TxMessageBuffer * message; message = canMod1.getTxMessageBuffer(CAN::CHANNEL0); que es el que /*Se coge del CHANNEL0 por * hemos configurado para transmitir *tengo que meter en el otro programa de *la nota de aplicación lo que tiene que *transmitir cada pulsador por el chanel0 */ /* IMPORTANTE lo que envía cuando se * pulsa hay que meterlo en el CHANEL0 */ if (message != NULL) { // limpiar el buffer message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID recibe, es decir = rxnode; //recepción del nodo (rxnode es el nodo que lo // a quien se lo envió) message->msgEID.IDE extendida = 1 = 0; //BIT message->msgEID.RTR = 1; //RTR a recesivo por ser trama remota message->msgEID.DLC = 0; // BIT DLC = longitud de los datos //message->data[0] = 0x00; //message->data[1] = 0x00; //message->data[2] = 0x00; //message->data[3] = 0x00; //message->data[4] = 0x00; //message->data[5] = 0x00; //message->data[6] = 0x00; //message->data[7] = 0x00; IDE = trama estándar = 0, trama // datos, la trama remota no envía nada Anexos 66 Controlador modular programable basado en procesadores de 32 bits y CAN bus. /* Esta función permite que el modulo CAN pueda saber como va el proceso del mensaje y cuando el * mensaje esta listo para ser procesado. */ canMod1.updateChannel(CAN::CHANNEL0); /* Modulo CAN directo para limpiar el canal TX . Esto envía algún mensaje pendiente en el canal TX . */ canMod1.flushTxChannel(CAN::CHANNEL0); } } /*______________________________________________________________________________________ ________________________________________________________________________________________ ________________________________________________________________________________________ _______________*/ /* ------------------------------------------------------------ */ /*** txCAN1 ** ** Descripción: ** Inicializa un buffer de paquetes con la cabecera y carga el paquete. La carga útil en este caso es solo un ** carácter ASCII (0x31 = '1'). Transmite el paquete.*/ void txCAN1(uint32_t rxnode, uint8_t dato0, uint8_t dato1, uint8_t dato2, uint8_t dato3, uint8_t dato4, uint8_t dato5) // en la variable piso va metido el bit que quiero que se ponga a // 1 cuando pulsas el piso correspondiente cada vez. { CAN::TxMessageBuffer * message; message = canMod1.getTxMessageBuffer(CAN::CHANNEL0); que es el que /*Se coge del CHANNEL0 por * hemos configurado para transmitir Anexos 67 Controlador modular programable basado en procesadores de 32 bits y CAN bus. /* IMPORTANTE lo que envía cuando se * pulsa hay que meterlo en el CHANEL0 */ if (message != NULL) { // limpiar el buffer message->messageWord[0] = 0; message->messageWord[1] = 0; message->messageWord[2] = 0; message->messageWord[3] = 0; message->msgSID.SID recibe, es decir = rxnode; // recepción del nodo (rxnode es el nodo que lo // a quien se lo envió) message->msgEID.IDE extendida = 1 = 0; //BIT IDE = trama estándar = 0, trama message->msgEID.RTR = 0; // RTR a dominante message->msgEID.DLC = 6; // BIT DLC = numero de bytes a mandar por = dato0; // dato un solo byte dato message->data[0] en este caso seria : message->data[1] = dato1; message->data[2] = dato2; message->data[3] = dato3; message->data[4] = dato4; message->data[5] = dato5; message->data[6] = dato6; //message->data[7] lo que quiero enviar = 0x00; /* Esta función permite que el modulo CAN pueda saber como va el proceso del mensaje y cuando el * mensaje esta listo para ser procesado. */ canMod1.updateChannel(CAN::CHANNEL0); /* Modulo CAN directo para limpiar el canal TX . Esto envía algún mensaje pendiente en el canal TX . */ canMod1.flushTxChannel(CAN::CHANNEL0); } Anexos 68 Controlador modular programable basado en procesadores de 32 bits y CAN bus. } //----------------------------------------------------------------------------------------------------------------------------------//** rxCAN1remota ** ** Descripción: //Comprueba si el nodo esta activo o no. Si esta activo imprime un mensaje indicando que esta correcto ** y sino es así imprime mensaje indicando de que es incorrecto por el monitor serie.*/ void rxCAN1remota(void) { CAN::RxMessageBuffer * message; if (isCAN1MsgReceived == false){ return; } //compruebo que si que ha llegado mensaje // si no ha llegado mensaje pongo NODO INACTIVO /* Mensaje ha sido recibido. Resetear los flags de isCAN1MsgReceived para recibir el siguiente mensaje. */ isCAN1MsgReceived = false; message = canMod1.getRxMessage(CAN::CHANNEL1); /* Llamar a la función CAN::updateChannel() para que el modulo CAN pueda saberlo que se hace en el * proceso del mensaje. Habilitar el evento para que cuando el modulo CAN genere una interrupción cuando * ocurre el evento.*/ canMod1.updateChannel(CAN::CHANNEL1); canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); } /* ----------------------------------------------------------------------------------------------------------------------------------------------- * / /*** rxCAN1 ** ** Descripción: ** Comprueba si el paquete ha sido recibido. Si es así leer el paquete recibido e imprimir la carga del ** paquete por el monitor seria.*/ void rxCAN1(byte DatosMsg[ ]) { CAN::RxMessageBuffer * message; if (isCAN1MsgReceived == false) { /* CAN1 no recibió ningún mensaje para salir de la función. Saltamos a ERRORCAN*/ //Seguridad_mal=1; Anexos 69 Controlador modular programable basado en procesadores de 32 bits y CAN bus. DatosMsg[0]= 0; DatosMsg[1]= 0; return ; } /* Mensaje ha sido recibido. Resetear los flags de isCAN1MsgReceived para recibir el siguiente mensaje. */ isCAN1MsgReceived = false; message = canMod1.getRxMessage(CAN::CHANNEL1); /* Imprime el primer byte del área del paquete cargado como un carácter ASCII por el monitor serie. */ Serial.print( DatosMsg [0]); /* Llamar a la función CAN::updateChannel() para que el modulo CAN pueda saberlo que se hace en el * proceso del mensaje. Habilitar el evento para que cuando el modulo CAN genere una interrupción cuando * ocurre el evento.*/ canMod1.updateChannel(CAN::CHANNEL1); canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true); DatosMsg[0]= (message->data[0]); DatosMsg[1]= (message->data[1]); DatosMsg[2]= (message->data[2]); DatosMsg[3]= (message->data[3]); DatosMsg[4]= (message->data[4]); DatosMsg[5]= (message->data[5]); DatosMsg[6]= (message->data[6]); DatosMsg[7]= (message->data[7]); return ; } /* --------------------------------------------------------------------------- */ /* Manejador de las funciones de interrupción */ /* --------------------------------------------------------------------------- */ /*** doCan1Interrupt ** ** Descripción: ** Rutina de servicio de interrupción para manejar el nivel de los eventos de interrupción para el modulo ** CAN1.*/ void doCan1Interrupt() { /* Este es el controlador de las interrupciones CAN1. Esto no es la rutina actual de interrupción, sino que es * el manejador de interrupciones de usuario instalado por CAN::attachInterrupt. Esto es llamado por el ISR. Anexos 70 Controlador modular programable basado en procesadores de 32 bits y CAN bus. * Ten en cuenta que hay muchos eventos en el modulo CAN1 que pueden causar esta interrupción. Estos * eventos son activados por la función CAN::enableModuleEvent() . * En este ejemplo solo CAN::RX_EVENT esta habilitado. */ /* Comprobar si el origen de la interrupción es la función CAN::RX_EVENT. * Esto es redundante ya que solo este evento esta habilitado en este ejemplo, pero esto muestra un * esquema para la manipulación de las interrupciones. */ if ((canMod1.getModuleEvent() & CAN::RX_EVENT) != 0) { /* En este marco, se pueden comprobar los hechos que ocasionaron la interrupción con la función * CAN::getPendingEventCode() para obtener alta prioridad del evento activo.*/ if(canMod1.getPendingEventCode() == CAN::CHANNEL1_EVENT) { /* Esto significa que el canal 1 ha causado un evento. * El CAN::RX_CHANNEL_NOT_EMPTY es un evento persistente. Tu puedes leer el canal en el ISR para * borrar la condición establecer una bandera para del evento o deshabilitar el origen del evento y * indicar que un mensaje se ha recibido. El evento puede ser habilitado por la aplicación cuando se ha * procesado un mensaje. * Ten en cuenta que la salida del evento habilitado podría causar que la CPU mantenga la ejecución de la * ISR ya que CAN::RX_CHANNEL_NOT_EMPTY es un evento persistente. (a menos que la condición no * este vacía, se borra.) */ canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, false); isCAN1MsgReceived = true; } } Anexos 71 Controlador modular programable basado en procesadores de 32 bits y CAN bus. /* La bandera de interrupción del CAN1 se limpia por la rutina de servicio de la interrupción después lo * devuelve la función. Esto sucederá porque la causa del evento de la interrupción * (CAN::RX_CHANNEL_NOT_EMPTY) esta deshabilitado . * El intento del ISR's de borrar el flag de interrupción seria un error en el caso de que * CAN::RX_CHANNEL_NOT_EMPTY este habilitado, porque el evento todavía esta presente. En este caso * otra interrupción podría ocurrir inmediatamente */ } Anexos 72 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 3. Anexo 3. Código de la aplicación SCADA. El código de la aplicación SCADA ya ha sido explicado e integrado paso a paso en la memoria casi en su totalidad. Aun así, si el lector lo desea podrá consultarlo en la carpeta del CD adjunto “Proyecto SCADAv7.0”. Anexos 73 Controlador modular programable basado en procesadores de 32 bits y CAN bus. 4. Anexo 4. Contenido del cd adjunto. El contenido del cd adjunto es el siguiente: • • • • • • • • • • • ANEXOS. Datashetts del bus CAN. Datasheets del hardware. Memoria. Planos. Pliego de condiciones. Portada y índice general. Presupuesto. Archivos Top Solid. Proyecto SCADAv7.0. Manual de usuario. Anexos 74 Controlador modular programable basado en procesadores de 32 bits y CAN bus. Logroño, a 3 de septiembre de 2013. Alberto Martínez Inchusta. Anexos 75 Planos Índice de Planos. 1. Plano 1. Entradas digitales ..................................................................................................... 1 2. Plano 2. Salidas digitales ......................................................................................................... 2 3. Plano 3. Entradas analógicas ................................................................................................. 3 4. Plano 4. Estructura hardware del autómata.................................................................... 4 5. Plano 5. Placa principal. ........................................................................................................... 5 6. Plano 6. Esquema electrónico de las salidas digitales rápidas. ................................ 6 7. Plano 7. Esquema electrónico de las salidas digitales a triac.................................... 7 8. Plano 8. Esquema electrónico de las entradas analógicas. ........................................ 8 9. Plano 9. Esquema electrónico de las entradas digitales. ............................................ 9 Controlador modular programable basado En procesadores de 32 bits y CAN bus 1. Plano 1. Entradas digitales Planos 1 Controlador modular programable basado En procesadores de 32 bits y CAN bus 2. Plano 2. Salidas digitales Planos 2 Controlador modular programable basado En procesadores de 32 bits y CAN bus 3. Plano 3. Entradas analógicas Planos 3 Controlador modular programable basado En procesadores de 32 bits y CAN bus 4. Plano 4. Estructura hardware del autómata. Planos 4 Controlador modular programable basado En procesadores de 32 bits y CAN bus 5. Plano 5. Placa principal. Información disponible en disco (CD-ROM) Planos 5 Controlador modular programable basado En procesadores de 32 bits y CAN bus 6. Plano 6. Esquema electrónico de las salidas digitales rápidas. Información disponible en disco (CD-ROM) Planos 6 Controlador modular programable basado En procesadores de 32 bits y CAN bus 7. Plano 7. Esquema electrónico de las salidas digitales a triac. Información disponible en disco (CD-ROM) Planos 7 Controlador modular programable basado En procesadores de 32 bits y CAN bus 8. Plano 8. Esquema electrónico de las entradas analógicas. Información disponible en disco (CD-ROM) Planos 8 Controlador modular programable basado En procesadores de 32 bits y CAN bus 9. Plano 9. Esquema electrónico de las entradas digitales. Información disponible en disco (CD-ROM) Planos 9 Controlador modular programable basado En procesadores de 32 bits y CAN bus Logroño, a 3 de Septiembre de 2013. Fdo: Alberto Martínez Inchusta. Planos 10 Pliego de condiciones Índice del pliego de condiciones. 1. Disposiciones Generales. ......................................................................................................... 1 1.1. Introducción. ........................................................................................................................ 1 1.2. Objeto...................................................................................................................................... 2 1.3. Propiedad intelectual. ...................................................................................................... 3 2. Disposiciones legales y normativa aplicable. .................................................................. 4 3. Condiciones facultativas. ......................................................................................................... 6 4. 3.1. Dirección................................................................................................................................ 6 3.2. Libro de órdenes................................................................................................................. 7 Condiciones de ejecución y montaje. .................................................................................. 8 4.1 Condiciones de fabricación del circuito impreso. .................................................. 8 4.2 Pruebas y ensayos del montaje de la placa. ............................................................. 9 4.2.1 Prueba de alimentación. ......................................................................................... 9 4.2.2 Prueba de la placa. .................................................................................................... 9 4.2.3 Conexionado de los componentes....................................................................... 9 4.3 Conexionado de sensores y actuadores................................................................... 10 4.3.1 Entradas digitales. ................................................................................................... 10 4.3.2 Salidas digitales. ....................................................................................................... 11 4.3.3 Entradas analógicas. ............................................................................................... 12 4.4 Especificaciones técnicas de la parte hardware................................................... 13 4.4.1 Placa principal. ......................................................................................................... 13 4.4.2 Módulo de entradas analógicas.......................................................................... 14 4.4.3 Módulo de entradas digitales.............................................................................. 16 4.4.4 Módulo de salidas digitales rápidas. ................................................................ 18 4.4.5 Módulo de salidas digitales a triac. ................................................................... 19 4.4.6 chipKIT MAX32. ....................................................................................................... 20 4.5 Especificaciones técnicas del CAN bus..................................................................... 21 4.5.1 5. MCP2551..................................................................................................................... 23 4.6 Instalación y uso de las aplicaciones ........................................................................ 25 4.7. Conservación...................................................................................................................... 26 4.8. Funcionamiento normal del equipo.......................................................................... 27 Condiciones de materiales y equipos. .............................................................................. 28 5.1. Condiciones técnicas de los materiales. .................................................................. 28 5.2. Condiciones técnicas del material informático .................................................... 29 5.3. Condiciones técnicas de los circuitos impresos. .................................................. 30 5.4. Condiciones técnicas de los elementos pasivos. .................................................. 31 5.5. Hardware Open Source. Condiciones de utilización........................................... 32 6. Manual de usuario. .................................................................................................................. 34 7. Disposición final. ...................................................................................................................... 48 Controlador modular programable basado en procesadores de 32 bits y CAN bus 1. Disposiciones Generales. 1.1. Introducción. Las características y la descripción del proyecto “Controlador modular programable basado en procesador de 32 bits y CAN bus”, los componentes que intervienen, el cableado y conexionado eléctrico y control del funcionamiento del mismo se detallan en el documento de la memoria y en los correspondientes planos del documento. En este documento se exponen todas las condiciones técnicas de montaje, especificaciones a cumplir por los elementos y materiales normalizados y comerciales que se deben considerar a la hora de llevar a cabo la realización del proyecto. En caso de no realizarse según las condiciones tal y como se presentan en este documento, el proyectista no se responsabilizará de los posibles fallos y averías propios del funcionamiento, repercutiéndose todo el peso del problema sobre terceras personas. Todas las modificaciones de las que pueda ser susceptible el proyecto, deberán ser aprobadas por el ingeniero o proyectista. Pliego de condiciones. 1 Controlador modular programable basado en procesadores de 32 bits y CAN bus 1.2. Objeto. La realización del presente Proyecto titulado “Controlador modular programable basado en procesador de 32 bits” se enmarca bajo la designación de Proyecto Fin de Carrera y tiene como propósito culminar con éxito los estudios de Ingeniería Industrial superior. El autor del presente proyecto ha cursado estos estudios en la Universidad de la Rioja, cumpliendo en su elaboración las directrices especificadas por dicho centro en la normativa del proyecto fin de carrera aprobada por el consejo de Gobierno el 15 de abril de 2005. Pliego de condiciones. 2 Controlador modular programable basado en procesadores de 32 bits y CAN bus 1.3. Propiedad intelectual. Según el artículo 13 de la normativa vigente en el centro, la propiedad intelectual del autor y director del Proyecto o Trabajo Fin de Carrera se regirá por el Real Decreto Legislativo 1/1996, de 12 de abril, por el que se aprueba el texto refundido de la Ley de Propiedad Intelectual, y por la normativa vigente en la Universidad de La Rioja. Pliego de condiciones. 3 Controlador modular programable basado en procesadores de 32 bits y CAN bus 2. Disposiciones legales y normativa aplicable. La realización del proyecto se regirá por la Ordenanza General de Seguridad e Higiene en el Trabajo del 7 de abril de 1970 y posteriores revisiones. Así mismo, se regirá por el Reglamento Electrotécnico de Baja Tensión, en el que se tendrá en cuenta las siguientes normativas: • • M.I. B.T.029, la cual se refiere a instalaciones de pequeñas tensiones, menores de 50 voltios. M.I. B.T.031, la cual se refiere a las condiciones generales de instalación, de utilización, así como de los requisitos a cumplir a la hora del diseño. El proyecto cumple también con las siguientes normativas DIN y UNE: • • • • • • • • • • • • • • • Los materiales que pueden ser utilizados para la realización de placas de circuito impreso UNE 20-621-85/3. Los espesores de los materiales con recubrimiento metálico y sus tolerancias especificadas en la norma UNE 20-621-84/3. La norma UNE 20552 especifica las tolerancias sobre el espesor total en la zona de contactos. En cuanto a la anchura de las pistas, según la intensidad que circule por el material conductor, se referirá a la norma UNE 20-621. Los diámetros de los taladros están especificados en la norma UNE 20621-84/3. La norma UNE 20-612/2 recoge varios tipos de ensayos que pueden realizarse y los materiales, como pueden ser los ensayos de espesor, adherencia, porosidad, etc. En las distancias entre taladros para la colocación de componentes, se seguirá lo indicado en la norma UNE 20-524/1, UNE 20-524/2 y UNE 20-524/3. Reglas de seguridad para los aparatos electrónicos de norma UNE 20514-82. DIN 40801, referente a circuitos impresos, fundamentos, orificios y espesores. DIN 40803, referente a circuitos impresos, placas y documentación. DIN 40804, referente a circuitos impresos, conceptos. DIN41494, referente a las formas de construcción para dispositivos electrónicos. Reglas para el diseño y utilización de placas de circuito impresas UNE 20-621-3. Especificación para la realización de placas de simple o doble cara con agujeros no metalizados y metalizados UNE 20-621-4 y UNE 20-621-5. Especificación para las placas impresas multicapas UNE 20-621-6. Pliego de condiciones. 4 Controlador modular programable basado en procesadores de 32 bits y CAN bus • • UNE 20902 que hace referencia a la técnica de circuitos impresos, terminología. UNE-EN 60249 en la cual se citan los materiales base para circuitos impresos. Este proyecto debido a sus características se encuentra recogido dentro del reglamento eléctrico de baja tensión. “Se calificará como instalación eléctrica de baja tensión todo conjunto de aparatos y circuitos asociados en previsión de un fin particular, producción, conversión, transformación, distribución, o utilización de la energía eléctrica, cuyas tensiones nominales sean iguales o inferiores a 1000 voltios para corriente alterna y 1500 voltios para corrientes continuas.” Pliego de condiciones. 5 Controlador modular programable basado en procesadores de 32 bits y CAN bus 3. Condiciones facultativas. 3.1. Dirección. La dirección del montaje estará realizada en su totalidad por el ingeniero o proyectista o por otra persona que esta delegue atendiendo a la capacidad de dicha persona para realizar este trabajo. Una vez realizado el montaje, su utilización podrá ser realizada por cualquier persona con conocimientos suficientes demostrables sobre el proyecto, la tecnología en él implicada y su funcionamiento. En caso de avería o pérdida de datos por incorrecta utilización, el proyectista queda exento de culpa. Pliego de condiciones. 6 Controlador modular programable basado en procesadores de 32 bits y CAN bus 3.2. Libro de órdenes. El montaje de los elementos del proyecto se realizará atendiendo a los documentos y planos del mismo. Si es necesario realizar una modificación, se realizará bajo el pertinente consentimiento del propio ingeniero o proyectista. Pliego de condiciones. 7 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4. Condiciones de ejecución y montaje. 4.1 Condiciones de fabricación del circuito impreso. Tanto el circuito impreso de la placa principal, así como cada uno de los módulos de entradas y salidas deberá regirse por la norma UNE-621-80, en la cual se especifican los ensayos a los que debe ser sometido el circuito impreso, así como los métodos para la ejecución de dichos ensayos. Pliego de condiciones. 8 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.2 Pruebas y ensayos del montaje de la placa. Una vez montados todos los componentes y soldados a la placa, se procederá a efectuar los siguientes ensayos: 4.2.1 Prueba de alimentación. Para verificar el correcto funcionamiento de cada placa, se debe alimentar con -24÷48V. Se deberá comprobar que al conectar ambas tensiones no se produzca ningún tipo de fallo tal y como un cortocircuito entre las alimentaciones. Las placas chipKIT disponen de un LED de rojo el cual se ilumina cuando la placa está siendo alimentada correctamente. Si este LED se desvanece lentamente al realizar alguna conexión es el principal indicativo de que se está produciendo un cortocircuito y el limitador de corriente está realizando su trabajo. 4.2.2 Prueba de la placa. Para realizar el ensayo de la puesta en marcha de la placa, se deberá utilizar los ejemplos de chipKIT. Se hará uso del programa de ejemplo denominado “Blink” que hace parpadear intermitentemente cada segundo el LED que la placa de interfaz tiene conectada al pin 13, que se puede identificar en la placa por estar marcado con una LD. Este ejemplo es el más simple de todos, ideal para asegurar que si se produce algún fallo sea de hardware y no esté siendo enmascarado por un fallo de software. Si se quiere comercializar en la UE, será necesario que el sistema sea sometido a los ensayos pertinentes entre los que destaca la compatibilidad electromagnética, así como otros ensayos preceptivos. 4.2.3 Conexionado de los componentes. El conexionado se realiza siguiendo los esquemas que se encuentran en el CD, ubicados en la carpeta “Adjuntos del proyecto”. Pliego de condiciones. 9 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.3 Conexionado de sensores y actuadores. 4.3.1 Entradas digitales. Figura 1) Pliego de condiciones. Conexionado de sensores a los borneros de los módulos de entradas digitales. 10 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.3.2 Salidas digitales. Figura 2) Conexionado de actuadores tanto a las salidas digitales rápidas como a las salidas a triac. Pliego de condiciones. 11 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.3.3 Entradas analógicas. Pliego de condiciones. 12 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.4 Especificaciones técnicas de la parte hardware. 4.4.1 Placa principal. Figura 3) Simulación en 3D de la placa principal. El aspecto de la placa principal es el de la imagen inferior, en ella se pueden observar los distintos zócalos que albergarán los módulos de entradas/salidas, así como los diferentes componentes electrónicos que forman: • • La fuente de alimentación de los módulos. El hardware de las cinco salidas analógicas. El esquema electrónico de la fuente de alimentación es el siguiente: Figura 4) Circuito electrónico de la fuente de alimentación Esta fuente de alimentación convierte de +/-24 Vcc a +/-15Vcc. Características técnicas de esta fuente. Pliego de condiciones. 13 Controlador modular programable basado en procesadores de 32 bits y CAN bus FUENTE DE ALIMENTACION Tensión de entrada máximo Tensión de salida máximo Tensión de entrada mínimo Tensión de salida mínimo Intensidad de entrada máxima Corriente de pico a la entrada Frecuencia de trabajo Rango de temperaturas Precio Figura 5) 24v 15v -24v -15v 1.2 A 2.4 A 120 Hz -65÷150 ºC euros Especificaciones técnicas de la fuente de alimentación. Para las salidas analógicas se emplea un FOD8321, cuya limitación podría venir impuesta por su frecuencia de operación, ya que la función analogWrite() de chipKIT, genera una onda cuadrada estable (PWM) en un pin de salida analógica. La frecuencia de esta señal PWM será aproximadamente de 490Hz. El FOD8321 presenta una frecuencia de operación de 50 KHz muy superior a los 490 Hz del PWM que emplean las salidas analógicas de chipKIT, de tal manera que esté integrado puede dar cobertura a este tipo de salidas. 4.4.2 Módulo de entradas analógicas. El módulo de cuatro entradas analógicas presenta los siguientes bloques. Figura 6) Pliego de condiciones. Bloques que componen los módulos de entradas analógicas. 14 Controlador modular programable basado en procesadores de 32 bits y CAN bus Por lo tanto ante lo mostrado en la figura 1, se puede ver que los componentes electrónicos que condicionan los valores máximos y mínimos tanto de entrada como de salida en voltajes son los analog switch ADG 5413 y el AD7512DITQ. El primero de los componentes presenta las siguientes características: • • • • • • • • • Rango de tensiones de entrada cuando trabaja en modo simple 9v ÷ 40v. Intensidad máxima a la entrada de 30mA. Pico de intensidad a la entrada 278mA. Rango de temperaturas: o Operación -40 a 125 ºC o Almacenamiento -65ºC a 150ºC Frecuencias de trabajo a temperatura ambiente. Ton típico de 170 ns Ton máximo de 202 ns Toff típico de 120 ns Toff máximo de 140 ns El segundo componente presenta las siguientes características. • • • • • Detecta nivel alto a partir de 3v y el mínimo con 0.8v máximo. Rango de temperaturas entre -55 y 125 ºC Frecuencias de trabajo a temperatura ambiente. Ton máximo de 1 us. Toff máximo de 1 us. Los bloques de conversión intensidad-voltaje y el de reducción de voltaje, presentan como datos más interesantes sus rangos de temperaturas, ya que su respuesta dinámica es más rápida que la del ADG 5413 y por lo tanto es este elemento el que condiciona el ton y el toff del módulo. Así mismo los rangos de intensidad y voltaje de entrada son condicionados por el ADG 5413 y los de salida por el AD7512DITQ. De manera que tanto el RCV420 como el LM358 se mueven en un rango de -25 a 85 ºC. Con las situaciones más desfavorables este tipo de módulos presenta las siguientes características. Pliego de condiciones. 15 Controlador modular programable basado en procesadores de 32 bits y CAN bus ENTRADAS ANALÓGICAS Número de Entradas Rango de voltajes de entrada(V) Retraso de señal a ON Retraso de señal a OFF Voltaje a salida máximo de estado OFF Voltaje a salida mínimo de estado ON Intensidad máxima de entrada Rango de temperaturas Precio Figura 7) 4 9÷40 v 202 ns 140 ns 0.8 v 3.3 v 30 mA -25÷85 ºC 50 euros Especificaciones técnicas del módulo de entradas analógicas. 4.4.3 Módulo de entradas digitales. La electrónica bajo la que se ha diseñado los módulos de entradas digitales, reduce el voltaje que llega de los sensores y además, aísla al chipKIT de picos de tensión que podrían destruir la placa de desarrollo. Figura 8) Circuito electrónico que aísla y adapta niveles. Los rangos de tensión de entrada entre los que trabaja son los siguientes: • • Entre 0 y 5.1 voltios es un 0 digital. Entre 5.1 y 48 voltios es un 1 digital. Los rangos de tensión a la salida en función del valor a la entrada: • • Vin entre 0 y 5.1 voltios, a la salida aparece 1.2 voltios máximo Vin entre 5.1 y 48 voltios, a la salida aparece entre 2.7 y 5 voltios. El componente electrónico que más influye en las especificaciones dinámicas, es el optoacoplador 4N25 – 300E. Las características de este componente son: Pliego de condiciones. 16 Controlador modular programable basado en procesadores de 32 bits y CAN bus • • Tensión entre sus pines 1 y 2 con la que empieza a conducir: 1.5v Intensidad con la que empieza a conducir: 10 mA. • • • Intensidad máxima de entrada de 60mA. Tensión máxima entre sus pines 1 y 2 de 5v. Rango de temperaturas: o Operación -55 a 100 ºC o Almacenamiento -55ºC a 125ºC Frecuencias de trabajo a temperatura ambiente. Ton de 2us. Toff de 2us. • • • Por su parte el zener 1N4733A, que posee una tensión nominal zener de 5.1 voltios, posee un rango de temperaturas bastante amplio, en concreto, -65 a 200 ºC. ENTRADAS DIGITALES Número de Entradas 7 Rango de voltajes de entrada(V) 5.1÷48 v Retraso de señal a ON 2us Retraso de señal a OFF 2us Voltaje a salida máximo de estado OFF 1.2 v Voltaje a salida mínimo de estado ON 5v Intensidad máxima de entrada 60 mA Rango de temperaturas -65÷125 ºC Precio 9 euros Figura 9) Pliego de condiciones. Especificaciones técnicas del módulo de entradas analógicas. 17 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.4.4 Módulo de salidas digitales rápidas. La electrónica de los módulos de salidas digitales rápidas es muy sencilla, basándose únicamente en un convertidor de intensidad a voltaje, en concreto el FOD 8321. Figura 10) Circuito electrónico de las salidas digitales rápidas. Características de este componente electrónico. • • • • • • • • • Rango de tensiones recomendable de entrada 5v máximo. Rango de tensiones de salida 0 a 35v. Intensidad máxima de salida de 2.5 A. Intensidad media a la entrada 25mA. Rango de temperaturas: o Operación -40 a 125 ºC o Almacenamiento -40ºC a 100ºC Frecuencias de trabajo a temperatura ambiente. Frecuencia de operación 25KHz. Ton típico de 500 ns Toff típico de 500 ns SALIDAS DIGITALES RAPIDAS Número de Entradas Rango de voltajes de salida(V) Retraso de señal a ON Retraso de señal a OFF Voltaje de entrada máximo Intensidad máxima de entrada Rango de temperaturas Precio Figura 11) Pliego de condiciones. 6 0÷35 v 500 ns 500 ns 5v 25 mA -40÷100 ºC 7 euros Especificaciones técnicas del módulo de salidas digitales rápidas. 18 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.4.5 Módulo de salidas digitales a triac. Las interfaces de salidas digital con triac, están basadas en un diodo luminiscente y un triac sensible a la luz (optotriac), en concreto el MOC3021 que controla a un triac de mayor potencia. Figura 12) Circuito electrónico de las salidas digitales a triac. Características de este componente electrónico. • • • • • • • Rango de tensiones 115/230vac. Rango de tensiones pico hasta 400v. Rango de 1 lógico hasta 1A. Intensidad media a la entrada 25mA. Rango de temperaturas: o Almacenamiento -40ºC a 150ºC Niveles tensión de salida 1 lógico hasta 3Vp. Niveles tensión de salida 0 lógico hasta 1.8Vp SALIDAS DIGITALES a triac Número de Entradas Rango de voltajes de salida(V) Rango de 1 lógico hasta Intensidad media a la entrada Voltaje de salida máximo para 1 lógico Voltaje de salida máximo para 1 lógico Rango de temperaturas Precio Figura 13) Pliego de condiciones. 6 115÷230 Vac 1A 25mA 3Vp 1.8Vp -40÷150 ºC 19 euros Especificaciones técnicas del módulo de salidas digitales a triac. 19 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.4.6 chipKIT MAX32. chipKIT MAX32 Microcontrolador Memoria FLASH Voltaje de operación Frecuencia de operación Voltaje de entrada Voltaje de entrada máximo I/O pins Entradas analógicas Rango de voltaje de las entradas analógicas Intensidad de entrada a los pines Periféricos. Figura 14) Pliego de condiciones. PIC32MX795F512L 128K 3.3v 80 Mhz 7v a 15v 20v 83 16 De 0v a 3.3v +/-18mA Ethernet 2 controladores CAN USB 2.0 Especificaciones técnicas del chipKIT 32MAX 20 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.5 Especificaciones técnicas del CAN bus. La capa física del CAN bus es responsable de la transferencia de bits entre los distintos módulos que componen la red. Define aspectos como niveles de señal, codificación, sincronización y tiempos en que los bits se transfieren al bus. En la especificación original del CAN, la capa física no fue definida, permitiendo diferentes opciones para la elección del tipo de unidad y niveles eléctricos de transmisión. Las características de las señales eléctricas en el bus fueron establecidas mas tarde por el estándar ISO 11898. La especificación CiA (CAN in Automotion), complementó las definiciones respecto al medio físico y conectores. Los módulos conectados al bus interpretan dos niveles lógicos denominados: • • Dominante: la tensión diferencial (CAN_H - CAN_L) es del orden de 2.0vcon CAN_H = 3.5 v y CAN_L = 1.5v (nominales). Recesivo: la tensión diferencial (CAN_H - CAN_L) es del orden de 0v con CAN_H = CAN_L = 2.5v (nominales). Otra de las partes a destacar de esta comunicación, es la velocidad con la que se transmiten los mensajes a través de la red. Lo normal es tener buses de corta longitud, para así obtener un funcionamiento óptimo. Pero si por el contrario tenemos redes de largas longitudes eso irá mermando la velocidad de transmisión, debido a los retardos en la línea, impedancias, tolerancias de los osciladores, etc. Para atenuar estas carencias se colocan en los extremos del bus impedancias de carga para una mayor estabilidad. A continuación, se muestran los valores típicos (son orientativos) de transmisión según la longitud de los buses: Velocidad (Bit/seg) Tiempo de bit (microseg) Longitud máxima (metros) 1 Mbps 1 microseg 30 m 800 Kbps 1,25 microseg 50 m 500 Kbps 2 microseg 100 m 250 Kbps 4 microseg 250 m 125 Kbps 8 microseg 500 m 50 Kbps 20 microseg 1000 m 20 Kbps 50 microseg 2500 m 10 Kbps 100 microseg 5000 m Pliego de condiciones. 21 Controlador modular programable basado en procesadores de 32 bits y CAN bus El número máximo de módulos no está limitado por la especificación básica y depende de las características de los controladores CAN (SJA 1000). Las especificaciones de buses de campo lo limitan a 32 o 64. El bus CAN utiliza transmisión serie asíncrona, y codificación NRZ, utilizando para evitar problemas el bit stuffing, inserción de un bit complementario tras 5 bits con el mismo valor, y una cuidadosa temporización de bit. Todos los dispositivos en una red CAN tienen su propio reloj, generalmente un oscilador de cuarzo, que pueden tener periodos ligeramente diferentes. Pese a ello, la velocidad de transmisión se ajusta para que sea la misma en todos los dispositivos aunque tengan frecuencias de oscilador diferentes. Al no ser estas frecuencias totalmente estables, los dispositivos se resincronizan con la corriente de bits. El tiempo nominal de bit (Bit timing) se divide en cuatro fases: • • • Sincronización, donde se espera el flanco. Retardo de propagación, compensando el desfase debido a los retardos de propagación. Buffer 1 y 2, que son los tiempos antes y después del punto de muestreo nominal, variables para realizar la resincronización. Se utilizan medios de transmisión eléctricos y ópticos, aunque sería posible utilizar transmisión por red eléctrica y sin cables. Se suelen utilizar cables de par trenzado UTP o STP, con transmisión diferencial, y hay que tener en cuenta los parámetros del cable cuando las distancias son largas ya que afectan a la tasa de transferencia. La topología básica es en bus, incluyendo dos terminadores a los extremos, para evitar reflexiones en la señal. Otras topologías más complejas se pueden usar gracias al uso de repetidores, que añaden retardo a la propagación de la señal. De puentes, que conectan dos redes lógicas separadas a nivel de enlace. Solo retransmiten aquellos mensajes que no son locales, y de pasarelas, que conectan redes con diferentes protocolos de alto nivel, cuando estos están presentes. Pliego de condiciones. 22 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.5.1 MCP2551. Como ya se explicó en la memoria, un enlace CAN requiere entre otros elementos un controlador y un transceiver. El primero de ellos, lo aporta por partida doble el chipKIT 32MAX, sin embargo, debe ser el usuario el que acople el transceiver MCP 2551 para poder crear esta red de comunicación. Figura 15) Explicación grafica de toda la estructura hardware necesaria en cada uno de los nodos del CAN bus. Este componente tiene como principales características soportar la tasa de transferencia máxima de 1 Mbps que se especifica en el protocolo CANopen, implementar los requerimientos de la capa física ISO-11898, detección de fallos en la tierra y permite conectar un máximo de 112 Nodos al Bus. Figura 16) Pliego de condiciones. Patillaje del MCP 2551. 23 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 17) Diagrama de bloques del MCP2551 La descripción detallada de cada pin se muestra a continuación: • • • • • • • • Pin 1: TxD: Entrada digital que recibe los datos que van a ser enviados por el Bus. Pin 2: VSS: Referencia de tierra. Pin 3: VDD: Tensión de alimentación (+5V). Pin 4: RxD: Señal digital que transmite los datos recibidos por el bus. Pin 5: Vref: Tensión de referencia a la salida definida como Vdd/2. Pin 6: CANL: Parte baja de la señal diferencial del Bus. Pin 7: CANH: Parte alta de la señal diferencial del Bus. Pin 8: RS: Este pin permite seleccionar distintos modos de operación (High Speed, Slope Control, Standby) mediante una resistencia externa. Pliego de condiciones. 24 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.6 Instalación y uso de las aplicaciones Para el correcto funcionamiento de todo el sistema, se debe instalar el controlador de la placa de chipKIT en el caso de que sea necesario para su funcionamiento siguiendo las instrucciones que se encuentran en la página web de digilent. Además se debe tener instalado el paquete de office. La aplicación SCADA podría requerir algún tipo de .dll, si se da el caso, el usuario deberá descargarla y depositarla allí donde se indique. Para el manejo de la aplicación se puede consultar el Manual de Usuario. Pliego de condiciones. 25 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.7. Conservación Si para el montaje y puesta en marcha de los equipos y materiales que componen el hardware y software se siguen todas las indicaciones, recomendaciones y se cumplen las especificaciones que se dan en el pliego de condiciones, anexos y memoria, la vida útil de los elementos estará supeditada a aquella que de el fabricante siguiendo sus recomendaciones de mantenimiento. Pliego de condiciones. 26 Controlador modular programable basado en procesadores de 32 bits y CAN bus 4.8. Funcionamiento normal del equipo Una vez realizados todos los pasos anteriores, el equipo estará listo para funcionar permanentemente. El equipo no necesita de un mantenimiento riguroso, siempre que su uso se realice dentro de los límites especificados para cada componente. El deterioro de los materiales puede ser debido al propio envejecimiento del material con el paso del tiempo. Pliego de condiciones. 27 Controlador modular programable basado en procesadores de 32 bits y CAN bus 5. Condiciones de materiales y equipos. 5.1. Condiciones técnicas de los materiales. Lo materiales a emplear en este proyecto deberán cumplimentar todas y cada una de las normas descritas en el presente documento y podrán ser sometidos a diferentes pruebas y ensayos para asegurarse así de su correcto funcionamiento. En caso de no realizarse dichas pruebas y ensayos, el proyectista quedará exento de responsabilidad en el posible deterioro de los elementos durante su utilización. Estos materiales deben cumplir las especificaciones citadas para cada uno de ellos. Si son reemplazados por unos nuevos, estos deben tener las mismas características que los que reemplazan, inhibiéndose de cualquier responsabilidad por fallo si estos requisitos no son cumplidos. Pliego de condiciones. 28 Controlador modular programable basado en procesadores de 32 bits y CAN bus 5.2. Condiciones técnicas del material informático Los requisitos mínimos del sistema informático necesario para poder ejecutar el software diseñado, son los siguientes: • • • • • Ordenador personal con procesador Intel Pentium IV a 2.0 GHz o equivalente. 512 MB de memoria RAM DDR. Un puerto USB libre para la conexión de la placa de interfaz. 100 MB de espacio en disco duro para la instalación del software. Microsoft Windows XP Para la realización del presente proyecto se ha utilizado la siguiente configuración de hardware y software: • • • • • • • • Ordenador personal con sistema operativo MAC OS X Lion. Navegador de internet. Compilador de chipKIT Licencias Visual Basic. Microsoft Word 2010. Microsoft Visio 2010. Autocad 2010. Software gratuito de diseño de circuitos KiCAD, con el objetivo de que cualquiera pueda realizar cambios personales sobre las placas. Pliego de condiciones. 29 Controlador modular programable basado en procesadores de 32 bits y CAN bus 5.3. Condiciones técnicas de los circuitos impresos. Las placas de los circuitos impresos serán de fibra de vidrio y tendrán un espesor no inferior a 750 um. Siendo una vez atacadas con ácido las placas para crear las pistas, cubiertas con un barniz protector fotosensible de manera que el proceso no oculte las zonas donde se deberán realizar la soldadura de los componentes. Se deberá tener especial cuidado en el proceso de soldadura de ciertos componentes tales como los semiconductores, tratando de reducir en la medida de lo posible el tiempo del proceso, ya que debido a la sensibilidad de éstos a la temperatura se podrían producir daños por sobrecalentamiento. Pliego de condiciones. 30 Controlador modular programable basado en procesadores de 32 bits y CAN bus 5.4. Condiciones técnicas de los elementos pasivos. Las resistencias y condensadores tendrán unas tolerancias o márgenes de error permisibles. En el caso de las resistencias se considerará aceptable un error de hasta el 5%, siendo tolerable para los condensadores un valor del 20%. Pliego de condiciones. 31 Controlador modular programable basado en procesadores de 32 bits y CAN bus 5.5. Hardware utilización Open Source. Condiciones de El hardware open-source (de fuente abierta) comparte muchos de los principios y metodologías del software libre y de código abierto. En particular, los usuarios deben poder conocer en profundidad este hardware para comprender su funcionamiento, modificarlo y compartir dichos cambios. Para facilitar esta tarea, el CD que acompaña al proyecto contiene todos los ficheros originales (KiCAD) del diseño del hardware. En estos ficheros se permiten realizar trabajos personales y comerciales derivados, siempre que estos den crédito al autor, al director del proyecto y a la Universidad de la Rioja, y publiquen sus diseños bajo la misma licencia que Arduino: Creative Commons Attribution Share-Alike. El software también open-source. El código fuente para el ambiente Java se publica bajo la GPL y las bibliotecas C/C++ del microcontrolador bajo la LGPL. Los diseños de referencia de la placa Arduino se encuentran disponibles en la página hardware. Estos se encuentran bajo licencia Creative Commonos Attribution Share-Alike, por lo que se es libre de utilizar y adaptarlos para sus propias necesidades sin pedir permiso o pagar tarifa alguna. Si el usuario planea hacer algo de interés para la comunidad, se sugiere discutir tus ideas en el foro de desarrollo de hardware, para que los potenciales usuarios puedan aportar sus sugerencias. Si estás fabricando tu propia placa, ¡Inventa un nombre tu mismo! Esto permitirá a la gente identificarte con tus productos y ayudarte a construir tu propia marca. Se creativo: trata de sugerir lo que la gente hará con tu placa, o enfatizar en su forma o características, o tan solo escoge una palabra al azar que suene bien. "Arduino" es una marca registrada del equipo Arduino y no debe utilizarse para variantes no oficiales. Si estás interesado en que tu diseño se incluya junto con las placas oficiales, por favor consulta la sección Así que quieres hacerte un Arduino y ponte en contacto con el equipo Arduino. Ten en cuenta que aun cuando no intentamos restringir la utilización del sufijo "duino", su utilización tiende a espantar a los miembros italianos del equipo (al parecer suena horrible); sera mejor que lo evites. Utilizar una placa Arduino dentro de un producto comercial no requiere que reveles o liberes ninguna de las partes de su diseño. Derivar el diseño de un producto comercial a partir de los ficheros Eagle de la placa Arduino requiere que publiques los ficheros modificados bajo la misma licencia Creative Commons Attribution Share-Alike. Puedes fabricar y vender el producto resultante. Utilizar el núcleo y las bibliotecas de Arduino para el firmware de un producto comercial no requiere que publiques el código fuente para el firmware. Pliego de condiciones. 32 Controlador modular programable basado en procesadores de 32 bits y CAN bus La LGPL requiere que se liberen los ficheros objeto que permitan el re-enlace al firmware para versiones actualizadas de las bibliotecas y núcleo de Arduino. Cualquier modificación al núcleo y bibliotecas debe ser publicado bajo la LGPL. El código fuente del ambiente Arduino está cubierto bajo la GPL, que requiere que cualquier modificación sea de código libre bajo la misma licencia. No previene la venta de software derivado o su incorporación en productos comerciales. En todos los casos, los requerimientos exactos son determinados por la licencia aplicable. Adicionalmente, consulta las preguntas anteriores para información sobre la utilización del nombre "Arduino". Pliego de condiciones. 33 Controlador modular programable basado en procesadores de 32 bits y CAN bus 6. Manual de usuario. El presente manual está redactado para la versión 7.0 del software de supervisión SCADA. Pretende ser una guía útil para el usuario, que le enseñe a crear una aplicación a su medida. Para ello se realiza un ejemplo de cada uno de los controles posibles a crear. Junto a estos ejemplos, se muestra al usuario como poner en marcha la aplicación, además de mostrar la utilidad de todos los botones. Pliego de condiciones. 34 Controlador modular programable basado en procesadores de 32 bits y CAN bus La primera pantalla de la aplicación es una pantalla de presentación, en la que aparecen dos botones, los cuales rezan de la siguiente manera, “PROYECTO NUEVO” y “PROYECTO EXISTENTE”. El primero de los botones permite crear un SCADA desde cero, por su parte el segundo botón concede al usuario la posibilidad de partir de un panel SCADA ya realizado o en proceso de realización. Figura 18) Pantalla de presentación de la aplicación. Se va a partir del supuesto caso en que el usuario decide crear el proyecto desde cero, ya que la única diferencia que existe con respecto a la otra opción es la no necesidad de pasar por una pantalla intermedia, que se va a analizar a continuación. Si por el contrario, se pulsaría la opción de “PROYECTO EXISTENTE”, la aplicación direccionaría al usuario a la última de las pantallas, una vez ahí, este debería pulsar el botón cargar y seleccionar el archivo (.xlsx) que desea cargar. La siguiente pantalla a la que nos conducirá la aplicación será un formulario limpio, que recibirá al usuario con una ventana emergente, en la que se le pedirá que “delimite la zona en la que se desea colocar la imagen de fondo”. Figura 19) Asistente de creación del panel SCADA El primer paso a realizar en esta pantalla, será delimitar el área en la que se quiere colocar la imagen. Esto se consigue de la misma manera que cuando se quiere realizar una selección sobre cualquier aplicación Windows. Una vez que ya se le ha indicado a la aplicación el área en la que se quiere imprimir la imagen aparecerá de nuevo otra ventana emergente, que indicará al usuario cual es el paso siguiente, “Cargue la imagen de fondo”. Pliego de condiciones. 35 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 20) Asistente de creación del panel SCADA Pulsando sobre el botón cargar, se desplegará una pantalla emergente en la que se solicitará la ruta de la imagen de fondo. Figura 21) Solicita la ruta de la imagen de fondo. Una vez seleccionado el archivo .jpeg que se desea cargar, inmediatamente se colocará la imagen sobre el fondo. Figura 22) Pliego de condiciones. Estado de la aplicación una vez cargada la imagen de fondo. 36 Controlador modular programable basado en procesadores de 32 bits y CAN bus Se pulsa el botón siguiente para pasar a la siguiente página en la que se podrá llevar a cabo la creación de los diferentes elementos que permitirán al usuario interacturar con el proceso. Una vez situado en la tercera página, de nuevo aparecerá una ventana emergente en la que pedirá al usuario que “marque las zonas a controlar y edítelas”. Figura 23) El asistente indica al usuario que puede comenzar a crear las zonas de control. Figura 24) Asistente de cración del panel SCADA. De manera, que siguiendo las instrucciones del asistente la siguiente tarea será crear las diferentes zonas de control. Para ello, de nuevo se marca la zona sobre la que se desea situar el elemento de control, en caso de que el usuario no esté convencido con el resultado obtenido, posee un botón de “MODIFICAR” que le permite borrar esta zona y volver a crear otra. Una vez que el usuario decida que esa es la zona final sobre la que desea colocar el elemento de control, pulsará en la zona remarcada y le aparecerá una ventana emergente a modo de formulario, que deberá rellenar para seleccionar si desea crear un botón, un shape, un slider, una etiqueta o una progressbar. Pliego de condiciones. 37 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 25) Formulario para crear los diferentes elementos de control. En caso de querer crear un botón el formulario deberá ser rellenado de la siguiente manera. Figura 26) Formulario rellenado para crear un botón. De manera que estamos creando un control booleano, cuyo estado por defecto es apagado y que configura al pin 25 del módulo cero como salida. Así mismo, en la parte de la derecha del formulario, permite elegir si se quiere un botón de color (que se ponga en verde cuando el actuador este encendido o en rojo Pliego de condiciones. 38 Controlador modular programable basado en procesadores de 32 bits y CAN bus en caso contrario) o un botón animado en el que se alterne la imagen elegida en función de la posición en que se encuentre. Una vez cumplimentado el formulario, se pulsa el botón Agregar, con el fin de guardar este componente y posteriormente se pulsa Aceptar para posicionar el control sobre la imagen de fondo. Figura 27) Aplicación SCADA con el botón ya creado. Si el usuario necesita crear un slider o text, deberá cumplimentar el formulario de la siguiente manera. Figura 28) Formulario rellenado para crear un slider. De nuevo creamos un control, pero en este caso los datos con los que trabaja son de tipo real. Se le indicará por tanto cual será el valor máximo y Pliego de condiciones. 39 Controlador modular programable basado en procesadores de 32 bits y CAN bus mínimo con los que se quiere trabajar y la aplicación de manera interna (como ya se ha explicado anteriormente) llevará a cabo el escalado. Se configura como salida analógica el pin 10 de módulo 0 y se le indica a la aplicación que cuando ofrezca el valor en el que este posicionado el slider lo acompañe de la unidad de medida que se le indique. Una vez realizado el formulario se seguirán la operativa será la misma que la expuesta en el punto anterior. Figura 29) Aplicación SCADA con el slider ya creado. En caso de querer crear un text, el formulario se rellena de la misma manera que en el anterior punto a excepción de que hay que marcar el check “text Analógico”. Pliego de condiciones. 40 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 30) Figura 31) Formulario rellenado para crear un text. Panel SCADA con el text ya creado. Para crear una progressbar el proceso es el mismo que con el resto de controles, únicamente cambia la manera de rellenar el formulario. Pliego de condiciones. 41 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 32) Formulario rellenado para crear una progressbar. En este caso se ha seleccionado un indicador (pin 0 del módulo 0), que trabajará con datos reales (analógicos), cuyos valores oscilarán entre 0 y 30. En la parte derecha se puede seleccionar la forma de relleno, o bien vertical o bien horizontal, así como el color de fondo y el color de la barra de progreso. De nuevo se le da la posibilidad al usuario de definir las unidades con las que está trabajando y que acompañarán al dato que indica cual es el valor de la entrada analógico (esta valor ya está escalado, en este caso entre 0 y 30). Así mismo el usuario podrá utilizar el servicio de gestión de alarmas marcando el check “Generar alarma”. Los campos que debe de rellenar es el valor límite a partir del cual quiere que se genere la alarma y el texto que quiere que aparezca. Figura 33) Pliego de condiciones. Generación de alarma tras superar el valor límite. 42 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 34) Aplicación SCADA con la progressbar ya creada. El último elemento a crear, es un shape, que requiere rellenar el formulario como se expone a continuación. Figura 35) Formulario rellenado para crear un shape. Con este formulario se indica que el pin 35 del módulo 0 debe trabajar como entrada digital (Booleano, Indicador) y que parte de un estado por defecto de cero (en este caso de apertura total de la válvula). En la parte de la derecha existen dos zonas que pinchando sobre ellas dan la posibilidad al usuario de seleccionar la ruta de las imágenes que deben aparecer en función del estado de las entrada. Además se ha seleccionado que se genere una alarma cuando el sensor transmita cero voltios. Pliego de condiciones. 43 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 36) Generación de alarma. De nuevo se pulsa Agregar y Aceptar y se cierra la ventana emergente apareciendo el shape en la página principal. Figura 37) Aplicación SCADA con el shape ya creado. Una vez que se tienen creados todos los elementos de control necesarios, es una práctica recomendable guardar la aplicación, para ello se pulsa el botón “GUARDAR” y se presentara una ventana emergente que solicitara al usuario el nombre que quiere dar al archivo y donde lo quiere guardar, tras cumplimentar ambas acciones la aplicación SCADA ya estará salvada y esperando a que en algún otro momento pueda ser cargada. Pliego de condiciones. 44 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 38) Ventana emergente que solicita la ruta en la que se quiere guardar la aplicación. El siguiente paso es generar el código que necesita el chipKIT principal para poder gestionar tanto las comunicaciones con el PC como con los distintos módulos integrados en el bus CAN, así como la configuración de los pines de cada uno de los módulos que existen en la red CAN. Para ello, se pulsa el botón “PROGRAMAR chpKIT”, la ventana emergente que aparece es la siguiente. Figura 39) Ventana de programación y compilación chipKIT. *Antes de realizar esta acción el usuario debe asegurarse que está conectado el PC con la placa de desarrollo mediante el cable USB. Pliego de condiciones. 45 Controlador modular programable basado en procesadores de 32 bits y CAN bus Una vez que aparezca el entorno de programación de chipKIT, el usuario deberá buscar la zona en la que ponga “Escriba el código programa a partir de esta zona” y ahí programar su algoritmo de control. Cuando ya lo tenga programado deberá cargar el programa a la placa, mediante la pulsación del botón: Figura 40) Botón transferir. En ese momento se comenzará a transferir el programa, mientras se este realizando esta acción no se debe modificar ninguna línea de la programación. Figura 41) Programa transfiriéndose al chipKIT. Una vez se ha transferido el programa de manera correcta, se pulsa el botón “CONECTAR” que permitirá establecer las comunicaciones entre los diferentes módulos y el panel SCADA. Inmediatamente después de realizar esta acción, saltará un aviso en el que se comunicará el estado de todos los módulos de la red CAN y el usuario deberá decidir si desea continuar o por el contrario reiniciar la conexión. Figura 42) Pliego de condiciones. Estado de los módulos del bus CAN. 46 Controlador modular programable basado en procesadores de 32 bits y CAN bus Figura 43) Pliego de condiciones. La aplicación funcionando. 47 Controlador modular programable basado en procesadores de 32 bits y CAN bus 7. Disposición final. Las partes contratantes, dirección técnica y empresa, se ratifican en el contenido del siguiente pliego de condiciones, en el cual tiene igual validez, a todos los efectos, que una escritura pública, prometiendo fiel cumplimiento. Pliego de condiciones. 48 Controlador modular programable basado en procesadores de 32 bits y CAN bus Logroño, a 03 de Septiembre de 2013. Fdo: Alberto Martínez Inchusta. Pliego de condiciones. 49 Presupuesto Índice de Presupuesto. 1. Introducción. ................................................................................................................................ 1 2. Mediciones. ................................................................................................................................... 2 3. 4. 5. 2.1. Partida hardware del sistema. ...................................................................................... 2 2.2. Partida software de programación. ............................................................................ 3 2.3. Partida placas de desarrollo. ......................................................................................... 3 2.4. Partida mano de obra. ...................................................................................................... 3 Cuadros de precios unitarios. ................................................................................................ 4 3.1. Partida hardware del sistema. ...................................................................................... 4 3.2. Partida software de programación. ............................................................................ 5 3.3 Partida placas de desarrollo. ......................................................................................... 5 3.4. Partida mano de obra. ...................................................................................................... 5 Presupuesto parcial................................................................................................................... 6 4.1 Partida hardware del sistema. ...................................................................................... 6 4.2. Partida software de programación. ............................................................................ 8 4.3. Partida placas de desarrollo. ......................................................................................... 8 4.4. Partida mano de obra. ...................................................................................................... 8 Presupuesto total. .................................................................................................................... 10 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. 1. Introducción. A lo largo de esta sección se desglosara el presupuesto en base a: • • • • Mediciones: listado de todos los componentes y equipos necesarios, para realizar el autómata. Cuadro de precios unitarios: en este apartado se contemplarán los precios individuales de cada uno de los elementos necesarios. Precios parciales: en este apartado se contemplarán los precios parciales de cada una de las partidas. Precios totales: se calculará el presupuesto total al que asciende el presente proyecto. Presupuesto 1 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. 2. Mediciones. En este apartado se enumerarán los elementos utilizados en la red de abastecimiento de Améscoa Baja, así como la cantidad de cada uno de ellos. 2.1. Partida hardware del sistema. Módulo de siete entradas digitales. DESCRIPCIÓN Resistencia de diferentes valores Diodo led Diodo zener Optoacoplador 4N-25-300E Condensador UNIDADES 35 7 7 7 7 Módulo de seis salidas digitales rápidas. DESCRIPCIÓN Conversor corriente-tensión FOD 8321 Condensador UNIDADES 6 6 Módulo de seis salidas digitales a TRIAC. DESCRIPCIÓN Circuito opto-triac MOC3021 Diodo led Resistencias Condensadores TRIAC UNIDADES 6 6 24 12 6 Módulo de cuatro entradas analógicas. DESCRIPCIÓN Analog-switches ADG 5413 Analog-switches AD 7512DI Micro switches Resistencias LM 358 RCV 420 Presupuesto UNIDADES 4 2 4 12 4 4 2 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. Placa de potencia principal. DESCRIPCIÓN Zócalos Fuente de alimentación Pin-head Salidas analógicas Borneros Micro-switches UNIDADES 12 1 7 5 36 5 2.2. Partida software de programación. DESCRIPCIÓN Visual Basic Studio UNIDADES 1 2.3. Partida placas de desarrollo. DESCRIPCIÓN chipKIT MAX 32 UNIDADES 16 2.4. Partida mano de obra. DESCRIPCIÓN Análisis de la solución software. Análisis y diseño de la parte hardware. Depuración del programa en chipKIT 32MAX. Programación del panel SCADA. Programación de la comunicación serie y CAN bus. Documentación. Presupuesto UNIDADES (Horas) 5 60 40 110 80 50 3 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. 3. Cuadros de precios unitarios. En este apartado quedan reflejados los precios unitarios de todos los elementos necesarios para llevar a cabo el proyecto, y que junto con el estado de mediciones sirven para realizar el presupuesto. 3.1. Partida hardware del sistema. Módulo de siete entradas digitales. DESCRIPCIÓN Resistencia de diferentes valores Diodo led Diodo zener Optoacoplador 4N-25-300E Condensador PRECIO UD.(€) 0.1 0.15 0.1 0.3 0.15 Módulo de seis salidas digitales rápidas. PRECIO UD.(€) Conversor corriente-tensión FOD 8321 Condensador PRECIO UD.(€) 0.94 0.15 Módulo de seis salidas digitales a TRIAC. DESCRIPCIÓN Circuito opto-triac MOC3021 Diodo led Resistencias Condensadores TRIAC PRECIO UD.(€) 0.35 0.15 0.1 0.15 1.88 Módulo de cuatro entradas analógicas. DESCRIPCIÓN Analog-switches ADG 5413 Analog-switches AD 7512DI Micro switches Resistencias LM 358 RCV 420 Presupuesto PRECIO UD.(€) 1.8 1.75 0.55 12 0.13 7.4 4 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. Placa de potencia principal. DESCRIPCIÓN Zócalos Fuente de alimentación Pin-head Salidas analógicas Borneros Micro-switches PRECIO UD.(€) 0.55 1.65 0.55 1 0.75 0.55 3.2. Partida software de programación. DESCRIPCIÓN Visual basic studio PRECIO UD.(€) 1283.65 3.3 Partida placas de desarrollo. DESCRIPCIÓN chipKIT MAX 32 PRECIO UD.(€) 40 3.4. Partida mano de obra. DESCRIPCIÓN Análisis de la solución software. Análisis y diseño de la parte hardware. Depuración del programa en chipKIT 32MAX. Programación del panel SCADA. Programación de la comunicación serie y CAN bus. Documentación. Presupuesto PRECIO UD.(€) 30 30 30 30 30 30 5 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. 4. Presupuesto parcial. 4.1 Partida hardware del sistema. Módulo de siete entradas digitales. DESCRIPCIÓN Resistencia de diferentes valores Diodo led Diodo zener Optoacoplador 4N-25-300E Condensador PRECIO UD.(€) 0.1 0.15 0.1 0.3 0.15 UNIDADES PRECIO (€) 35 7 7 7 7 3.5 1.05 0.7 2.1 1.05 Módulo de seis salidas digitales rápidas. DESCRIPCIÓN Conversor corriente-tensión FOD 8321 Condensador PRECIO UNIDADES UD.(€) 0.94 6 0.15 6 PRECIO (€) 5.64 0.9 Módulo de seis salidas digitales a TRIAC. DESCRIPCIÓN Circuito opto-triac MOC3021 Diodo led Resistencias Condensadores TRIAC Presupuesto PRECIO UNIDADES UD.(€) 0.35 6 0.15 6 0.1 24 0.15 12 1.88 6 PRECIO (€) 2.1 0.9 2.4 1.8 11.28 6 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. Módulo de cuatro entradas analógicas. DESCRIPCIÓN Analog-switches ADG 5413 Analog-switches AD 7512DI Micro switches Resistencias LM 358 RCV 420 PRECIO UD.(€) 1.8 1.75 0.55 0.1 0.13 7.4 UNIDADES PRECIO (€) 4 2 4 12 4 4 7.2 8.75 2.2 1.2 0.52 29.6 PRECIO UD.(€) 0.55 1.65 0.55 1 0.75 0.55 UNIDADES PRECIO (€) 12 1 7 5 36 5 6.6 1.65 3.85 5 27 2.75 Placa de potencia principal. DESCRIPCIÓN Zócalos Fuente de alimentación Pin-head Salidas analógicas Borneros Micro-switches PARTIDA Partida de hardware del sistema. TOTAL PARTIDA 129.74 Asciende la partida de hardware del sistema a ciento veinte nueve con setenta y cuatro. Presupuesto 7 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. 4.2. Partida software de programación. DESCRIPCIÓN PRECIO UNIDADES UD.(€) 1283.65 1 Visual basic studio PARTIDA Partida software de programación PRECIO (€) 1283.65 TOTAL PARTIDA 1283.65 Asciende la partida de software de programación a mil doscientos ocheinta y tres con seseinta y cinco. 4.3. Partida placas de desarrollo. DESCRIPCIÓN PRECIO UNIDADES PRECIO UD.(€) (€) 40 1 40 chipKIT MAX 32 PARTIDA Partida placas de desarrollo TOTAL PARTIDA 40 Asciende la partida de placas de desarrollo a cuarenta euros. 4.4. Partida mano de obra. DESCRIPCIÓN Análisis de la solución software. Análisis y diseño de la parte hardware. Depuración del programa en chipKIT 32MAX. Programación del panel SCADA. Programación de la comunicación serie y CAN bus. Documentación. Presupuesto PRECIO UD.(€) UNIDADES (Horas) PRECIO (€) 30 30 5 60 150 1800 30 40 1200 30 30 110 80 3300 2400 30 50 1500 8 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. PARTIDA Partida mano de obra. TOTAL PARTIDA 10350 Asciende la partida de mano de obra a diez mil trescientos cincuenta. Presupuesto 9 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. 5. Presupuesto total. PARTIDA Partida de hardware del sistema. Partida software de programación Partida placas de desarrollo Partida mano de obra. PRESUPUESTO (€) 129.74 1283.65 40 10350 TOTAL PARCIAL 11803.39 I.V.A. 21% sobre total parcial. 2478.71 TOTAL 14282.10 Asciende el precio total del proyecto a la mencionada cantidad de, CATORCE MIL DOSCIENTOS OCHEINTA Y DOS CON DIEZ EUROS. *Los precios con los que se calcula este presupuesto son del 2013, si el proyecto no es desarrollado en los dos años siguientes, los precios podrían ser otros. *Los precios de los componentes electrónicos, están supeditados a la compra de cien unidades. *El cálculo de la partida de hardware, está realizado para un módulo de cada tipo. Presupuesto 10 Telecontrol de la Red de Abastecimiento de Améscoa Baja: Mediante tecnología WiMAX. Logroño, a 3 de Septiembre de 2013. Fdo: Alberto Martínez Inchusta. Presupuesto 11 UNIVERSIDAD DE LA RIOJA MANUAL DE USUARIO DEL PANEL SCADA v7.0 ALBERTO MARTINEZ INCHUSTA 2013 El presente manual está redactado para la versión 7.0 del software de supervisión SCADA. Pretende ser una guía útil para el usuario, que le enseñe a crear una aplicación a su medida. Para ello se realiza un ejemplo de cada uno de los controles posibles a crear. Junto a estos ejemplos, se muestra al usuario como poner en marcha la aplicación, además de mostrar la utilidad de todos los botones. Manual de usuario del panel SCADA. 1 La primera pantalla de la aplicación es una pantalla de presentación, en la que aparecen dos botones, los cuales rezan de la siguiente manera, “PROYECTO NUEVO” y “PROYECTO EXISTENTE”. El primero de los botones permite crear un SCADA desde cero, por su parte el segundo botón concede al usuario la posibilidad de partir de un panel SCADA ya realizado o en proceso de realización. Figura 1) Pantalla de presentación de la aplicación. Se va a partir del supuesto caso en que el usuario decide crear el proyecto desde cero, ya que la única diferencia que existe con respecto a la otra opción es la no necesidad de pasar por una pantalla intermedia, que se va a analizar a continuación. Si por el contrario, se pulsaría la opción de “PROYECTO EXISTENTE”, la aplicación direccionaría al usuario a la última de las pantallas, una vez ahí, este debería pulsar el botón cargar y seleccionar el archivo (.xlsx) que desea cargar. La siguiente pantalla a la que nos conducirá la aplicación será un formulario limpio, que recibirá al usuario con una ventana emergente, en la que se le pedirá que “delimite la zona en la que se desea colocar la imagen de fondo”. Figura 2) Asistente de creación del panel SCADA El primer paso a realizar en esta pantalla, será delimitar el área en la que se quiere colocar la imagen. Esto se consigue de la misma manera que cuando se quiere realizar una selección sobre cualquier aplicación Windows. Una vez que ya se le ha indicado a la aplicación el área en la que se quiere imprimir la imagen aparecerá de nuevo otra ventana emergente, que indicará al usuario cual es el paso siguiente, “Cargue la imagen de fondo”. Manual de usuario del panel SCADA. 2 Figura 3) Asistente de creación del panel SCADA Pulsando sobre el botón cargar, se desplegará una pantalla emergente en la que se solicitará la ruta de la imagen de fondo. Figura 4) Solicita la ruta de la imagen de fondo. Una vez seleccionado el archivo .jpeg que se desea cargar, inmediatamente se colocará la imagen sobre el fondo. Figura 5) Estado de la aplicación una vez cargada la imagen de fondo. Manual de usuario del panel SCADA. 3 Se pulsa el botón siguiente para pasar a la siguiente página en la que se podrá llevar a cabo la creación de los diferentes elementos que permitirán al usuario interacturar con el proceso. Una vez situado en la tercera página, de nuevo aparecerá una ventana emergente en la que pedirá al usuario que “marque las zonas a controlar y edítelas”. Figura 6) El asistente indica al usuario que puede comenzar a crear las zonas de control. Figura 7) Asistente de cración del panel SCADA. De manera, que siguiendo las instrucciones del asistente la siguiente tarea será crear las diferentes zonas de control. Para ello, de nuevo se marca la zona sobre la que se desea situar el elemento de control, en caso de que el usuario no esté convencido con el resultado obtenido, posee un botón de “MODIFICAR” que le permite borrar esta zona y volver a crear otra. Una vez que el usuario decida que esa es la zona final sobre la que desea colocar el elemento de control, pulsará en la zona remarcada y le aparecerá una ventana emergente a modo de formulario, que deberá rellenar para seleccionar si desea crear un botón, un shape, un slider, una etiqueta o una progressbar. Manual de usuario del panel SCADA. 4 Figura 8) Formulario para crear los diferentes elementos de control. En caso de querer crear un botón el formulario deberá ser rellenado de la siguiente manera. Figura 9) Formulario rellenado para crear un botón. De manera que estamos creando un control booleano, cuyo estado por defecto es apagado y que configura al pin 25 del módulo cero como salida. Así mismo, en la parte de la derecha del formulario, permite elegir si se quiere un botón de color (que se ponga en verde cuando el actuador este encendido o en rojo en caso contrario) o un botón animado en el que se alterne la imagen elegida en función de la posición en que se encuentre. Manual de usuario del panel SCADA. 5 Una vez cumplimentado el formulario, se pulsa el botón Agregar, con el fin de guardar este componente y posteriormente se pulsa Aceptar para posicionar el control sobre la imagen de fondo. Figura 10) Aplicación SCADA con el botón ya creado. Si el usuario necesita crear un slider o text, deberá cumplimentar el formulario de la siguiente manera. Figura 11) Formulario rellenado para crear un slider. De nuevo creamos un control, pero en este caso los datos con los que trabaja son de tipo real. Se le indicará por tanto cual será el valor máximo y mínimo con los que se quiere trabajar y la aplicación de manera interna (como ya se ha explicado anteriormente) llevará a cabo el escalado. Se configura como salida analógica el pin 10 de módulo 0 y se le indica a la aplicación que cuando ofrezca el valor en el que este posicionado el slider lo acompañe de la unidad de medida que se le indique. Manual de usuario del panel SCADA. 6 Una vez realizado el formulario se seguirán la operativa será la misma que la expuesta en el punto anterior. Figura 12) Aplicación SCADA con el slider ya creado. En caso de querer crear un text, el formulario se rellena de la misma manera que en el anterior punto a excepción de que hay que marcar el check “text Analógico”. Figura 13) Manual de usuario del panel SCADA. Formulario rellenado para crear un text. 7 Figura 14) Panel SCADA con el text ya creado. Para crear una progressbar el proceso es el mismo que con el resto de controles, únicamente cambia la manera de rellenar el formulario. Figura 15) Formulario rellenado para crear una progressbar. En este caso se ha seleccionado un indicador (pin 0 del módulo 0), que trabajará con datos reales (analógicos), cuyos valores oscilarán entre 0 y 30. En la parte derecha se puede seleccionar la forma de relleno, o bien vertical o bien horizontal, así como el color de fondo y el color de la barra de progreso. De nuevo se le da la posibilidad al usuario de definir las unidades con las que está trabajando y que acompañarán al dato que indica cual es el valor de la entrada analógico (esta valor ya está escalado, en este caso entre 0 y 30). Manual de usuario del panel SCADA. 8 Así mismo el usuario podrá utilizar el servicio de gestión de alarmas marcando el check “Generar alarma”. Los campos que debe de rellenar es el valor límite a partir del cual quiere que se genere la alarma y el texto que quiere que aparezca. Figura 16) Generación de alarma tras superar el valor límite. Figura 17) Aplicación SCADA con la progressbar ya creada. El último elemento a crear, es un shape, que requiere rellenar el formulario como se expone a continuación. Figura 18) Formulario rellenado para crear un shape. Con este formulario se indica que el pin 35 del módulo 0 debe trabajar como entrada digital (Booleano, Indicador) y que parte de un estado por defecto de cero (en Manual de usuario del panel SCADA. 9 este caso de apertura total de la válvula). En la parte de la derecha existen dos zonas que pinchando sobre ellas dan la posibilidad al usuario de seleccionar la ruta de las imágenes que deben aparecer en función del estado de las entrada. Además se ha seleccionado que se genere una alarma cuando el sensor transmita cero voltios. Figura 19) Generación de alarma. De nuevo se pulsa Agregar y Aceptar y se cierra la ventana emergente apareciendo el shape en la página principal. Figura 20) Aplicación SCADA con el shape ya creado. Una vez que se tienen creados todos los elementos de control necesarios, es una práctica recomendable guardar la aplicación, para ello se pulsa el botón “GUARDAR” y se presentara una ventana emergente que solicitara al usuario el nombre que quiere dar al archivo y donde lo quiere guardar, tras cumplimentar ambas acciones la aplicación SCADA ya estará salvada y esperando a que en algún otro momento pueda ser cargada. Manual de usuario del panel SCADA. 10 Figura 21) Ventana emergente que solicita la ruta en la que se quiere guardar la aplicación. El siguiente paso es generar el código que necesita el chipKIT principal para poder gestionar tanto las comunicaciones con el PC como con los distintos módulos integrados en el bus CAN, así como la configuración de los pines de cada uno de los módulos que existen en la red CAN. Para ello, se pulsa el botón “PROGRAMAR chpKIT”, la ventana emergente que aparece es la siguiente. Figura 22) Ventana de programación y compilación chipKIT. *Antes de realizar esta acción el usuario debe asegurarse que está conectado el PC con la placa de desarrollo mediante el cable USB. Manual de usuario del panel SCADA. 11 Una vez que aparezca el entorno de programación de chipKIT, el usuario deberá buscar la zona en la que ponga “Escriba el código programa a partir de esta zona” y ahí programar su algoritmo de control. Cuando ya lo tenga programado deberá cargar el programa a la placa, mediante la pulsación del botón: Figura 23) Botón transferir. En ese momento se comenzará a transferir el programa, mientras se este realizando esta acción no se debe modificar ninguna línea de la programación. Figura 24) Programa transfiriéndose al chipKIT. Una vez se ha transferido el programa de manera correcta, se pulsa el botón “CONECTAR” que permitirá establecer las comunicaciones entre los diferentes módulos y el panel SCADA. Inmediatamente después de realizar esta acción, saltará un aviso en el que se comunicará el estado de todos los módulos de la red CAN y el usuario deberá decidir si desea continuar o por el contrario reiniciar la conexión. Figura 25) Manual de usuario del panel SCADA. Estado de los módulos del bus CAN. 12 Figura 26) Manual de usuario del panel SCADA. La aplicación funcionando. 13