Autor:: Provided by Repositorio Universidad de Zaragoza
Autor:: Provided by Repositorio Universidad de Zaragoza
Autor:: Provided by Repositorio Universidad de Zaragoza
Autor:
Óscar Clemente Pedrico
Director:
Fernando Tricas Lamana
Ponente:
José Luis Briz Velasco
Resumen
2
Índice general
1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1. Objetivo y alcance del proyecto . . . . . . . . . . . . . . . 7
1.2. Contexto de desarrollo . . . . . . . . . . . . . . . . . . . . 7
1.3. Métodos y técnicas . . . . . . . . . . . . . . . . . . . . . . 7
1.4. Tecnologı́as empleadas . . . . . . . . . . . . . . . . . . . . 8
1.5. Herramientas empleadas . . . . . . . . . . . . . . . . . . . 8
2. Análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3. Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1. Arquitectura del sistema . . . . . . . . . . . . . . . . . . . 10
4. Estudio del protocolo DNP3 . . . . . . . . . . . . . . . . . . . . . 12
4.1. Caracterı́sticas del protocolo DNP3 . . . . . . . . . . . . . 12
4.2. Metodologı́a del análisis . . . . . . . . . . . . . . . . . . . 12
4.3. Estructura del protocolo . . . . . . . . . . . . . . . . . . . 12
4.3.1. Objetos . . . . . . . . . . . . . . . . . . . . . . . 14
4.3.2. Capa de enlace . . . . . . . . . . . . . . . . . . . 14
4.3.3. Capa de transporte . . . . . . . . . . . . . . . . 15
4.3.4. Capa de aplicación . . . . . . . . . . . . . . . . . 16
5. Implementación del protocolo DNP3 . . . . . . . . . . . . . . . . 18
5.1. Librerı́a de configuración . . . . . . . . . . . . . . . . . . 19
5.2. Criptografı́a TLS . . . . . . . . . . . . . . . . . . . . . . . 20
5.3. Ejecutivo cı́clico . . . . . . . . . . . . . . . . . . . . . . . 20
5.4. Script IFTTT . . . . . . . . . . . . . . . . . . . . . . . . . 23
6. Sensores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6.1. Arduino Due . . . . . . . . . . . . . . . . . . . . . . . . . 24
6.2. Caudalı́metro . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.3. Anemómetro . . . . . . . . . . . . . . . . . . . . . . . . . 26
6.4. Detector de movimiento . . . . . . . . . . . . . . . . . . . 26
6.5. Sensor de humedad y temperatura . . . . . . . . . . . . . 26
6.6. Sensor de ultrasonidos . . . . . . . . . . . . . . . . . . . . 27
7. Gestión del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.1. Planificación . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.2. Tiempo dedicado . . . . . . . . . . . . . . . . . . . . . . . 28
7.3. Herramientas de gestión . . . . . . . . . . . . . . . . . . . 28
8. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
8.1. Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3
8.2. Lecciones aprendidas . . . . . . . . . . . . . . . . . . . . . 30
8.3. Conclusión personal . . . . . . . . . . . . . . . . . . . . . 30
8.4. Futuro del proyecto . . . . . . . . . . . . . . . . . . . . . 31
Bibliografı́a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Anexos 33
1. Anexo 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4
Índice de figuras
5
Índice de cuadros
1. Objetos implementados . . . . . . . . . . . . . . . . . . . . . . . 15
2. Tareas del ejecutivo cı́clico en Pago de Aylés . . . . . . . . . . . 23
3. Requisitos funcionales . . . . . . . . . . . . . . . . . . . . . . . . 34
6
1. Introducción
1.1. Objetivo y alcance del proyecto
El objetivo propuesto para este proyecto consiste en crear una red de SCADAs
que monitorizan las variables dadas por sensores y dispositivos, en la que toda
la información se comunica mediante el uso del protocolo DNP3 y criptografı́a
TLS por parte de los clientes y servidores . Las variables llegan a los clientes
DNP3, y éstos se las comunican a los servidores DNP3 que monitorizan cada
variable. El servidor se encarga de verificar que las variables permanecen dentro
de un rango definido mediante tecnologı́a basada en IFTTT. En caso de que el
valor se salga fuera del rango, el servidor actuará y usando un mensaje DNP3
se comunicará con el cliente adecuado y modificará su comportamiento para
corregir los valores.
Los clientes y servidores DNP3 se despliegan sobre dispositivos ARM Gu-
ruPlug que funcionarán como cliente o servidor dependiendo de la necesidad.
Las variables llegan a los clientes a través de unos sensores que captan la in-
formación, se comunican con una placa Arduino y ésta se los pasa al ARM
GuruPlug.
7
Se busca que cada tarea se base en lo realizado en la anterior para formar
un desarrollo incremental y también mantener el periodo de realización de cada
tarea en torno a dos semanas, tiempo suficiente para que una tarea sea intere-
sante y consistente pero también suficientemente pequeño como para que la
tarea no sea difı́cil de abordar y demasiado compleja.
Cada una de las tareas se encuentra dentro de los siguientes rangos:
8
Buildroot: Es una herramienta que facilita la generación de entornos y
compiladores para compilación cruzada [1]. En el caso de este TFG se ha
necesitado generar un compilador cruzado para la CPU ARM9E del ARM
GuruPlug.
Wireshark: Es un analizador de paquetes de red que permite comprobar el
protocolo de cada paquete, su identidad y verificar la correcta estructura
de este.
OpenDNP3: Simulador del protocolo DNP3 que permite generar tramas
del protocolo, para en este caso comprobar que la implementación desar-
rollada cumple el estándar DNP3.
9
Figura 1: Diagrama de componentes y conectores.
2. Análisis
La fase de análisis determina el alcance del proyecto y las funcionalidades
que va a presentar el sistema una vez completado. En el anexo se encuentra una
tabla con los requisitos funcionales (Anexo 1).
3. Diseño
Conociendo las funcionalidades que va a cumplir el proyecto se procedió al
diseño de alto nivel de la arquitectura y la organización del sistema.
10
Figura 2: Diagrama de despliegue.
correctos y en caso de que no lo sean responde al cliente con una orden que
permita corregir los valores.
El diagrama de despliegue muestra el despliegue fı́sico de cada una de las
partes que componen el proyecto incluyendo algunos de los sensores utilizados
(Figura 2).
11
4. Estudio del protocolo DNP3
4.1. Caracterı́sticas del protocolo DNP3
DNP3 (Distributed Network Protocol 3) es un protocolo industrial para co-
municaciones entre equipos inteligentes, estaciones controladoras y componentes
de sistemas SCADA. Es un protocolo ampliamente utilizado en el sector eléctrico
y de tratamiento de lı́quidos, de gran difusión en toda América.
Los sistemas que usan este protocolo se diferencian normalmente en dos: el
máster y los outstation.
El máster es la máquina encargada de recopilar toda la información de las
diferentes outstations y es usada por los equipos de gestión para visualizar
la información, agruparla, analizarla o reenviarla a otro sistema.
El outstation o RTU (Remote Terminal Unit) es la máquina encargada
de coger los datos directamente del sistema eléctrico o de agua, transfor-
mar estos datos a datos DNP3 correctos, empaquetarlos en el mensaje y
enviarlos al máster.
El protocolo DNP3 presenta importantes funcionalidades que lo hacen más
robusto, eficiente y compatible que otros protocolos más antiguos pero también
hacen que sea más complejo [2].
12
Figura 3: Composición de tramas DNP3.
cumple con todas las especificaciones del modelo OSI y a dı́a de hoy se suele
implementar sobre TCP/IP.
La estructura en capas sigue el siguiente esquema (Figura 3):
13
Figura 4: Object header.
Añadir la cabecera del nivel de enlace. Las tramas ya están listas para ser
enviadas.
4.3.1. Objetos
Los datos que se envı́an a través de mensajes DNP3 están encapsulados
en el interior de objetos. Un objeto es un conjunto de datos que mantienen
caracterı́sticas comunes y están identificados por el Object Type Field (Figura
4).
Object Type Field: (2 bytes) El primer byte indica de que grupo forma
parte el objeto y el segundo byte, la variación de este.
Qualifier Field: (1 byte) Indica la estructura de los datos que llegan. En
nuestro caso para simplificar, solo usaremos el valor 0x07 que establece
que el Range Field es de un solo byte y que indica el número de objetos
de forma numeral (otras formas de hacerlo son con rangos o con ı́ndices).
Range Field: (1-2 bytes) Indica el número de objetos en este grupo.
14
Cuadro 1: Objetos implementados
Objeto Variación Descripción Tamaño
1 1 Binary Input 1 bit
1 2 Binary Input Status 1 byte
10 1 Binary Output 1 bit
10 2 Binary Output Status 1 byte
30 1 32 bit Analog Input Quality 5 bytes
30 2 16 bit Analog Input Quality 3 bytes
30 3 32 bit Analog Input 4 bytes
30 4 16 bit Analog Input 5 bytes
40 1 32 bit Analog Output Status 5 bytes
40 2 16 bit Analog Output Status 3 bytes
40 3 32 bit Analog Output 4 bytes
40 4 16 bit Analog Output 2 bytes
70 1 File Object Identifier 1 byte
100 1 Short Floating Point 1 byte
100 2 Long Floating Point 2 bytes
100 2 Extended Floating Point 4 bytes
110 1 Octet String 1 byte
15
Figura 7: Transport layer header.
Application Control: (1 byte) que está compuesto por los siguientes sub-
campos.
• FIN: (1 bit) Bit a 1 indica que el segmento actual es el último de
todos los enviados.
• FIR: (1 bit) Bit a 1 indica que el segmento actual es el primero de
todos los enviados.
• Confirmed: (1 bit) Indica si el segmento ha de ser confirmado, es decir
si el receptor del mensaje a de mandar un mensaje DNP3 de vuelta
mostrando que lo ha recibido
• Unsolicited: (1 bit) Indica si el segmento que se envı́a no ha sido
pedido por el máster si no que se ha enviado de forma esporádica.
16
• Sequence: (4 bits) Indica el número de orden del segmento enviado.
Function Code: (1 byte) Código de la función.
Internal Indications: (2 bytes) Código usado solo en la respuesta del outsta-
tion al máster con diferentes bits que indican el estado actual del sistema
(Problemas, sincronización, overflow, configuración corrupta...).
Object Type Field: (2 bytes) El primer byte indica de que grupo forma
parte el objeto y el segundo byte, la variación de este.
Qualifier Field: (1 byte) Indica la estructura de los datos que llegan. En
nuestro caso para simplificar, solo usaremos el valor 0x07 que indica que el
Range Field sea de un solo byte e indique el número de objetos de forma
numeral (otras formas de hacerlo son con rangos o con ı́ndices).
Range Field: (1-2 bytes) Indica el número de objetos en este grupo.
A partir de aquı́ se colocan los datos. El tamaño de los datos enviados de-
pende del Object Type y del Range Field. Una vez acaba el objeto actual, se
transmite el siguiente, comenzando con los tres campos anteriores. Conviene
notar que cada 16 bytes de la capa de aplicación hay que insertar 2 bytes de
CRC, lo que incluye también a las cabeceras de la capa de aplicación. Ha de
haber también un CRC final aunque el tamaño de los datos previos sea menor
a 16 bytes.
17
Figura 10: Diagrama de clases de la implementación DNP3.
18
El outstation inicia el ejecutivo cı́clico y recibe los valores de los sensores
ya encapsulados en objetos DNP3. El siguiente paso es dividir los datos de los
sensores si superan el tamaño máximo de la capa de aplicación. A continuación,
se incluye la cabecera de la capa de aplicación y se comprueba que no sobrepasa
el tamaño máximo de la capa de transporte, si lo supera se divide de nuevo.
Tras asegurar que los segmentos tienen un tamaño valido, se añade la cabecera
de la capa de transporte a todos ellos. Tanto la cabecera de aplicación como
la de transporte contienen valores que informan del orden del segmento para la
correcta recepción de la trama completa.
En este momento el outstation tiene preparada una trama a nivel de trans-
porte que aún requiere cambios. Cada 16 bytes se calcula un CRC DNP de 16
bits y se insertan estos dos bytes después de los 16 bytes. Por último se añade
la cabecera de enlace dejando el mensaje listo para ser enviado hacia el máster.
El máster por su parte hace lo mismo que el outstation pero en orden inverso.
Elimina la cabecera de enlace y los CRC, comprobando que estos últimos sean
correctos. En caso de no serlos se deniega el mensaje completo y se espera a que
llegue un nuevo mensaje. Se elimina la cabecera de transporte pero con atención
a los valores de secuencia que contienen, que ayudan para reensamblar la trama
de objetos en el orden original. Lo mismo ocurre con la cabecera de aplicación.
El resultado final es una trama de objetos DNP3. El máster llama a la función
que descompone los objetos y los envı́a al script IFTT para ser analizados, en
caso de que algún valor no entre dentro de los rangos aceptables se enviará al
outstation una respuesta DNP3 con órdenes para los sensores.
19
Figura 11: Establecimiento de una sesión TLS.
20
Algoritmo 1: Algoritmo ejecutivo cı́clico.
1 function task cycle(mcd, mcm, timecycle, tasklist, dnp3period)
2 step = mcm;
3 while always do
4 timeleft = time compare(timecycle);
5 if !is time zero(timeleft) then
6 clock nanosleep(CLOCK MONOTONIC, TIMER ABSTIME,
timeleft, NULL);
7 end
8 for i in sensorlist.length do
9 if step % sensorlist[i].period == 0 then
10 get sensor data(sensorlist[i].id, message);
11 end
12 end
13 if step % dnp3period == 0 then
14 send dnp3(message);
15 receive dnp3 response();
16 end
17 step -= mcd;
18 if step ≤ 0 then
19 step = mcm;
20 end
21 add seconds(timecycle, mcd);
22 end
Las tareas de tipo sensor se encargan de leer los valores de un sensor realizan-
do una comunicación Modbus con la placa Arduino que, una vez ha identificado
la petición que ha recibido, selecciona el valor y lo devuelve al outstation donde
la propia tarea lo encapsula en un objeto DNP3. Todas tienen el mismo nivel
de prioridad y se ejecutan en el orden que han sido declaradas en el fichero de
configuración. Hay dos ficheros de configuración que son utilizados para poder
editar y añadir nuevas tareas de tipo sensor.
El primer fichero de configuración, sensors.cfg, contiene todos los sen-
sores que se han implementado y que pueden o no ser usados en el sistema,
además se encarga de definir el tipo de sensor del que se trata con una descrip-
ción y con el tipo de objeto DNP3 en el que se va a encapsular. El segundo,
sensors used.cfg, determina los sensores que se van a usar en el sistema actual
y el periodo de la tarea que lee el valor del sensor.
El otro tipo de tareas son las que denominamos tareas de comunicación.
Constan de dos tareas ya definidas, la escritura de los mensajes DNP3 que van
a ser enviados al máster y la lectura de las respuestas que llegan del máster.
Estas dos tareas tienen su periodo definido en el fichero de configuración del
proceso outstation.
21
El ejecutivo cı́clico encargado de organizar y ejecutar cada una de las tareas
cumpliendo sus periodos es un ejecutivo soft real-time, por lo que se aligeran
las constricciones de tiempo. Se permite que alguna tarea sobrepase su deadline
ya que no es un sistema crı́tico. Como reloj se usa CLOCK MONOTONIC para las
mediciones de tiempo, es un reloj absoluto que garantiza su valor linealmente
incremental durante casi 50 años.
El ejecutivo usa el Algoritmo 1. Los valores mcd y mcm representan el máxi-
mo común divisor y el mı́nimo común múltiplo de los periodos de las tareas que
se han seleccionado en el fichero de configuración sensors used.cfg. Tanto mcd
como mcm, al existir las restricciones establecidas en el fichero de configuración,
tendrán siempre un valor de segundos. A continuación se describen funciones
relevantes del ejecutivo.
clock gettime(clockid t clk, struct timespec *t): Asigna el valor del reloj al
struct timespec *t. En este ejecutivo se usa el reloj CLOCK MONOTONIC.
clock nanosleep(clockid t clock id, int flags, const struct timespec *re-
quest, struct timespec *remain): Suspende la ejecución del thread que
llama a la función durante el tiempo req usando el reloj establecido en
clock id que en este caso será el reloj usado en la función clock gettime().
Se usa el flag TIMER ABSTIME y el parámetro remain es NULL.
Para que el ejecutivo cı́clico cumpla las restricciones tiempo real de las tareas,
debe de lanzar una nueva instancia de cada una de acuerdo con su periodo, y
de modo que finalice antes del siguiente. Para ello se ha tomado como tiempo
de ejecución de cada tarea (C) el WCET (Worst Case Execution Time) de la
misma, usando una función que devuelve un valor temporal con precisión de
nanosegundos antes y después de la ejecución de la tarea (Cuadro 2). El tiempo
de ejecución de las tareas de tipo sensor es el mismo ya que solo se encargan de
obtener el valor del sensor en la placa Arduino, que al tener los valores de los
sensores guardados en memoria, no necesita calcularlos cada vez que se realiza
una petición. Se ha utilizado el contexto de la instalación realizada en la planta
depuradora de viñedos Pago de Aylés.
Se ha incluido un diagrama que muestra la organización de la ejecución de
tareas en el marco temporal (Figura 12).
22
Cuadro 2: Tareas del ejecutivo cı́clico en Pago de Aylés
Tarea C(ms) T(ms) D(ms)
Caudalı́metro 12 2000 2000
Detector mov. 12 2000 2000
Nivel lı́quido 12 2000 2000
Sensor PH 12 4000 4000
Anemómetro 12 8000 8000
Veleta 12 8000 8000
Humedad 12 8000 8000
Temperatura 12 8000 8000
Escribir DNP3 19 2000 2000
Leer DNP3 104 2000 2000
23
Algoritmo 2: Extracto de script IFTT.
1 if [$sensor == ”a”] then
2 #sensor de nivel
3 if $value -lt 20 then
4 #nivel alto
5 #desactivar bomba de lı́quido
6 echo ”c 0”
7 end
8 if $value -gt 100 then
9 #nivel bajo
10 #activar bomba de lı́quido
11 echo ”c 1”
12 end
13 end
6. Sensores
6.1. Arduino Due
La placa Arduino Due contiene una CPU ARM Cortex-M3 de 32 bits con
una frecuencia de 84 MHz. Los pines I/O permiten una tensión máxima de 3,3V
que es diferente del resto de Arduinos disponibles ya que funcionan a 5V.
El lenguaje de programación usado para la placa Arduino es C++. Se ha
utilizado el Arduino IDE para programar sobre la placa haciendo uso de las
librerı́as de terceros TimeLib y TimeAlarms para la implementación de valores
históricos de los sensores.
La comunicación entre el GuruPlug outstation y la placa Arduino Due se
realiza mediante un cable USB usando el protocolo de comunicación Modbus
(Figura 13). Modbus es un protocolo simple pero robusto para comunicaciones
en puertos serial compuesto por cuatro campos: La dirección del dispositivo al
que se dirige la acción, el código de función que especifica el tipo de acción, un
conjunto de datos y por ultimo dos bytes de CRC [8].
Existen dos tipos de comunicación.
Lectura: El outstation realiza una petición y el código de función Modbus
contiene un código que corresponde con la lectura de un sensor. El Arduino
verifica que es un mensaje Modbus correcto y comprueba el CRC, tras esto
24
comprueba cual es el sensor al que se ha realizado la petición y coge el
valor correspondiente de la posición de memoria donde está almacenado
el valor. Compone un mensaje Modbus y lo devuelve al outstation por el
USB.
Escritura: El outstation envı́a un mensaje por el Modbus con un código de
función que corresponde al de la escritura de un sensor. Tras verificarse
que el mensaje es correcto, se comprueba cual es la posición de memoria en
la que está el registro del sensor sobre el que se va a actuar y se sobrescribe
usando el valor del campo Data del mensaje Modbus.
Inicialmente la comunicación serial del Arduino a través del USB es lenta es-
tando siempre por encima del segundo, para mejorar la velocidad de las comuni-
caciones es necesario cambiar dos valores en la placa Arduino. Las funciones de
lectura del serial tienen como estándar un timeout de un segundo que garantiza
que el mensaje a leer va a llegar de forma completa y que no se va a detener
la lectura cuando aún faltan datos por llegar. Se ha reducido este timeout a
un milisegundo, esto es posible cambiando el valor de Serial.setTimeout y
haciendo que antes de realizar una lectura se compruebe que se han recibido
en el serial tantos bytes como tamaño tiene el mensaje de Modbus que se está
usando. El otro cambio que mejora la velocidad de la comunicación es aumentar
la velocidad de la transmisión de datos al serial, inicialmente el valor son 9600
bps y se ha cambiado a 115200 bps.
El código consiste en una función de setup que activa los pines a los que
están conectados los sensores, prepara las interrupciones e inicializa variables
necesarias para la ejecución. Una vez acaba la ejecución de la función setup se
inicia la función loop que se ejecuta de forma continua y permanente, desde aquı́
se llama al resto de funciones necesarias para el muestreo de los sensores.
6.2. Caudalı́metro
El modelo FS300A G3/4.es un caudalı́metro simple que funciona por el efecto
Hall al producirse una corriente en presencia de un electroimán perpendicular
que rota empujado por el flujo del interior del caudalı́metro. Tiene tres cables,
el rojo contiene la tensión de 5V para alimentar el caudalı́metro, el amarillo es
el cable de salida que sacará 5V cada vez que se reproduzca el efecto Hall y por
último el cable negro que funciona como tierra.
La implementación se ha realizado mediante interrupciones, cada vez que
llega un flanco de subida del sensor la interrupción ejecuta una función que
aumenta el valor de una variable. El muestreo se realiza cada segundo, existe
un timeout preparado para que después de un segundo ejecute una función que
calcule el número de litros que han pasado por el caudalı́metro según el número
de interrupciones usando la siguiente ecuación.
Interrupciones ∗ 60
Caudal =
5,5Q
25
Usando la librerı́a para Arduino TimeAlarm se ha implementado un histórico
de los datos del caudalı́metro, pudiéndose observar el caudal de las últimas horas.
6.3. Anemómetro
El anemómetro 6410 Davis Vantage Pro 2 tiene dos funcionalidades, medir
la velocidad del viento y con la veleta medir la orientación desde la que sopla el
viento.
Para la velocidad del viento se usan interrupciones en el flanco de subida
que aumentan el valor de una variable. Debido a la variabilidad del viento que
cambia continuamente de velocidad, el muestreo se realiza cada 10 segundos para
aumentar la fiabilidad de la medición. Para convertir los pulsos de la interrupción
en velocidad real del viento existe una ecuación del fabricante que produce
millas por hora, para convertirlo a metros por segundo es necesaria añadir otra
operación de división a la fórmula del fabricante.
P ulsos∗2,25
P eriodo
V elocidad =
0,44704
La veleta devuelve un entero entre 0 y 360 siendo 180 el soporte de la veleta
por lo que para obtener un valor correcto es necesario instalar la veleta en una
pared que apunte al norte o si no es posible usar un offset para corregir el valor.
26
para solo actualizarse cada dos segundos por lo que al realizar lecturas con
intervalos menores se recibe el mismo valor.
27
Figura 14: Diagrama de Gantt del proyecto.
7.1. Planificación
El proyecto comenzó el dı́a 15 de febrero de 2016, principalmente definiendo
los objetivos y las funcionalidades a ser desarrolladas. Acabada esta fase pre-
liminar se comenzó con el análisis del proyecto para realizar posteriormente un
primer diseño.
Las iteraciones en las que se realizan análisis, diseño, implementación, prue-
bas y documentación concluyen el dı́a 29 de julio. Tras las iteraciones se dedicó
un tiempo a acabar la memoria que ya se habı́a comenzado previamente y dejarla
preparada para el depósito (Figura 14).
28
Figura 15: Tiempo dedicado por tarea.
29
8. Conclusiones
Una vez finalizado el proyecto, se realizan las valoraciones sobre el desarrollo
y el resultado obtenido del proyecto.
8.1. Resultados
Con el proyecto acabado se ha conseguido implementar el sistema diseñado
cumpliendo con todas las especificaciones definidas al comienzo del proyecto. El
sistema final permite obtener datos de sensores y dispositivos, comunicarlos con
el protocolo DNP3 y TLS a un máster que monitoriza y analiza los datos y que
es capaz de responder ante valores impropios de los dispositivos enviando una
respuesta que corrige el funcionamiento de los dispositivos y sensores.
Se ha desarrollado un ejecutivo cı́clico soft real-time que obtiene las tareas
de un fichero de configuración y que permite cambiar las tareas sin necesidad
de recompilar el código.
Por último se ha implementado una comunicación Modbus con una placa
Arduino para obtener los valores de los sensores que también han sido progra-
mados y calibrados.
30
ha requerido implementar sensores fı́sicos. Además el proyecto requerı́a que se
ejecutase en los GuruPlug ARM por lo que ha sido necesario crear un entorno de
compilación cruzada con BuildRoot para poder ejecutar el código en máquinas
ARM.
He aprendido a usar tecnologı́as y librerı́as que no conocı́a pero también he
mejorado mi conocimiento de otras que ya conocı́a como el lenguaje de progra-
mación C, que aunque ya lo habı́a usado varias veces, nunca lo habı́a hecho a
este nivel de profundidad.
Además me he tenido que desenvolver en un entorno laboral real. Aunque el
proyecto ha sido individual, he debido de colaborar con compañeros para ciertas
tareas y cada pocas semanas mostrar como avanzaba el proyecto a mi director
de TFG.
Por último, la realización del proyecto me ha aportado madurez, capaci-
dad organizativa y la paciencia para enfrentarme a nuevos proyectos de gran
envergadura.
31
Bibliografı́a
[8] Modicon, Modicon Modbus Protocol Reference Guide, Junio 1996, [En lı́nea],
http://modbus.org/docs/PI MBUS 300.pdf
[9] L. Llamas, Medir distancia con arduino y sensor de ultrasonidos, 16 Ju-
nio 2015, [En lı́nea], http://www.luisllamas.es/2015/06/medir-distancia-
con-arduino-y-sensor-de-ultrasonidos-hc-sr04/
32
Anexos
33
1. Anexo 1
34