Está en la página 1de 185

Proyecto Fin de Carrera

Ingeniería de Telecomunicación

Red de sensores para monitorización


inteligente de vivienda

Autor: Javier Arcenegui Almenara


Tutor: Dr. Antonio Luque Estepa

Equation Chapter 1 Section 1

Departamento de Ingeniería Electrónica


Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2016
II
Proyecto Fin de Carrera
Ingeniería de Telecomunicación

Red de sensores para monitorización inteligente de


vivienda

Autor:
Javier Arcenegui Almenara

Tutor:
Dr. Antonio Luque Estepa
Profesor titular de Ingeniería Electrónica

Departamento de Ingeniería Electrónica


Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2016
IV
Proyecto fin de carrera: Red de sensores para monitorización inteligente de vivienda

Autor: Javier Arcenegui Almenara

Tutor: Dr. Antonio Luque Estepa

El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros:

Presidente:

Vocales:

Secretario:

Acuerdan otorgarle la calificación de:

Sevilla, 2016

El Secretario del Tribunal


VI
A mi familia
A mis amigos
A mis maestros
VIII
Agradecimientos

Agradezco especialmente a Dr. Antonio Luque su ayuda, consejos y esfuerzo en este proyecto. Y por los
conocimientos que me ha enseñado durante la carrera. También quiero agradecer a los demás profesores de la
carrera que he tenido el honor de que me dieran clase. Y a mis profesores y maestros de mis estudios
anteriores a la carrera. Que todos ellos han hecho que sepa todo lo que sé hoy.
Quiero agradecer también a mi familia por ayudarme y apoyarme. Principalmente a la primera persona que me
recomendó estudiar esta ingeniería, mi tío Antonio, que en paz descanse. Además de a mis padres, por su gran
apoyo, por educarme, por su cariño y por creer en mí. Ya que gracias a ellos soy la persona que soy.
A mis amigos, por su paciencia ante las muchas horas de estudio durante la carrera. Por que sin ellos la vida
hubiera sido muy aburrida.
A Gemma, por su apoyo, su ayuda y por su motivación. Y por convencerme de hacer aquel viaje que aún
perdura.
X
Resumen

Este sistema pretende crear una red de sensores autoinstalables que permite conocer desde cualquier lugar la
temperatura, humedad y luminosidad de las diferentes habitaciones de una vivienda. Información que influye
directamente sobre el estado de bienestar. Incluyendo seguridad mediante un sistema de alarma con control de
presencia. Para ello se crean dos tipos de nodos, una serie de nodos periféricos que recogen los datos medidos
por los sensores y los envían al nodo central mediante un protocolo de comunicaciones inalámbricas. Y un
único nodo central cuya función, además de recibir los datos obtenidos por los nodos periféricos y mandarlos a
internet, es recolectar los datos de sus propios sensores, así como leer las tarjetas de identificación de los
huéspedes autorizados en la vivienda.
El proyecto engloba la interfaz web donde se puede acceder a los datos proporcionados por la lectura del
hardware. Y para ello será necesario el uso de un servidor, de un bróker, de una base de datos y de servicios
que estarán corriendo constantemente desde el servidor.
XII
Abstract

This system aims to create a network of self-installing sensors that allows to know temperature, humidity and
light of the different rooms of our house from anywhere. Including information that directly affects the well-
being of the guest.
The system has two-node types, some peripheral nodes read data measured by the sensors, temperature,
humidity, luminosity and presense, and sent to the central node via a wireless communication. A single central
node whose function, in addition to receiving the data from the peripheral nodes and send them to the server, is
to collect data from their own sensors to send it to the server and read the ID cards of authorized guests at
home.
In addition, the project also includes the web interface where there can access the data provided by reading
hardware. And this will require also the use a server, a broker, a database and services that will be constantly
running in the server.
XIV
Índice

1 Introducción 1
1.1 Objetivos 1
2 Estado del arte 3
2.1 Domótica 3
2.1.1 Aplicaciones generales de la domótica 3
2.1.2 Arquitectura 4
2.2 Hardware Open-source 5
2.2.1 Arduino 5
2.2.2 Microchip 14
2.2.3 Libelium waspmote 16
2.2.4 Texas Instrument 16
2.3 Comunicaciones inalámbricas 18
2.3.1 Wi-Fi 18
2.3.2 Bluetooth 18
2.3.3 XBee 19
2.3.4 Telefonía Móvil 20
2.3.5 Sigfox 20
2.4 Webservice 20
2.4.1 PHP 20
2.4.2 NodeJS 21
2.5 Protocolos de la capa de aplicación 21
2.6 Interfaz gráfica 21
2.6.1 Aplicación de escritorio 21
2.6.2 Aplicación móvil 21
2.6.3 Aplicación web 21
2.7 Estado del arte 22
2.7.1 OpenDomo 22
2.7.2 Casa Jasmina 22
2.7.3 OpenHab 23
2.7.4 Domoticz 23
2.7.5 PiDome 23
3 Desarrollo del Hardware 26
3.1 Descripción de necesidades Hardware 26
3.1.1 Nodo central 27
3.1.2 Nodo periférico 28
3.2 Nodo periférico 28
3.2.1 Microcontrolador 28
3.2.2 Módulo de comunicación 28
3.2.3 Shield de sensores 30
3.3 Nodo Central 33
3.3.1 Microcontrolador 33
3.3.2 Módulos de comunicación 34
3.3.3 Shield de sensores 35
XVI
3.4 Servidor web, base de datos, Bróker MQTT y Node.js 37
3.4.1 Servidor web y base de datos 37
3.4.2 Bróker MQTT 38
3.4.3 Node.js 39
4 Desarrollo del Firmware 42
4.1 Nodo periférico 43
4.1.1 Sensores 43
4.1.2 Módulo de comunicación 44
4.1.3 Gestión Energética 46
4.2 Nodo Central 50
4.2.1 Sensores 50
4.2.2 Módulos de comunicaciones. 51
5 Desarrollo Software 56
5.1 Descripción de necesidades software 56
5.2 Backend 56
5.2.1 Base de datos en mySQL 56
5.2.2 Servicios web 58
5.2.3 Panel de administración 60
5.3 Middleware 64
5.3.1 Servicio NodeJS 64
5.4 Frontend 65
5.4.1 HTML y CSS 66
5.4.2 JavaScript 68
6 Pruebas y validación 72
6.1 Pruebas de conexión 72
6.1.1 Conexión del nodo central con la red WiFi 72
6.1.2 Conexión de nodo central con el bróker MQTT 73
6.1.3 Conexión de los nodos periféricos con el nodo central 74
6.1.4 Conexión del servicio con la base de datos 74
6.1.5 Conexión del servicio con el bróker MQTT 74
6.1.6 Conexión de la web con la base de datos 75
6.2 Pruebas y calibración de los sensores 75
6.2.1 Sensor DHT11 75
6.2.2 Sensor PIR 75
6.2.3 Sensor LDR 76
6.2.4 Pruebas RC-522 76
6.3 Pruebas del sistema completo 76
7 Conclusiones y desarrollos futuros 80
7.1 Desarrollos futuros 81
7.1.1 GSM 81
7.1.2 Actuación 81
7.1.3 App Movil 81
8 Referencias bibliográficas 82
9 Anexos 86
9.1 Anexo I - Código del nodo central 86
9.2 Anexo II - Código del nodo periférico 100
9.3 Anexo III - Código del servicio NodeJS 108
9.4 Anexo IV - Código Index.hml 118
9.5 Anexo V - Código estilos.css 124
9.6 Anexo VI - Código javascript.js 130
9.7 Anexo VII - Código SuperConsulta.php 132
9.8 Anexo VIII - Código get_sensor.php 134
9.9 Anexo IX - Código get_data.php 136
9.10 Anexo X - Código setup.html 138
9.11 Anexo XI - Código estilosAdmin.css 140
9.12 Anexo XII - Código admin.php 144
9.13 Anexo XIII - Código mRegistro.php 150
9.14 Anexo XIV - Datasheet Atmel ATmega328P 158
9.15 Anexo XV - Datasheet GL55 160
9.16 Anexo XVI - Datasheet DHT11 162
XVIII
ÍNDICE DE FIGURAS

Figura 2-1 – Arquitectura de redes (A) centralizada, (B) mixta y (C) distribuida 4
Figura 2-2 - Logo de la comunidad de arduino 5
Figura 2-3 - Arduino UNO 6
Figura 2-4 - Arduino Leonardo 7
Figura 2-5 - Arduino Mega 2560 8
Figura 2-6 - Arduino PRO mini 8
Figura 2-7 Arduino PRO 8
Figura 2-8 - Arduino Nano 9
Figura 2-9 - Arduino y Genuino Micro 9
Figura 2-10 - Arduino FIO en vista Frontal y trasera 9
Figura 2-11 - Arduino DUE 10
Figura 2-12 Arduino y Genuino ZERO 11
Figura 2-13 - Arduino M0 PRO 11
Figura 2-14 - Arduino M0 12
Figura 2-15 - Genuino 101 12
Figura 2-16- Genuino MKR1000 13
Figura 2-17 - Arduino YUN 13
Figura 2-18 - Arduino TIÄN 14
Figura 2-19 - Arduino Industrial 101 14
Figura 2-20 - Pinguino 18F2550, Primera versión de las placa de desarrollo pinguino 15
Figura 2-21 - ChipKit UNO32 15
Figura 2-22 – ChipKit MAX32 16
Figura 2-23 – IDE Energía 17
Figura 2-24 – Texas Instruments MSP-EXP430G2 LaunchPads 17
Figura 3-1 – Nodo periférico 28
Figura 3-2 – XCTU (A) Descubrimiento un xBee, (B) Configurando un xBee 29
Figura 3-3 – Conexión del sensor DHT11 30
Figura 3-4 – Vista inferior de un sensor PIR 30
Figura 3-5 – Montaje LDR 31
Figura 3-6 – Gráfica Lux en función de la resistencia LDR 31
Figura 3-7 – PCB de la shield del nodo periférico 32
Figura 3-8 – Esquemático de la shield del nodo periférico 32
Figura 3-9 – Nodo central 33
Figura 3-10 – Arduino Wireless SD Shield 34
Figura 3-11 – Arduino WiFi Shield 34
XX
Figura 3-12 - Módulo RC-522 35
Figura 3-14 Esquemático de la shield del nodo central 36
Figura 3-13 – PCB de shield del nodo central 36
Figura 4-1 – Posibles estados de ahorro de energía del Atmel ATmega328p 46
Figura 4-2 – Registro de estado del microcontrolador Atmel ATmega328p 48
Figura 4-3 – Registro de control del temporizador watchdog del microcontrolador Atmel ATmega328p 48
Figura 4-5 – Tiempo de preescalado del watchdog del microcontrolador Atmel ATmega328p 49
Figura 5-1 – Panel de login de la interfaz de administración. 60
Figura 5-3 – Panel de administración 61
Figura 5-2 – Panel de login con usuario o contraseña erróneo 61
Figura 5-5 – Solo se actualiza un elemento 62
Figura 5-4 – Cambio de dos elementos simultáneos en la interfaz de administración 62
Figura 5-6 – No se actualiza ningún campo 63
Figura 5-7 – Panel de login tras caducar la sesión 63
Figura 5-8 – Sección introducción de la interfaz de usuario 66
Figura 5-9 – Sección sensores de la interfaz de usuario 66
Figura 5-10- Popup con las gráficas de los nodos. 67
Figura 5-11 – Sección Acerca de de la interfaz de usuario 68
Figura 5-12 – Formulario con los nodos y sensores disponibles 70
Figura 5-13 – Calendario para seleccionar el rango de fechas a mostrar. 71
Figura 6-1 – Conexión a la red wifi y al bróker MQTT 72
Figura 6-2 – Reconexión del nodo central al modem wifi 73
Figura 6-3 – Reconexión del nodo central al bróker MQTT 73
Figura 6-4 – (A) Recepción de datos en el nodo central, (B) Envío de datos desde el nodo periférico 74
Figura 6-5 – Aviso de nuevo dispositivo 76
Figura 6-6 – Histórico del nodo central 77
Figura 6-7 – Aviso de entrada, salida y armado de la alarma 77
Figura 6-8 – Vista final y verificando el correcto funcionamiento del sistema 78
Notación

ºC
Grado centígrado
A Amperios
AC Corriente alterna
AC/DC Conversor corriente alterna a corriente continua
ADC Conversor analógico a digital
API Application Programing Interface o Interfaz de programación de aplicaciones
ARC Arquitectura RISC de microprocesadores
ARM Arquitectura RISC de microprocesadores
AT Comando de comunicación entre hombre y módem.
AVR Arquitectura RISC de microprocesadores
B Offset de la señal logarítmica
BLE Bluetooth Low Energy
CC Conector común
CPU Central Processor Unit o unidad central de procesamiento
CSS Cascading Style Sheets u hojas de estilo en cascada
DAC Conversor digital a analógico
DC Corriente continua
DC/DC Conversor de corriente continua a corriente continua
DDR2 Memoria RAM de doble tasa de datos versión 2
DHCP Dynamic Host Configuration Protocol
DiY Do it Yourself o Hazlo tu mismo
DSP Digital Signal Processor o procesador digital de señales
DMA Acceso directo a memoria
EDGB Debugeador integrado
EEPROM Memoria de solo lectura borrarle eléctricamente
eMMC Lector integrado de tarjetas multimedias
FTDI Driver de conexión TTL a USB
HTML HyperText Markup Language o lenguaje de marcas de hipertexto
HTTP HyperText Transfer Protocol o protocolo de transferencia de hipertexto
GND Tierra
GPIO Entradas salidas de propósito general
GPS Sistema de posicionamiento global
I2C Protocolo de transferencia de datos, circuito inter integrado
I/O Entrada/salida
ID Identificador
IDE Entorno de programación
IEEE Instituto de ingenieros electrónicos y eléctricos
IoT Internet of Things o Internet de las cosas
IP Protocolo de Internet
XXII
ISP Programación en el sistema
JS JavaScript
LDO Regulador de corriente continua
LDR Resistencia sensible a la luz
LGA Formato de componentes para soldadura superficial
M Pendiente de la señal logarítmica
MAC Dirección física o control del acceso al medio
MISO Entrada en maestro y salida en esclavo
MOSI Salida en maestro y entrada en esclavo
MQTT Sistema de mensajes telemétricos en cola
NC (pin out) No conectado
NC (Relé) Normalmente cerrado
NO Normalmente abierto
PCB Placa de circuito impreso
PHP Pre Procesador de Hipertexto
PIR Sensor de presencia por infrarrojos
PWM Modulación de ancho de pulso
RAM Memoria de acceso aleatorio
RFID Identificador por Radio Frecuencia
RISC Arquitectura de microprocesador basados en pocas instrucciones
ROM Memoria de solo lectura
RST Reset
RTC Reloj de tiempo real
SCK Señal de reloj
SRAM Memoria de acceso aleatorio estático
SSH Secure Shell, acceso remoto mediante consola comandos
SSID Identificador del servicio de red inalámbrica
SWD Debugeador del puerto serie
TCP Protocolo de control de transmisión
TWI Interfaz de comunicación por dos cables "I2C"
UART Transmisor/Receptor universal asínconcrono
USART UART
USB Bus serie universal
1 INTRODUCCIÓN

El verdadero progreso es el que pone la tecnología al


alcance de todos.
- Henry Ford-

a tecnología avanza a un ritmo vertiginoso. Durante los últimos años se ha experimentado una

L importante evolución tecnológica que ha permitido no solo mejorar la calidad de vida, sino también la
percepción de lo que nos rodea. Dicho avance ha ocasionado que a través de la tecnología de internet,
las tareas cotidianas sean más fáciles, rápidas y asequibles, sin la necesidad de salir de la vivienda.
Queda en el recuerdo las películas de ciencia ficción donde los personajes son capaces de interactuar con su
hogar. Apagar o encender las luces con el sonido de una palmada o interactuar con una casa inteligente ya no
es ciencia ficción, y esto se debe a la domótica. Actualmente en la era del internet de las cosas (IoT) es
impensable que estas tareas no sean posibles. Existen relojes que dicen las pulsaciones, los pasos registrados o
hablar con amigos y familiares. Teléfonos móviles que no solo permiten la comunicación entre personas, sino
también trabajar a distancia desde el propio terminal, con cámaras de gran calidad y con juegos de gráficos de
alta resolución. Gracias a estos avances en telefonía inteligente y al llamado internet de las cosas se puede
conectar todo tipo de objetos a internet para controlarlos desde un Smartphone o Smartwatch.
En contraposición todos estos artículos conectados suponen un gran desembolso económico, en algunos
aspectos con precios prohibitivos. Por la fuerza adquirida tanto a conceptos de Software Libre o Hardware
Libre los entusiastas del DiY (hazlo tu mismo) tienden a fabricar sus propios sistemas domóticos. Usando en
su mayoría arduinos o raspberry pi, debido a su simplicidad a la hora de programación y de uso.
Arduino está íntimamente ligado a conceptos como IoT o DiY, esto se debe a la existencia de una gran
comunidad detrás de esta plataforma. Se pueden encontrar módulos de comunicación, de sensórica y de
control entre otros, además de sus correspondientes librerías que permiten programar todo el sistema, sin la
necesidad de conocer que es un registro o su función.
Una estimación del coste de un sistema domótico basado en hardware libre es de 50€ por nodo, dependiendo
de las dimensiones y del alcance del mismo.

1.1 Objetivos
Medir las principales variables relacionadas con la eficiencia energética, como son la humedad, la temperatura
y la luminosidad, mediante una red de sensores. También debe funcionar como una alarma de seguridad que
avise al administrador cuando se detecte una persona no autorizada. Por esta razón los nodos deben incorporar
un detector de presencia y al menos uno de los nodos debe tener un sistema de identificación. La red debe ser
escalable, se debe poder agregar tantos nodos como sean necesarios.

1
2 Introducción

Los datos obtenidos por estos sensores deben ser mostrados mediante una interfaz sencilla tanto en
ordenadores como en dispositivos móviles. Debe permitir la administración de los diferentes elementos de la
red mediante una interfaz específica para esta función, que debe estar protegida con usuario y contraseña ya
que solo el administrador de la red debe tener acceso a esta.

Para el desarrollo del sistema completo se ha de desarrollar todas las partes del mismo. Selección y
programación del hardware, configuración del servidor y programación de la interfaz web, tanto la de usuario
como la de administración.
2 ESTADO DEL ARTE

La mente que se abre a una nueva idea nunca vuelve a


su tamaño original
- Albert Einstein -

l proyecto está diseñado con placas de desarrollo open-source interconectadas entre ellas mediante una

E comunicación inalámbrica. La información obtenida por los sensores se almacena en una base de datos
mediante el uso de un middleware y se puede gestionar mediante una interfaz web.

2.1 Domótica
Conjunto de sistemas y subsistemas que permiten automatizar una vivienda generando valor añadido en
cuanto a comunicación, bienestar, eficiencia energética y seguridad. Surge en Estados Unidos en la época de
los años 70 con el objetivo de reducir el consumo energético [1], el cual aparece debido a la crisis energética
mundial que se produjo durante esta década. Es exactamente en 1978 cuando aparece el sistema X-10,
considerado el primer sistema domótico. En sus inicios solo fue usado en lugares donde el consumo energético
era elevado como hoteles y hospitales hasta llegar a los hogares, en la actualidad es común encontrarlo en
casas y oficinas de todo el mundo.

2.1.1 Aplicaciones generales de la domótica

2.1.1.1 Eficiencia energética

El origen de la automatización del hogar viene derivado de la necesidad del ahorro energético y sigue siendo el
principal objetivo de la domótica. Se produce al gestionar de forma eficiente la temperatura, luminosidad y el
sistema eléctrico.
2.1.1.1.1 Temperatura
Los sistemas de climatización consiguen un ahorro energético evitando el uso excesivo de sistemas de frío o
calor estableciendo un rango de temperatura óptima.
2.1.1.1.2 Luminosidad
Teniendo control sobre las persianas y el sistema de iluminación se puede establecer una luminosidad
adecuada minimizando el consumo eléctrico.
2.1.1.1.3 Gestión eléctrica
Permite desconectar los equipos prescindibles cuando no estén en uso o no sea necesario su utilización,
además usa de forma inteligente ciertos equipos en los horarios de tarifa reducida. Por otro lado, se puede

3
4 Estado del arte

controlar la gestión de la energía renovable. Estas últimas gestiones afectan al ahorro económico del uso
energético, más que al ahorro energético propiamente dicho.

2.1.1.2 Estado de bienestar

Los factores mencionados en el punto 2.1.1.1 están íntimamente ligados a la mejora de la calidad de vida. La
integración de servicios de valor añadido mediante IoT permite la utilización de electrodomésticos de forma
remota. Para que sea posible debe existir una interfaz de usuario fácil e intuitiva.

2.1.1.3 Seguridad

Los diferentes sensores utilizados en domótica permiten conocer el estado de la vivienda a tiempo real. Esta
información hace que se pueda detectar cualquier anomalía, tales como temperatura extrema que alertaría de
fuego, o una presencia no esperada que alertaría de robo.
A nivel preventivo se puede hacer uso de simulación de presencia para disuadir al ladrón, controlando la
apertura de las persianas, el sistema de iluminación, televisor, etc.

2.1.1.4 Comunicaciones

Es el medio o canal que posibilita conectarse al sistema domótico, ya sea por bluetooth, WiFi o cualquier otro
protocolo de comunicación. Permite no solo controlar el hogar sino avisos de alarma, tele mantenimiento, tele
asistencia, generar informes de consumo a tiempo real, etc.

2.1.2 Arquitectura
Bajo el pretexto de control sobre el
sistema existen diferentes arquitecturas
en función de la topología entre los
sensores, actuadores y controladores.

2.1.2.1 Centralizada

Desde un controlador centralizado se


recibe los datos desde los sensores, el
controlador procesará los datos y
decidirá la acción que deben cumplir los
actuadores. Tiene la ventaja de que
tienen un coste reducido y es de fácil
instalación. Además el sistema es
fácilmente ampliable. Sin embargo,
depende del correcto funcionamiento del
Figura 2-1 – Arquitectura de redes (A) centralizada, (B) mixta y (C) distribuida nodo central, si este falla, el sistema
completo deja de funcionar.

2.1.2.2 Distribuida

Toda la inteligencia está distribuida entre los nodos del sistema, ya sean actuadores o sensores. Están
conectados con un sistema cableado en bus o sistemas inalámbricos. Tiene la ventaja de ser un sistema robusto
al funcionar en bus. Su implementación es más difícil ya que necesita de una programación más compleja en
cada uno de los nodos puesto que cada uno tiene sus propios sensores y actuadores, por lo tanto podrían
funcionar de manera autónoma al resto.

2.1.2.3 Mixta o descentralizada

Cada nodo del sistema tiene su propia inteligencia, y pueden gestionar las tareas de forma independiente al
resto de nodos. Informará al resto de dispositivos tanto de los datos adquiridos como de las actuaciones
pertinentes. Tiene la ventaja de que al ser descentralizado se trata de un sistema mucho más robusto, y el
Red de sensores para monitorización inteligente de vivienda 5

rediseño de la red es trivial. Son elementos no universales, generalmente de coste elevado.

2.2 Hardware Open-source


Un proyecto open-source [2] o de fuente abierta es un proyecto en el cual el creador del mismo concede la
posibilidad de que el cliente sea capaz de ver la fuente, modificarlo y hasta distribuirlo. Esto tiene ventajas en
cuanto técnicas tanto de seguridad como de rendimiento. Al estar liberado el código, los propios usuarios
podrán mejorar el proyecto. Es un error común confundir este concepto con “No comercial”. Que el usuario
final disponga del código del programa y de la licencia competente para modificarlo no significa que no haya
pagado por él.
El concepto open-source nació para el desarrollo software y se ajusta a la perfección a este. El concepto de
hardware open-source [3] surge poco después, pero al ser un elemento tangible no es trivial transportar este
concepto del software al hardware. Es por ello que aparece una primera distinción con respecto al Software.
En este caso es imposible compartir una placa idéntica ya que esta es única y depende de los parámetros de
fabricación o de la disponibilidad de los componentes. Por lo tanto, el traslado del hardware open-source se
lleva a cabo compartiendo diseños y/o esquemáticos.
Pese a no ser la primera placa open-source, la aparición de arduino en 2005 marca un antes y un después en
este concepto por el bajo coste de fabricación y a la simplicidad que conlleva su programación. Siendo una
sinergia perfecta entre hardware open-source y software open-source.

2.2.1 Arduino

Figura 2-2 - Logo de la comunidad de arduino

Es una placa de desarrollo de hardware open-source basada en un microcontrolador de uso general. Permite
desarrollar un prototipo rápido sin tener que diseñar una placa propia. En función del funcionamiento y
requerimientos mínimos que han utilizado en este, se selecciona un nuevo microcontrolador de uso específico,
reduciendo así el coste de fabricación y desarrollo.
Está diseñado para que pueda ser usado por personas que no tengan conocimientos de electrónica, o de
programación si utilizan scratch. Aunque el conocimiento de estas materias aumenta notablemente el potencial
de estas placas. La simplicidad del uso de programing permite utilizar un microcontrolador sin tener
conocimiento de su funcionamiento interno. Existe una extensa comunidad que permite tener librerías pre
programadas de casi todos los componentes, así como shields para cualquier uso. Siendo una shield una placa
con una electrónica específica que se acopla a arduino.
Arduino [4] nació por la necesidad de crear placas de desarrollo por un bajo precio. En 2005 las placas de
desarrollo tenían un precio medio de unos 100€ y no ofrecían un soporte adecuado. Massimo Banzi era
estudiante de computación y electrónica e inició un proyecto DiY para conseguir que su instituto no entrara en
quiebra. Pretendía que el instituto pudiese vender sus placas desde un euro la unidad. Por esta razón el primer
prototipo de arduino fue fabricado por este instituto, IVRAE. Era una placa con todo lo necesario para que se
pudiera programar un microcontrolador (cristal, resistencias, condensadores y un puerto serie para
programarla).
Unos años más tarde Hernando Barragán, un estudiante de la Universidad de Colombia, al enterarse de este
proyecto contribuyó con el desarrollo de un entorno de programación para esta placa junto con David Mellis,
6 Estado del arte

también del instituto IVRAE, quien mejorará la interfaz gráfica. Este entorno recibe el nombre de Wiring.
Poco después aparece el estudiante español David Cuartielles quien diseña junto a Banzi una nueva placa que
mejora la interfaz hardware. Con la integración de Tom Igoe se agregan los puertos USB para programar
arduino.
Gianluca Martino fue el publicitario encargado de promocionar arduino, que empezó a desarrollarse de forma
masiva gracias a la ayuda de Natan Sadle para distribuirse por Italia, y tras ver su aceptación empiezan a
exportar las placas a nivel europeo para posteriormente empezar a distribuirlos a nivel mundial.
Como G. Martino fue el encargado de la distribución de estas placas, registró el nombre “arduino” a su
persona en lugar de hacerlo al equipo fundador, debido a la fuerte amistad contraída con M. Banzi, este no le
dio importancia. Aunque a la hora de registrarlo en EEUU fue M. Banzi el que formaliza el registro en nombre
de todo el equipo.
Durante finales de 2014 y principio de 2015 el equipo de arduino se ve divido y aparecen dos líneas de
desarrollo, una liderada por Massimo Banzi y otra liderada por Gianluca Martino, quien se apodera de los
derechos del nombre arduino en todo el mundo a excepción de los EEUU [5], que pertenece al equipo de
Banzi. Para poder vender placas por el resto del mundo Banzi se ve obligado a utilizar el nombre Genuino,
aunque sigue conservando el nombre arduino en sus placas de EEUU.
Pese a que algunas placas a nivel europeo reciben el nombre de Genuino, al ser también Arduino en los
EEUU, este documento se referirá a todas las placas con el nombre de arduino.

2.2.1.1 Placas basadas en microcontroladores de 8 Bits

2.2.1.1.1 Arduino UNO


Se trata del arduino por antonomasia, es la evolución actual del
primer arduino [6], el arduino Serial. Que se podía encontrar en
potemkin.org, antes de evolucionar a arduino.cc y después dividirse
entre arduino.cc y arduino.org. Así pues, su evolución pasó en
primer lugar a usar el puerto USB y finalmente cambiar el
microcontrolador auxiliar para llegar al actual diseño.
El arduino UNO utiliza un microcontrolador de Atmel. Al igual que
sus predecesores, pero esta vez, en su tercera revisión utilizando el
ATmega328P [7] como microcontrolador principal a 16 MHz y un
Figura 2-3 - Arduino UNO
microcontrolador auxiliar que sirve para simular un puerto serie
mediante USB y así poder programarlo directamente desde el IDE
de arduino mediante USB. Este microcontrolador auxiliar es un Atmel ATmega16u2. Dispone de su propio
puerto ICSP y su propio oscilador también a 16 MHz. Todos los pines del microcontrolador auxiliar a
excepción del ISCP y su comunicación con el microcontrolador principal están en configuración NC (No
Conectado). Por lo que no se podrá sacar partido de este microcontrolador más allá de su comunicación USB
con el principal o la programación del mismo.
Esta placa de desarrollo está preparada para ser alimentada tanto por USB, así como por el conector Jack para
corriente DC el cual puede alimentar a la placa en un rango de entre 7V y 12V. Esta placa debido a su
electrónica interna permite que ambos conectores de alimentación estén conectados simultáneamente siendo la
fuente predefinida la del Jack, si este se desconectase, pasaría a ser alimentado por el USB, siendo transparente
para el usuario.
Debido a que se basa en el microcontrolador ATmega328P, dispone de catorce pines de entrada/salida
digitales, de los cuales seis pueden ser utilizados como PWM. Y pese a que disponga el microcontrolador de
ocho entradas analógicas, tan solo dispone de seis. Esto es así para respetar el diseño del pin out original de
arduino.
Dispone de forma interna de tres contadores, dos de 8 bits y uno de 16 bits [8]. Así como un sistema de
medición interna de temperatura del propio microcontrolador. Permite una programación maestro/esclavo para
una interfaz SPI e I2C. Así como un puerto Serie UART con el que comunicarse, ya sea con el PC mediante el
Red de sensores para monitorización inteligente de vivienda 7

microcontrolador auxiliar o con otros módulos de comunicación que utilicen este sistema como xBee o los
módulos SIM entre otros muchos.
Dispone de una memoria de programa de 32Kbytes que puede ser programado mediante instrucciones RISC,
aunque es más cómodo usar el propio IDE de arduino. Dispone también de una memoria EEPROM de 1Kbyte
que permite almacenar datos incluso cuando el arduino no está alimentado. Y de una memoria interna para
variables del tipo SRAM de 2 Kbytes.
Dispone de la posibilidad de utilización de watchdog y de modo hibernación, aunque ambas configuraciones
son necesariamente programadas mediante el uso de las instrucciones RISC o de su código C alternativo
facilitado por el fabricante. Ya que será necesario la programación con uso de registros.
Por último comentar que dispone de dos pines de interrupción externa configurable como nivel alto, nivel bajo
o cambio de nivel de la señal de entrada. Estos pines están asignados a los pines digitales 2 y 3.

2.2.1.1.2 Arduino Leonardo


Se trata de la evolución del arduino UNO, aunque no
parece atraer a los seguidores de arduino, ya que la gran
mayoría de la comunidad sigue prefiriendo el uso del
arduino UNO pese a las mejoras implícitas del arduino
Leonardo. Incluso ha sido retirado por parte de arduino.cc
[9].
Tal como se puede apreciar en la figura 2-4, solo dispone
de un microcontrolador, el Atmel ATmega32u4 a 16 MHz
[10]. Este permite la programación directa mediante el
puerto USB, por lo tanto no necesita de un
microcontrolador auxiliar. Esto posibilita gestionar el
puerto USB y con esta gestión controlar periféricos USB
(USB host). Figura 2-4 - Arduino Leonardo
El arduino Leonardo dispone de un total de veinte pines
digitales, los catorce pines que se aprecian como pines digitales según el pin out de arduino, y los seis pines
analógicos, que también pueden ser utilizados como pines digitales tanto en esta placa como en el arduino
UNO. Como diferencia con esta, el arduino Leonardo puede utilizar algunos de los pines reservados en el pin
out de pines digitales como entrada analógica. En total se pueden usar doce como entrada analógica. Seis de
los pines digitales también podrán ser usados como PWM. Aunque si se modifican los registros se puede
obtener hasta 11 bits para el PWM en operaciones de alta velocidad, y al menos cuatro de hasta 16 bits en
operaciones normales. Al igual que el arduino UNO dispone de tres contadores internos, uno de 8 bits y dos de
16 bits, más otro contador de 10 bits con PLL y modo de comparación [11]. Dispone de un puerto serie
USART, un puerto SPI y un puerto I2C. Este microcontrolador permite entrar en modo Sleep o hibernación y
dispone de watchdog, así como de cinco pines de interrupciones externas, los pines digitales 0, 1, 2, 3 y 7.
En cuanto a la memoria de programa, dispone de 32 Kbytes. Al estar el bootloader instalado en el propio
microcontrolador, se dispone solo de 28 Kbytes para su programación. Esto no ocurre en el arduino UNO ya
que el bootloader está instalado en el microcontrolador auxiliar. Dispone de 2.5 Kbytes de memoria SRAM y
1 Kbyte de EEPROM.

2.2.1.1.3 Arduino Mega 2560


Arduino está basado en un microcontrolador Atmel ATmega2560 [12]. Uno de los microcontroladores de 8
bits más potente de Atmel. Dentro de las versiones de Arduino Mega aparece también el arduino Mega 1280,
cuya única diferencia es que dispone de 128 Kbytes de memoria de programa en lugar de los 256 KBytes que
tiene el arduino Mega 2560. Siendo similares el resto de características. Ambos disponen de 8 Kbytes de
memoria SRAM y 4 Kbytes de memoria EPPROM.
8 Estado del arte

Se trata de una versión con mejores características que la placa de arduino UNO. Dispone de un
microcontrolador auxiliar, que coincide con el que utiliza el arduino UNO, que se utiliza exclusivamente para
la comunicación USB del arduino con el ordenador. Por lo que tampoco será necesario ocupar el bootloader en
la memoria de programa ni será posible sacar provecho del mismo. Al ser un microcontrolador con cien pines
[13], cincuenta y cuatro pines se utilizan como entrada/salida digital, de los cuales quince pueden ser utilizados
como PWM. Dispone de dieciséis entradas analógicas, cuatro puertos serie UART, un puerto SPI y un puerto
I2C.

Figura 2-5 - Arduino Mega 2560

Al ser un microcontrolador con mayores características tiene un mayor número de contadores, en este caso
dispone de dos contadores de 8 bits y cuatro de 16 bits. Así como un de un watchdog. Dispone de seis pines de
interrupciones para poder despertar el microcontrolador cuando este entre en modo Sleep, o para cualquier otra
función con prioridad.
Al igual que las dos placas descritas anteriormente dispone de alimentación mediante USB y mediante un Jack
para adaptadores AC/DC o DC/DC cuya salida estén comprendidas entre 7 y 12V.

2.2.1.1.4 Arduino PRO / Pro Mini


Se tratan de placas basadas en el microcontrolador ATmega328P, orientado a una gama más profesional para
la fabricación de prototipos, debido a que incluyen los elementos mínimos necesarios para su funcionamiento.
Permite varias configuraciones en función de las necesidades del proyecto, ya que puede ser alimentado a 5V
ó 3V3, así como a diferentes frecuencias de reloj (8 MHz, 10 MHz, 16MHz y 20 MHz).
No dispone de la posibilidad de programación por USB, pero se pueden programar
mediante un cable FTDI con el IDE de arduino. Por lo que hace de este dispositivo
una herramienta interesante para la fabricación
de prototipos basados en arduino.
La diferencia entre la arduino PRO [14] y la
PRO mini [15], es que arduino PRO está
Figura 2-6 - Arduino PRO concebido con el pin out típico de arduino así
mini
como la posibilidad de conectar una tensión
entre 4 y 12 V y gestión de batería mientras que arduino PRO mini está
orientado para su uso en placas de pruebas o breadboard, siendo la única
forma de alimentarlo a la tensión configurada de forma externa.
Al no disponer de microcontrolador auxiliar se dedica 0.5 Kbytes de la
Figura 2-7 Arduino PRO
memoria de programa para el bootloader, que permite su programación
mediante el cable FTDI.
Red de sensores para monitorización inteligente de vivienda 9

2.2.1.1.5 Arduino Nano


Se trata de una versión para breadboard del Arduino UNO [16]. Existen
dos versiones, una que funciona con el micro ATmega328, similar al
ATmega328P pero con un consumo mayor y otra que funciona con el
ATmega168, similar al ATmega328 pero con 16 Kbytes de memoria de
programa, 1Kbyte de SRAM y 0.5Kbyte de EEPROM. En ambos casos
funcionan a 16 MHz.
La principal diferencia, aparte del diseño y el pin out, es el
microcontrolador auxiliar, en lugar de utilizar un ATmega16u2, en su
lugar utiliza el FT232RL, un micro que simula una comunicación serie
mediante USB, similar a como hace el cable FTDI del arduino PRO.

Figura 2-8 - Arduino Nano


Para poder alimentar el circuito entre 7 y 12 V se tendrá que utilizar los
pines Vin y GND, ya que no dispone de un socket para Jack, aunque si
del regulador de tensión.

2.2.1.1.6 Arduino Micro

Figura 2-9 - Arduino y Genuino Micro

Se trata de una versión para breadboard del arduino Leonardo [17], la única diferencia entre este y el arduino
Leonardo es el pin out. Al igual que ocurre con el arduino Nano, esta placa no dispone de un socket para Jack
de alimentación, por lo que para alimentar la placa entre 7 y 12V se debe conectar entre los pines Vin y GND.

2.2.1.1.7 Arduino FIO


Se trata de una versión modificada
del arduino PRO mini, donde se
utiliza gestión de batería y un socket
para xBee [18]. Una placa de
desarrollo con tamaño apto para
utilizar en una breadboard y está
basada en el microcontrolador Atmel
ATmega328P. Es posible que cause
confusión que incluya un puerto mini
USB, pero solo tiene conectado los
pines de alimentación. Por lo que las
únicas formas posibles para
programar este arduino son mediante
un cable FTDI y con el método
general para programar los
microcontroladores de Atmel, usando Figura 2-10 - Arduino FIO en vista Frontal y trasera
el ISCP, disponible en todas las placas
de arduino. Esta placa funciona a 3V3 y tiene una frecuencia de reloj de 8 MHz.
10 Estado del arte

2.2.1.2 Placas basadas en microcontroladores de 32 bits

2.2.1.2.1 Arduino DUE


Solo está disponible en arduino.org, es el primer arduino de
32 bits, utilizando el microcontrolador Atmel SAM3X8E
ARM Cortex-M3 [19]. Como trabaja a 3V3 una entrada
superior en cualquiera de sus pines podría dañar la placa de
manera irreparable. Puede ser alimentado tanto por USB
como por Jack. Existe una electrónica de potencia que se
encarga de adaptar el voltaje al del correcto funcionamiento
para el arduino, así como una lógica de control que permite
que ambas alimentaciones no hagan cortocircuito. Al tratarse
de un procesador de 32 bits, necesita una mayor velocidad de
reloj, 84 MHz, lo que significa también que tiene un
consumo bastante elevado, hasta 0.8A.
Como se puede apreciar tiene el mismo pin out que el
arduino Mega, por lo que dispone también de hasta cincuenta Figura 2-11 - Arduino DUE
y cuatro pines de entrada/salida digitales, de los cuales doce
pueden ser usados como PWM, doce entradas analógicas, cuatro puertos serie UART, un puerto SPI. Tiene
dos puertos I2C. Además de dos conversores digital-analógico y un conector JTAG, el cual se utiliza para su
programación. Al contrario que los arduinos de 8 bits que tienen una arquitectura AVR, los de 32 bits tienen
una arquitectura ARM, por lo que no pueden ser programados mediante un puerto ISCP.
Esta placa posee dos puertos USB, uno para su programación y otro como USB nativo. Es posible programar
el arduino DUE desde el USB nativo, si falla no se podrá utilizar este puerto de nuevo para su programación
hasta que se reprograme por el puerto JTAG. Por ello es recomendable utilizar el puerto para realizar el
borrado y la transferencia del sketch usando un microcontrolador auxiliar, el ATmega16u2. Esta vez el
protocolo de comunicación que utiliza será diferente al del arduino UNO o Mega ya que tanto el borrado como
la transferencia del sketch se produce de diferente forma.
Dispone de un total de 512 Kbytes de memoria de programa. Divididos en dos bloques de 256 Kbytes, 96
Kbytes de memoria SRAM la cual está dividida en dos bloques uno de 32 Kbytes y otro de 64 Kbytes, 16
Kbytes de memoria ROM, donde está almacenado el bootloader del arduino Due.
Esta placa permite la comunicación con el puerto CANBUS y NFC [20]. Pese que el IDE de arduino no lo
soporta, sí que se puede programar a nivel de registro. Dispone de un controlador DMA, lo que hace posible
hacer llamadas intensivas a memoria sin perjudicar el funcionamiento de la CPU. Cuenta con ocho contadores
de 16 bits y un registro de 32 bits para un temporizador de tiempo real (RTT) y un reloj de tiempo real (RTC).
Así como un generador de números aleatorios reales y un registro de protección de los datos escritos en la
memoria de programa.

2.2.1.2.2 Arduino Zero


Se trata de una actualización por parte de arduino.cc del arduino UNO a 32Bits. Está basada en el
microcontrolador ATSAMD21G18 [21], un micro de Atmel de 32 bits con una frecuencia de reloj de 48 MHz
y funciona a 3V3. Al igual que ocurre con el arduino DUE, puede ser programado por los dos puertos USB
que tiene disponible, el puerto de programación o el puerto nativo.
El puerto de programación conecta el microcontrolador principal con un microcontrolador EDGB (Embedded
Debugger) de Atmel, que además de realizar un borrado hardware del micro y su programación, permite una
interfaz completa como debugger. Esta placa ha sido desarrollada con ayuda de los ingenieros de Atmel, por lo
tanto es totalmente compatible con Atmel studio.
Red de sensores para monitorización inteligente de vivienda 11

Figura 2-12 Arduino y Genuino ZERO

El puerto nativo permite su programación, aunque como ocurre con el arduino Due, su uso no está
recomendado para la programación, sino para ser usado como USB Host.
Dispone de veinte pines digitales de entrada/salida. Seis pueden utilizarse como entradas analógicas de 12 bits,
dieciocho pueden utilizarse como PWM. Uno como conversor digital a analógico de 10 bits y todos los pines
que se describen como digitales en la PCB pueden ser empleados para interrupciones externas, a excepción del
pin 4.
Tiene cinco contadores de hasta 16 bits, de los cuales uno se puede configurar como 8 bits, otro de 32 bits con
dos comparadores [20] y tres contadores de 24 bits para control. Dispone de un contador exclusivo para el
watchdog.
Tiene una memoria Flash de 256 Kbytes y 32 Kbytes de SRAM. No dispone de EEPROM, no obstante, han
ideado una forma para poder escribir los datos que se quieran modificar en la memoria de programa como si
fuese EEPROM. Estos valores se perderán al subir un nuevo sketch ya que se borra toda la memoria de
programa en el proceso.
Otros beneficios de usar un núcleo ARM son el uso de DMA de doce canales, que dedica 32 bits al RTC, tiene
un generador de código de errores CRC de 32 bits y un control de periféricos táctiles (PTC). Todas estas
características deben de programarse con el uso de registros ya que no están disponibles en wiring.
Puede ser alimentado entre 7 y 12 V mediante el Jack o bien mediante el puerto USB. El microcontrolador
funciona a 3V3, meter una tensión mayor en sus entradas podría dañar el arduino.

2.2.1.2.3 Arduino M0 Pro


Se trata de una versión idéntica del arduino Zero, la única diferencia entre
ellas es el mapeado de los pines, si se conoce la equivalencia podrían
programarse con el IDE del contrario. Desde arduino.org se ha dado a
conocer el modelo del debugger EDBG [22], pese a que no estar
indicado, utiliza el mismo microcontrolador EDBG que el arduino Zero,
el AT32UC3A4256 de cien pines VFBGA. El arduino M0 pro puede ser
alimentado entre 6V y 15V, un rango bastante superior al ofrecido por el
arduino Zero. La razón de que esta placa sea similar al arduino Zero es
que fue la primera placa que se produce durante la división del equipo de Figura 2-13 - Arduino M0 PRO
arduino. Como fue desarrollada en conjunto, ninguna de las dos empresas
quiere quedarse sin esta placa, por lo que se generan dos placas con diferente nombre y layout aunque con el
mismo diseño de hardware.
12 Estado del arte

2.2.1.2.4 Arduino M0
Se trata de una versión reducida y de bajo coste del arduino M0 pro,
Se elimina el microcontrolador EDBG [23], por lo que solo podrá ser
programado mediante su USB nativo. Esto produce un ahorro de casi
un 50% del precio de la M0 pro, pero pierde la capacidad de
depuración y de programación cuando se produzca un fallo en el
microcontrolador, solo podrá ser reprogramada mediante el puerto
JTAG o SWD.
Si se busca crear un sistema simple o bien se requiere que tenga un
consumo especialmente bajo, el uso de esta placa es idóneo. Aunque la
Figura 2-14 - Arduino M0 ausencia de depurador hace que no sea del todo interesante para la
creación de prototipos rápidos.

2.2.1.2.5 Arduino 101


Tras la división del equipo de Arduino, el equipo de arduino.cc
apuesta por placas de desarrollo de 32 bits, mientras que el equipo
de arduino.org apuesta por placas con sistema operativo como se
verá en el apartado 2.2.1.3.
Se trata de una nueva placa arduino en colaboración con los
ingenieros de Intel, por lo que en lugar de utilizar un
microcontrolador de Atmel, utiliza por primera vez en una placa
integra de arduino un microcontrolador INTEL[24]. En concreto
el Intel Curie, con arquitectura de 32 bits ARC bajo una
frecuencia de reloj de 32 Mhz.
Figura 2-15 - Genuino 101
Uno de los puntos fuertes de esta placa es que tiene un precio
ligeramente superior al arduino UNO y no solo se trata de una mejora con un microcontrolador de 32 bits,
pues incluye BLE, acelerómetro de seis ejes y giroscopio. Se convierte en una gran opción para aquellas
personas que se quieren iniciar en el mundo de arduino y los sistemas automáticos.
Dispone de catorce pines de entrada/salidas digitales, de los cuales cuatro se pueden utilizar como salidas
PWM. Seis entradas analógicas, un conector serie que está conectado al USB para subir los sketches así como
un puerto SPI y otro I2C.
Por otro lado, al contrario que ocurre con las otras placas de 32 bits, esta placa, pese a funcionar a 3V3, sus
pines pueden soportar hasta 5V, ya que tienen un sistema de protección frente a estos voltajes a la entrada. Un
punto negativo es que carece de conversor DAC.
Tiene 196 Kbytes de memoria Flash y 24 Kbytes de SRAM, y como ocurre con el arduino Zero, tampoco
dispone de memoria EEPROM, aunque sí que se puede utilizar la memoria flash para tal fin.

2.2.1.2.6 Arduino MKR1000


Se trata de una versión reducida y mejorada del arduino Zero. Se reduce el tamaño de forma considerable por
lo que puede ser utilizado directamente en una breadboard. Integra un módulo WiFi [25] lo que permite
conectar el arduino a internet convirtiéndola en una interesante propuesta para IoT. Esta placa no incluye un
debugger, por lo que al igual que ocurre en arduino M0, si ocurre un error durante la carga del sketch, solo se
podrá utilizar reprogramando el bootloader mediante el puerto JTAG.
Red de sensores para monitorización inteligente de vivienda 13

Dispone de un socket para batería, lo cual permite cargar una batería hasta 4.2V con un máximo de 1400 mAh,
y se recomienda el uso de una batería de al menos 700 mAh.

Figura 2-16- Genuino MKR1000

Esta placa no se puede alimentar con más de 6V, ya que no dispone de un LDO para transformar mayores
tensiones.

2.2.1.3 Placas Mixtas con Microcontroladores y DSP

2.2.1.3.1 Arduino YÚN


Con la aparición de las raspberry PI, Beagle bones y otras placas
basadas en DSPs con sistema operativo Linux, Arduino se ve en
la obligación de crear su propia placa con DSP creando un
híbrido entre una placa de desarrollo con microcontrolador y una
placa de desarrollo con DSP [26], el arduino YÚN.
Está diseñado para diferenciarse en dos partes autónomas que
son capaces de funcionar de manera conjunta. Por un lado se
tiene el DSP, Atheros AR9331 con arquitectura MIPS a 400Mhz
y tiene 62 Mbytes de memoria RAM DDR2. Este micro soporta
una versión de Linux llamada OpenWrt-Yun, el cual podremos Figura 2-17 - Arduino YUN
controlar por SSH.
Como ventaja adicional este DSP incluye el control de un socket RJ45 para Ethernet y de una antena para
WiFi. Se puede utilizar para proyectos de IoT. Cuenta con la gestión de un lector de tarjetas SD, por lo que se
pueden realizar infinidad de proyectos con diferentes objetivos.
Por otro lado se tiene una réplica exacta del arduino Leonardo. Desde el microcontrolador se puede generar
peticiones al DSP, ya sea conexión WiFi, lectura de archivos, gestión de la SD o cualquier otra acción
mediante un puente que comunica ambas partes por el puerto Serie. Desde el DSP se podrá controlar y
programar el microcontrolador. Por lo tanto, el puerto Serie del arduino se utiliza exclusivamente para la
comunicación con el DSP. Si se necesita utilizar algún dispositivo por el puerto Serie hay que simularlo
mediante un puerto serie software.
El hecho de que se pueda programar la placa desde el DSP permite la programación del arduino mediante
WiFi siempre y cuando esté conectado a la misma red.
14 Estado del arte

2.2.1.3.2 Arduino TIÄN


Se trata de una mejora del arduino YÚN. El microcontrolador en
lugar de basarse en un arduino Leonardo se basa en un arduino M0
[27]. En cuanto a la parte del DSP se utiliza el Atheros AR9342, con
una memoria de 16 Mbytes más una memoria eMMC de 4 Gbytes.
Lo que permite un mejor uso de Linux. Aunque también lo hará
mediante SSH sin interfaz gráfica.
A toda la conectividad que ofrece el DSP se le suma un procesador
BlueCore CSR8510 BLE con soporte para bluetooth de generaciones
anteriores.

Figura 2-18 - Arduino TIÄN En cuanto a la programación del M0, en lugar de utilizar directamente
el USB del microcontrolador, se utiliza un chip de silicon labs, el
CP2105, que permite la conexión con el DSP y la programación mediante el IDE de arduino.

2.2.1.3.3 Industrial 101


Desde arduino.org han diseñado una versión con formato LGA de la parte del DSP
que integra el arduino YÚN, es decir toda la electrónica necesaria para la conexión
del Atheros AR9331 en un único módulo para poder conectarlo con cualquier
microcontrolador. Este módulo recibe el nombre de arduino Industrial 101. Han
hecho una placa de desarrollo que integra este módulo dirigida a que los usuarios
puedan experimentar y hacer sus prototipos utilizandolos y para darla a conocer. Figura 2-19 - Arduino
Industrial 101
Analizando sus características se puede apreciar que se trata de un arduino YÚN sin
conexión USB, Ethernet ni lector de tarjeta SD, aunque el resto de características tanto del arduino como del
DSP son las mismas [28]. En esta nueva placa el DSP puede aprovechar los pines GPIO que con arduino YUN
no estaban disponibles. Esto da acceso al control de una pantalla oled llamada dogOLED, la cual puede ser
conectada mediante al socket que está disponible en esta placa.
La comunicación bidireccional del microcontrolador con el DSP se establece con un protocolo denominado
CIAO.

2.2.2 Microchip
La compañía microchip ha intentado formar parte del mundo arduino. A nivel académico los
microcontroladores PICs se han convertido en un estándar dado que el lenguaje RISC permite que sea
fácilmente programable a bajo nivel. Su principal ventaja es que los estudiantes no necesitan realizar
desembolso económico para utilizar su software y que dispone de un sistema de samples para adquirir varios
microcontroladores sin costo. En enero de 2016 Microchip compra Atmel [29], lo que permite que los
microcontroladores Atmel se puedan adquirir en un programa de samples de una forma mucho más
controlada.
La empresa intenta hacer que los PICs estén presentes en las placas de desarrollo con una programación
basada en wiring. Fue la comunidad que hay detrás de estos microcontroladores quienen empezaron esta
visión, diseñando unas placas de desarrollo bautizadas con el nombre “pinguino” [30]. No se dirigen a nivel
comercial y se pueden fabricar en casa por apenas un euro.

2.2.2.1 Creados por la comunidad

2.2.2.1.1 Pinguino 18f2550


Es una placa de desarrollo de 8 bits basado en el microcontrolador 18F2550, está compuesta por los elementos
justos para su funcionamiento, un botón de reset, un reloj a 20 Mhz, un led de encendido, un condensador para
Red de sensores para monitorización inteligente de vivienda 15

RTC, unas resistencias para proteger los pines entrada/salida por error humano, y la conexión USB para poder
subir los sketch por USB.
Era necesario programar el micro mediante un programador para poder quemar el bootloader al pinguino, una
vez hecho esto, se puede programar utilizando un IDE similar al de arduino. Su IDE era más limitado ya que la
comunidad que estaba detrás de pingüino era mucho más pequeña.
Está compuesto por dieciocho pines de entrada/salida digitales, que están definidos ocho como salidas
digitales, cinco como entradas digitales y cinco como entradas analógicas. Se puede cambiar las funciones de
estos pines durante la ejecución y tan solo se puede cambiar en el setup. Solo dos de los pines digitales se
pueden utilizar como salidas PWM.
Dispone de dos modos de ahorro energético, el modo idle y el modo Sleep y también de un timer de 8 Bits y
tres de 16 bits.
Tiene una memoria de programa de 32 Kbytes, 2 Kbyte de SRAM y 256 bytes de EEPROM.

Figura 2-20 - Pinguino 18F2550, Primera versión de las placa de


desarrollo pinguino

2.2.2.1.2 Pinguino 18f4550


Se trata de una evolución del pinguino 18F2550. Pertenece a la misma gama de microcontroladores, siendo la
única diferencia el número de pines disponibles para su uso. Dispone de veintiocho pines de entrada/salida
analógicas, de los cuales dos pueden ser utilizados como PWM y ocho como entradas analógicas.

2.2.2.2 Basado en microcontroladores PIC de 32bits

2.2.2.2.1 ChipKit UNO32


A nivel universitario se convirtieron en un referente, intentan hacer lo
mismo a nivel de primaria o secundaria. Pese a los esfuerzos de la
compañía, la fuerza obtenida por arduino y la gran comunidad que hay
detrás no les permite el acceso en microcontroladores de 8 bits. Por
ello se adelantan con los microcontroladores de 32 bits, donde aún hay
un campo abierto y es más sencillo tener nicho de mercado.
Se trata de una placa basada en un microcontrolador de 32 bits de
Microchip (PIC32MX320F128H) inspirada en el pin out de arduino
UNO[31]. Es compatible con todas las shields que trabajen a 3V3 y
utiliza el mismo IDE de arduino siempre que se instale un
Figura 2-21 - ChipKit UNO32 complemento, aunque también existe la opción de usar el IDE de
microchip (MPLAB). Puede ser alimentada entre 7 y 15V.
Al ser un microcontrolador de 32 bits, funciona a una frecuencia de 80 Mhz, tiene una memoria de datos de
128KB, lo que permite tener un programa más potente. Tiene cuarenta y dos pines de entrada/salida, doce de
ellos se pueden configurar como entradas analógicas y cinco como PWMs. Dispone de un puerto I2C, dos
puertos SPI, dos puertos UART y cinco pines de interrupciones externas.
Es posible dos modos de ahorro de energía al igual que ocurre con los pinguinos y dispone de cinco timers de
16 Estado del arte

16 bits, aunque permite unificar dos de ellos para formar uno de 32bits y también dispone de watchdog.

2.2.2.2.2 ChipKit MAX32


Placa basada en un microcontrolador de 32 bits de
Microchip (PIC32MX795F512) inspirada en el hardware
de Arduino DUE [32]. Al igual que chipkit UNO es
compatible con todas las shields de arduino que trabajen a
3V3 y utiliza el IDE de arduino o el de microchip.
Funciona a una frecuencia de 80 Mhz con una memoria de
datos de 512KB lo que permite tener un programa
complejo. Tiene ochenta y tres pines de entrada/salida,
dieciséis de ellos pueden ser configurados como entradas
analógicas y cinco como PWMs. Dispone de dos puertos
I2C, dos puertos SPI, y hasta seis puertos UARTs, aunque
desde la placa solo se puede utilizar cuatro de ellos, uno se
utiliza como USB OTG y otro como conector Ethernet.
Puede utilizar dos controladores para el puerto CAN, cinco Figura 2-22 – ChipKit MAX32
interrupciones externas, watchdog y dos modos de ahorro
energético. Dispone de cinco timers de 16 bits aunque se pueden unificar dos para obtener un timer de 32 bits.

2.2.3 Libelium waspmote


Libelium es una compañía que se dedica casi en exclusiva a componentes de Smartcities. Tiene una gama de
productos de placas de desarrollo llamada waspmote [33]. Está pensada para ser usada con XBee o Lora,
aunque permite el uso de otras redes inalámbricas. Posee Shields de sensóricas o de comunicación con sus
propias librerías. Se basa en el Atmel ATmega1281P y su programación es mediante wiring. Dispone de
socket para batería y su correspondiente gestión de carga. Están concebidas para su utilización en Smartcities,
por lo que disponen de un socket para tarjetas SD y GPS.
El microcontrolador utilizado es de la misma familia que en la versión corta del arduino Mega. Aunque desde
la compañía se vende como una versión más preparada que arduino. La única diferencia en su programación
es que los desarrolladores de Libelium proporcionan todo tipo de librerías para utilizar de forma más sencilla
la placa waspmote. Incluyendo librerías para poner el micro en modo Sleep y utilizar los timers, algo que no se
incluye dentro del IDE de arduino, aunque se puede realizar con las librerías que proporciona Atmel o la
comunidad de arduino.
Es una placa de desarrollo open-source que utiliza componentes y shields propias, por lo que tiene un precio
muy elevado. Funciona a 14 MHz, a esa frecuencia de reloj es mucho más eficiente para el funcionamiento de
la UART a 115200 baudios. Tiene siete entradas analógicas, ocho salidas/entradas digitales, dos puertos
UART, un puerto SPI y un puerto TWI.
La gama waspmote dispone de una serie de dispositivos llamados plug&sense. Es una placa waspmote con
una shield conectada a seis socket especiales de siete pines dentro de una caja IP68. Existen diferentes sensores
especiales para conectar en estos sockets. En esta serie se conecta un sensor y mediante un programa
proporcionado por Libelium se genera un sketch de forma automática que lea los datos de los sensores y los
mande al concentrador. En la práctica es necesario realizar una batería de medidas en entornos controlados
para la calibración de los sensores.

2.2.4 Texas Instrument


Se introdujo en el mercado de las placas de desarrollo open-source por Energia y LaunchPad MSP-
EXP430G2, su modelo más económico. En sus inicios se podían conseguir desde 3€ la unidad. Energia es un
IDE de programación basado en wiring muy similar al de arduino [34]. Lo que permite programar las
Red de sensores para monitorización inteligente de vivienda 17

LaunchPads como si fuesen un arduino, adaptando las librerías desarrolladas para arduino.
Se describen las diferentes familias de LaunchPads. En cada una de ellas existen placas según las necesidades
de los proyectos que se vayan a realizar . Texas Instruments proporciona de la forma más presisa posible sus
placas de desarrollo [35].

Figura 2-23 – IDE Energía

2.2.4.1 MSP LaunchPads

Son las placas de desarrollo más básicas de Texas instruments y su precio está entre los 10 y 18 dólares. Sus
características son similares a la de un arduino y cuanto más aumentemos el precio más prestaciones tiene,
como pantalla LCD o RTC. Están pensadas para uso de propósito general y aplicaciones de bajo consumo.
Usan microcontrtoladores de 8 bits.

Figura 2-24 – Texas Instruments MSP-EXP430G2


LaunchPads

2.2.4.2 C2000 LaunchPads

Estas placas están diseñadas para aplicaciones de control de motores a tiempo real. Funcionan con
microcontroladores de 32 bits y tienen al menos 8 PWM y cuatro salidas PWM de alta resolución (HRPWM).
En función de la placa se pueden manejar diferentes tipos de motores, desde motores DC de baja tensión hasta
18 Estado del arte

potentes motores trifásicos.

2.2.4.3 Connected LaunchPads

Placas de desarrollo pensadas para el uso de comunicación. Contienen módulos tanto para comunicaciones
cableadas (Ethernet, USB o CAN) como inalámbricas (WiFi o Bluetooth) y su precio varía dependiendo del
sistema de comunicación integrado en la placa. En función de las necesidades del sistema de comunicación las
placas intengran un microcontrolador de 8 o 32 bits.

2.2.4.4 Hercules LaunchPads

Son placas con componente de alta seguridad para aplicaciones que requieren unas normas de seguridad
exigentes. En campos como el transporte, medicina o industrial. Funcionan con controladores ARM Cortex,
por lo que sus especificaciones son de alta velocidad y está destinadas a un uso muy concreto.

2.3 Comunicaciones inalámbricas


Para la realización de un sistema domótico, es imprescindible que los nodos estén comunicados. Existen
diferentes protocolos de comunicaciones, y en función de las necesidades del sistema se utilizará uno u otro. A
continuación se describen las características de los diferentes sistemas de comunicación inalámbricas.

2.3.1 Wi-Fi
Es un protocolo de comunicación Ethernet inalámbrica (IEEE 802.11) [36], que permite interconectar equipos
de manera remota. Este estándar nace de la necesidad de crear una red inalámbrica que sea totalmente
universal. Está diseñado para distancias reducidas con un uso doméstico, evitando posibles interferencias.
Trabaja a 2.4 GHz, al igual que otros protocolos como bluetooth o xBee. No hace interferencia debido al
diseño de los protocolos, por lo tamto no son compatibles entre sí.
El valor añadido de wifi con respecto a otras redes, es el uso de diferentes posibles tipologías, así como la
seguridad contando con un nombre o SSID y un cifrado de seguridad. Existen otros métodos que permiten
reforzar la seguridad realizando filtrados por MACs por ejemplo.

2.3.2 Bluetooth
Es un protocolo para redes inalámbricas que posibilita la transmisión de datos entre dos dispositivos. Buscando
una comunicación directa entre dispositivos y la posibilidad de crear redes de datos inalámbricos. Por ello se
busca que tenga un alcance corto basado en transceptores de bajo costo. Existen diferentes versiones de
bluetooth íntimamente ligados con la capacidad del canal. Sigue el estándar del IEEE 802.15.1 [37].

2.3.2.1 Bluetooth estándar

Así se denominan a las versiones 1, 2 [38] y 3 [39]. Tienen un ancho de banda de 1 Mbps, 3 Mbps y 24Mbps
respectivamente. Las versiones 1 y 2 de bluetooth son compatibles en todas sus versiones, no obstante con la
aparición de Bluetooth v3.0 no se cumple en todos sus dispositivos. Son versiones unicast y no necesita un
pareado completo para el intercambio de datos.
Red de sensores para monitorización inteligente de vivienda 19

2.3.2.2 Bluetooth LowEnergy

Conocido como bluetooth de bajo consumo y alta velocidad (32 Mbps) [40]. Está dirigido a aplicaciones de
baja potencia. Supone un avance permitiendo la conexión punto a multipunto, así como la posibilidad del
aumento de la distancia. Aunque no es directamente compatible con sus versiones anteriores existe la
posibilidad de que lo sean, quedando esta desición a disposición del fabricante tal y como ocurre con la versión
3.0.

2.3.3 XBee
Es un protocolo de comunicación muy similar a bluetooth, pero orientado a redes ac hoc, lo cual permite
obtener una red completa y totalmente conectada sin necesidad de cablear toda la vivienda [41]. La principal
diferencia entre este protocolo y bluetooth es la posibilidad de comunicarse con otros dispositivos, ya sea
punto a multipunto o punto a punto. Con este tipo de módem se tiene la posibilidad de crear una red, teniendo
tres tipos de configuraciones “Coordinador”, “Router” y “Nodo final”. Las cuales son seleccionadas en
función de las necesidades.
Diseñado para tener un mayor alcance de red ad hoc. Con configuraciones en router se puede ampliar el
alcance, no obstante, la velocidad de transmisión se ve reducida en comparación con bluetooth [42]. Existen
dos tipos de xBee, el basado en la norma 802.15.4 y el creado por la zigbee Alliance.

2.3.3.1 Configuraciones

Existen tres tipos de configuraciones, que permitirán crear una red específica en función de las necesidades del
usuario.

2.3.3.1.1 Nodo coordinador


En esta configuración solo puede haber un nodo por red que especifica su red y sus parámetros. Todos los
elementos conectados necesitan conocer la mac de este dispositivo, de esta forma, el nodo puede obtener el
valor de la red que se necesite.

2.3.3.1.2 Nodo router


Esta configuración permite utilizarse como nodo final o intermedio. Si al establecerse la red, se aprecia que no
se puede conectar algún elemento lejano porque su señal no llegue al nodo final pero si alcanza a un router, el
nodo final se conectará con el coordinator mediante una retransmisión del nodo router. Este puede hibernar,
pero no podrá retransmitir ninguna trama en este estado.

2.3.3.1.3 Nodo final


Es la configuración para nodos finales donde se desea un bajo consumo. Permite poner el dispositivo en modo
hibernación. El cual despertará al recibir una trama o mediante una interrupción externa en el pin DTR. La
única desventaja es que existe un tiempo de wake-up, o despertar, de entre veinte y treinta segundos. Tiempo
que hay que esperar desde que se despierta hasta que sea capaz de mandar o recibir datos.

2.3.3.2 Tipos

En la actualidad existen dos tipos de xBee, incompatibles entre ellos.


20 Estado del arte

2.3.3.2.1 802.11.4
La Serie 1 de xBee [43] no requiere de configuración, lo cual permite un uso más fácil. Su funcionamiento es
muy similar a los de la serie 2 (ZigBee) evitándo la configuración necesaria para establecer una comunicación
punto a punto. La carencia de esta configuración solo permite que sea coordinator (coordinador) o end device
(dispositivo final). Lo que dificulta la conexión al establecer una red punto a multipunto.

2.3.3.2.2 ZigBee
Zigbee [44] surge como una alianza de varias empresas para poder crear redes MESH basada en tecnología
xBee para mejorar la eficiencia energética y abaratar precios. Son más difíciles de utilizar porque es necesaria
una compleja configuración previa. Se obtendrá una red MESH fuerte que permitirá su uso no solo en redes
domóticas dentro del hogar, sino en redes externas para Smartcities.

2.3.4 Telefonía Móvil


El estándar GSM (Global Standard Mobile) aparece a finales de los años 80 con la intención de desarrollar un
sistema estándar de comunicación mediante telefonía móvil digital [45]. Pero es a principio de los años 90
cuando aparecen los primeros equipos GSM. Está basado en un sistema de células que permite la
comunicación desde casi cualquier ubicación. Esta tecnología posibilita el acceso remoto a la domótica
mediante el uso del SMS, que surgió a partir del GPRS. Cuando este se conecta a la www (wordwide web) se
comienza a utilizar la telefonía móvil para monitorizar el estado de los sensores y controlar los actuadores en
un sistema domótico.
El descubrimiento de las nuevas generaciones de telefonía móvil (WCDMA, HSPA o LTE) no supone un
avance para los sistemas domóticos. Esto se debe a que la cantidad de datos intercambiados es tan pequeña que
no es necesario el uso de sistemas más rápidos, permitiendo abaratar costes de mantenimiento. Los sistemas
domóticos y de Smartcities siguen utilizando la tecnología GPRS para controlar hogares y ciudades de una
forma rápida y económica.

2.3.5 Sigfox
Aparece como la primera solución de conectividad mundial especializada en IoT. La principal ventaja de estos
sistemas frente a la telefonía móvil es el ahorro energético [46]. Los sistemas GPRS actuales cumplen
notablemente con los requisistos de velocidad para el IoT, no obtante, cuando se intentan reproducir estos
sistemas el consumo es excesivamente elevado, como por ejemplo a wearables (ropa inteligente). De media un
módulo GSM tiene picos de consumo de hasta 2 A, frente a los 61 mA de Sigfox [47].
Se sirve de una infraestructura diferente a la utilizada en GSM, lo que se desvincula del “apagón GSM” que se
avecina [48], las operadoras estiman este apagón entre 2017 y 2025.

2.4 Webservice
El uso de Webservice o servicios web permite gestionar datos o la conexión del hardware con la base de datos.
En función de la sensibilidad a la seguridad de los datos, se realiza una llamada GET o POST. IoT está ligado
al uso de bases de datos, gestión de contenido y a la existencia de una interfaz, lo que produce que se lleven a
cabo estas gestiones mediante el uso de webservice.
Dentro su desarrollo existen diversas posibilidades, pero este proyecto se centrará en las que se basan en el uso
de tecnología web.

2.4.1 PHP
Permite el envío de peticiones GET o POST de forma simple y rápida, pero debido a la falta de encriptación es
Red de sensores para monitorización inteligente de vivienda 21

fácil relicar sus mensajes. Su principal ventaja es la facilidad de programación y que cualquier sistema de
hosting que acepte PHP permite realizar el servicio.

2.4.2 NodeJS
NodeJS es un entorno de programación basado en el motor V8 de JavaScript[49], permite realizar desde
cualquier cometido sencillo hasta la creación de un hosting completo. Su uso es exclusivo para un servidor
propio o virtual (VPS) ya que necesita la instalación del entorno en el mismo. Su principal ventaja es la
posibilidad de construir un sistema seguro a partir de la creación de un rest, el cual permite generar un token de
seguridad.

2.5 Protocolos de la capa de aplicación


Se tratan de los protocolos que utilizan las aplicaciones para el intercambio de datos o la gestión de los
mismos. El usuario final no interactúa con estos, sino con aplicaciones que se sirven de ellos. MQTT y HTTP
son los dos protocolos de la capa de aplicación más utilizados en domótica, por no necesitar licencia para su
uso. El protocolo HTTP es el utilizado para acceder a la web y el protocolo MQTT es un protocolo que
permite crear una o varias conexiones punto a punto con un consumo de datos muy ligero. Estos protocolos
son fundamentales para aplicaciones de IoT, pero además sería necesario el uso de un bróker o comunicador.

2.6 Interfaz gráfica


Es la parte visible de un sistema con la que el usuario interactua de forma intuitiva sin necesidad de poseer
conocimientos avanzados sobre la utilización de líneas de comandos o de programación. Siendo transparente
para el usuario el método utilizado para recoger la información almacenada en la base de datos o la interacción
con el sistema. Las diferentes formas de mostrar la interfaz son como aplicación de escritorio, como aplicación
nativa en un SmartPhone, en una tablet o mediante una página web, siendo esta última visible en todos los
soportes.

2.6.1 Aplicación de escritorio


Se trata de una aplicación instalada en el ordenador, cuyo acceso se produce directamente pulsando con el
ratón sobre el icono de la misma. Existen tres grandes sistemas operativos (Mac, Windows y Linux), por lo
que se tiene que tener en cuenta que la programacón y compilación para cada uno es diferente.

2.6.2 Aplicación móvil


Se trata de aplicaciones instaladas en el teléfono movil o tablet, generalmente están programadas mediante un
lenguaje que establece la compañía a cargo del sistema operativo. Existen variados sistemas operativos entre
los que se destacan iOS y Android. No obstante, existen desarrollos de aplicaciones basadas en tecnología web
que permiten usar funciones nativas de ciertas librerías compatibles.

2.6.3 Aplicación web


Es la aplicación más genérica. Se puede acceder a los datos consultados a través de un navegador web con el
enlace de la aplicación o también se puede interactuar con el hogar de forma remota. Se puede utilizar en
dispositivos con o sin sistema operativo, desde móviles antiguos o televisores SmartTV con sistema operativo
propio hasta los dispositivos con tecnología más avanzanda.
22 Estado del arte

2.6.3.1 HTML Y CSS

El lenguaje HTML se utiliza para maquetar una página web. CSS son hojas de estilo donde se pueden crear
diseños que pueden ser escalables a cualquier resolución de pantalla. En conjunto HTML y CSS sirve para
diseñar una interfaz web, desde HTML se maqueta una estructura básica, se genera el contenido, los enlaces
etc. Mientras que desde las hojas de estilos CSS, se les da color y forma a la maquetación.

2.6.3.2 PHP

Al igual que ocurre con los webservices, desde PHP se podrá acceder a la base de datos para ofrecer la
información que generan los sensores. Permite generar nuevos contenidos y estructuras compatible con el
código HTML y CSS.

2.6.3.3 JAVASCRIPT

Para integrar PHP dentro de HTML es necesario el uso de JavaScript, el cual mediante llamadas AJAX puede
acceder a PHP y obtener los datos requeridos y mostralos en formato en HTML o para generar gráficas.
Disponiendo de un servidor NodeJS se puede eliminar el paso intermedio de PHP para acceder a la base de
datos al ser un lenguaje del lado del servidor, ahorrando tiempo en el acceso y aumentando la seguridad.

2.7 Estado del arte


Existen varias soluciones para a la automatización de una vivienda, algunos ejemplos de estas soluciones a
nivel comercial y no comercial son las siguientes.

2.7.1 OpenDomo
Nace en 2006 con el objetivo de crear una comunidad para el control de instalaciones, basadas en sistemas
open-source. Que forma parte del desarrollo de diferentes proyectos hardware/software en este ámbito. Bajo
estos proyectos se pueden encontrar una serie de productos y software tanto en ámbito profesional como no
comercial. Su principal gama de productos son medidores de corriente (monofásica y trifásica), así como
dispositivo de controles autómatas para iluminación, riego y domótica en general.
La ventaja es que es un sistema totalmente desarrollado y en continuo avance debido a su comunidad. Se trata
de un sistema modular, por lo que se necesitará varios de estos dispositivos para generar un sistema final,
implementando pasarelas y autómatas en cada uno de los nodos, lo cual en ciertas circunstancias es excesivo
cuando se tienen pocos dispositivos que controlar y pocos sensores.

2.7.2 Casa Jasmina


Proyecto de domótica impulsado por Arduino LLC. Se trata de un proyecto piloto que lleva dos años en
desarrollo de un espacio totalmente conectado a internet. Desde el uso de estructuras inteligentes, desarrollo de
elementos para jardines o incluso mobiliario inteligente.
Es un edificio abierto donde la comunidad puede desarrollar sus productos orientados a IoT que se encuentra
en Italia y durante estos dos años ha recibido casi medio centenar de proyectos diferentes. Basado en estos
proyectos, que son totalmente independientes con el fin común de desarrollar una casa inteligente open-source.
Red de sensores para monitorización inteligente de vivienda 23

2.7.3 OpenHab
Se trata de una interfaz para gestionar los dispositivos conectados a una casa automatizada, no se dedica ni se
relaciona con el hardware. Es una aplicación pensada para instalarse en un ordenador, Smartphone, o raspberry
PI/ Beaglebone, aunque siempre como gestor de contenidos. Es una aplicacion open-source compatible con
otros sistemas como Xively. Es un sistema visual o “front-end”, por lo que no se tiene que adaptar todo el
software y el sistema de comunicación de acuerdo a sus estándares para su correcto funcionamiento, sino que
solo se tendría que adaptar el hardware utilizado.

2.7.4 Domoticz
Es un sistema similar a OpenHab, un sistema open-source multidispositivo que está preparado para todas las
plataformas donde gestionar y almacenar los datos generados con el hardware. Está dirigido a personas con un
alto conocimiento en programación ya que está orientado a que sea el usuario el que compile el sistema en
función de las necesidades del mismo. Tiene una versión instalable que se puede configurar mediante un
sistema de programación en bloque del estilo de scratch.

2.7.5 PiDome
Sistema open-source que busca la domotización completa del hogar a partir del uso de Raspberry Pi en todo el
sistema. Dispone de servidores donde almacenar los datos proporcionados por los clientes y ofrecerlos
mediante un entorno gráfico al acceder al servidor HTTP que contiene la misma. Aunque existe una versión
estable, se encuentra en desarrollo para completar el sistema con nuevos sistemas de comunicaciónes o nuevas
shields de sensores. El principal problema de este sistema es que está basado únicamente en rapsberry PI, por
lo que será difícil personalizar el Hardware para obtener un dispositivo pequeño y discreto.
25
26 Desarrollo del Hardware

3 DESARROLLO DEL HARDWARE

Cualquier tecnología suficientemente avanzada es


indistinguible de la magia.
- Arthur Clarke-

l objetivo del proyecto es crear una red de sensores para domótica, completándose con un sistema de

E alarma. Este pretende ser un sistema completo, desde la creación de los nodos físicos hasta el
desarrollo de la interfaz con el objeto de tener un sistema personalizado. Los componentes que se van
a utilizar se basan en elementos y placas de origen open-sourse. Se pretende dar uso a esta red en una casa de
cuatro habitaciones, donde se tendrá un único nodo central y tres nodos periféricos. Por lo que se creará un
sistema centralizado, aunque cada nodo podrá tener inteligencia propia de actuación si se implementase. Se
podrá conectar tantos nodos periféricos como el módulo de comunicación que utilizamos lo permita.
Los nodos periféricos estarán exclusivamente destinados a tomar datos de medida y comunicarlos al nodo
central. Mientras que el nodo central se encargará de recabar toda esta información, generar la información de
los sensores y la comunicación con internet. Debido a que el sistema incluye alarma, desde el nodo central se
podrán identificar los habitantes mediante tarjetas RFID Mifare.
Se pretende utilizar una “Raspberry Pi 3 Model B” como servidor, para simular el uso de un servidor
comercial real o virtual.

3.1 Descripción de necesidades Hardware


En el sistema domótico que se plantea en el proyecto, se deben de cumplir una serie de requisitos cuyo
objetivo es mantener un estado de bienestar. Para cumplir dicha necesidad se debe configurar una red de nodos
instalados en las habitaciones de una vivienda. Los nodos deben estar formados por los sensores necesarios
para medir la temperatura, la humedad y la luminosidad. Al menos uno de los elementos de esta red debe tener
conexión a internet para poder transmitir la información de todos los sensores a una base de datos.
Debe cumplir que haya un registro de presencia en la vivienda. Por lo que el conjunto de los nodos debe
detectar la presencia de personas y la gestión de entradas y salidas de personas en la vivienda. Tal que si todas
las personas con acceso permitido salen del hogar el sistema arme la alarma, la cual debe empezar a sonar
cuando se detecte a una persona sin acceso permitido a la vivienda.
Englobaría la creación de una interfaz web que permita el acceso a los datos, así como la gestión de los
diferentes nodos o datos de acceso. Pudiendo agregar y eliminar nodos y accesos permitidos. Los datos
registrados por los sensores no son sensibles por lo que pueden ser mostrados sin la necesidad de introducir
una contraseña. Además se debe poder mostrar un histórico de estos datos en un rango de fechas a elegir por el
usuario. Los nodos, accesos y alarma solo pueden ser gestionados por el administrador de la red de sensores,
por lo que debe tener un acceso seguro mediante un usuario y contraseña.
Red de sensores para monitorización inteligente de vivienda 27

Como valor añadido, sin ser un elemento indispensable del sistema, puede avisar por e-mail de las entradas y
salidas de las personas con acceso, así como informar si la alarma está armada, desarmada o sonando.
Teniendo en cuenta las necesidades descritas, la mejor opción es realizar una red centralizada compuesta por
dos tipos de nodos, el nodo periférico y el nodo central. La finalidad del nodo periférico sería la lectura de
datos del sensor y el envío de esta información al nodo central. Tendría una función adicional de enviar todos
los datos recibidos al webservice así como los producidos por el propio nodo central y activar la alarma si
fuera necesario con un control de accesos.

3.1.1 Nodo central


El nodo central es el encargado de comunicar todos los datos entrantes y de llevarlos al servicio web. La
opción de utilizar una red existente evita el desembolso económico mensual por mantenimiento y gastos que
suponen otros sistemas. Por ello, para realizar una conexión con acceso a internet se puede utilizar tanto una
versión con cable Ethernet o bien una versión inalámbrica mediante WiFi. Debido a que el acceso mediante
WiFi permite mayor movilidad del nodo se utilizará para el proyecto la shield de arduino “Arduino WiFi
Shield”.
Se necesita una conexión con el resto de los nodos, esto se realizará mediante xBee, por ello se utilizará la
“Wireless SD Shield” de arduino.cc, junto con un módulo “Digi xBee Pro Serie 2”.
El uso de shields para Arduino está orientado a ser usado con una placa de Arduino. Por lo que las versiones
más económicas de estas placas son suficiente. Por lo que selecciona la versión de arduino “Arduino UNO
rev.3”
Además de las conexiones deberá tener una shield con sensores y actuadores.

3.1.1.1 Sensor PIR

Se utilizará un sensor PIR genérico. Este sensor se trata de un sensor digital con microcontrolador integrado, se
configura la sensibilidad del sensor mediante un potenciómetro. Está basado en la detección de movimiento.
Por lo general, siempre que se produzca un movimiento significa que algo o alguien realiza ese movimiento. Si
existe movimiento de algún objeto significa que alguien realiza ese movimiento, aunque un movimiento de la
tierra o del edificio (por ejemplo un fuerte choque con alguna de sus paredes) puede genera un movimiento,
por ello, cuando se detecte se realiza una segunda lectura transcurrido un tiempo, si este sigue dando positivo
mandará una trama al nodo central.

3.1.1.2 Sensor de temperatura y humedad DHT11

Se trata de un módelo de sensórica tanto para temperatura como para humedad. Tiene la ventaja de ser fácil de
utilizar debido a la comunidad de arduino y un precio muy bajo. En cambio tiene mala resolución tanto en
temperatura como en humedad. Pero como se trata de un proyecto de lectura de datos sin actuación este error
queda dentro del alcance del proyecto.

3.1.1.3 Sensor de luminosidad

En este caso se utiliza una resistencia sensible a la luz (LDR), de esta forma, en función de la luz incidente se
podrá estimar la iluminación de la habitación. Apenas necesita electrónica adicional para su uso, pero necesita
unos cálculos así como una calibración para hallar la lectura en unidades Lux.
28 Desarrollo del Hardware

3.1.1.4 RFID

Se dispondrá de un módulo cuya única función es detectar las tarjetas RFID y mandar la información al
webservice, donde estará la lógica de activación de la alarma.

3.1.1.5 Relé

Se trata de un actuador necesario para poder encender la sirena. Un relé es un actuador que sirve de interruptor
controlado mediante una señal eléctrica, dispone de dos conectores como entrada de señal y de tres conectores
para su salida (CC o conector común, NO o normalmente abierto y NC o normalmente cerrado).
En reposo el CC se encontrará conectado a NC, al introducir una señal de 5V CC pasará a conectarse a NO.

3.1.2 Nodo periférico


Necesita la conexión xBee y los sensores a utilizar. Por ello una buena posibilidad es usar el Arduino FIO, ya
que integra el socket para xBee y es totalmente compatible con los módulos xBee PRO Serie 2 que se utilizan.
Además para los sensores se fabricará una shield específica que contendrá los sensores PIR, DHT11 y LDR.

3.2 Nodo periférico


Con el avance del proyecto se concluyó que se
debían utilizar tantos nodos como habitaciones tenga
el usuario en su vivienda, de esta forma se puede
adaptar a todo tipo de viviendas con un máximo de
253 habitaciones diferenciadas.
Debido a las necesidades básicas del nodo
periférico, se utilizará un arduino FIO, con un
módulo de comunicación xBee PRO Serie 2 como
canal de comunicación con el nodo central. Para la
medida de los sensores se utilizará una shield propia
que agrega un sensor de temperatura y humedad
DHT 11, un sensor de presencia por infrarojos
genérico (PIR) y un LDR GL5528.

Figura 3-1 – Nodo periférico


3.2.1 Microcontrolador
El arduino FIO utiliza un microcontrolador Atmel ATmega328p con el bootloader de arduino FIO
preinstalado. Que permite el modo hibernación aumentando así la autonomía del sistema, esto se produce por
la gestión de la batería y la programación del microcontrolador a bajo nivel.

3.2.2 Módulo de comunicación


Como se ha comentado se utilizará un xBee PRO Serie 2 aprovechando el zócalo incluido en la placa de
desarrollo arduino FIO. Este módulo irá programado en modo API como router. Además para aliviar el
consumo se utilizará el modo Sleep del módulo de comunicación, de tal forma que se pueda dormir y despertar
este cuando se desee con el uso del pin DTR, que se incluye en la placa de desarrollo.
Para la comunicación entre el microcontrolador y el módulo de comunicaciones es necesario el uso del puerto
serie. Para facilitar su programación se utilizará la librería de xBee para arduino, el uso de esta obliga a tener
una configuración específica en el módulo xBee. Para realizar esta configuración se utiliza el programa XCTU
que proporciona el fabricante de modulos xBee “digi”. Este no funciona con el arduino FIO al necesitar un
Red de sensores para monitorización inteligente de vivienda 29

cable FTDI para conectarlo con el ordenador. Por lo tanto se debe configurar el módulo xBee mediante el
arduino UNO con la Wireless SD Shield. Para que el arduino no interfiera con el puerto serie, es necesario
instalar un firmware vacío. Es necesario conectar el pin DTR con GND para configurar que el módulo pueda
hibernar en modo router.
Una vez abierto XCTU el programa debe reconocer el módulo de comunicación, para ello se establece el
baudrate configurado en el módulo, generalmente 9600 bauds, sin embargo, al haber sido utilizado este
módulo previamente se utilizará 115200 bauds.
Se seleccionará el puerto serie tal como se puede observar en la figura 3-2 se seleciona el puerto COM 4. Y se
pulsa sobre el botón “test/query modem”. Habrá que esperar hasta que aparezca un mensaje similar al
mostrado en la figura 3-2 (A). Una vez XCTU haya reconocido el módem, en la pestaña “modem
configuration” se definirá las características del módem. En este caso no hace falta modificar ninguna
característica ya que como se observa en la figura 3-2 (B), este está configurado. Para configurarlo desde cero
sería necesario buscar en function set “ZIGBEE ROUTER API” y pulsar sobre el botón Restore.
A partir de este momento se puede configurar el módem xBee. En primer lugar el “PAN ID” funciona mejor
cuando es definido por lo que se utilizará el “PAN ID = 0x1AAA”. Aunque es posible dejar esta configuración
libre. Para identidicar el módem se puede utilizar una etiqueta llamada Node Identifier, en este caso este recibe
el nombre de “XBEEARDU3” aunque se puede nombrar como se desee. Una de las partes más importantes
dentro de la configuración es la selección del baud rate, que será de 115200 bauds. En este caso esta velocidad
esta definida con el numero 7 “BD = 7 - 115200”.
Para utilizarse mediante el uso de librerías es necesario que esten en modo API en lugar de Comandos AT. Por
ello además de configurar el function set como modo API es necesario establecer el registro “AP=2” como
requisito adicional de la librería. Para hibernar el módem el registro SM se debe de seleccionar como “SM = 1
PIN HIBERNATE”.
Tras esta configuración se seleccionará el tick “Always Update Firmware” para actualizarlo si fuera necesario
y sobre el botón write para escribirlo en el módem. Si se ha cambiado el baudrate no podrá comprobar si se
realizó el cambio correctamente ya que no está sincronizado, por ello es necesario realizar el primer paso para
leer los datos de configuración del módem con el nuevo baudrate y comprobar que no existe ningún problema.
Adicionalmente para amplificar la señal se utilizará una antena de 5 dB, lo que permite establecer una
comunicación desde cualquier parte del edificio sin interferencias.

Figura 3-2 – XCTU (A) Descubrimiento un xBee, (B) Configurando un xBee


30 Desarrollo del Hardware

3.2.3 Shield de sensores


Es una tarjeta PCB que se puede conectar directamente al arduino. Ha sido creada para este proyecto con el
software Eagle. Está diseñada para un arduino FIO e incluye un módulo DHT 11 para la lectura de tempetura y
humedad, un LDR para la lectura de luminosidad, y un detector de presencia por infrarojos PIR.

3.2.3.1 DHT11

Se trata de un sensor digital que mediante un protocolo


propio proporciona información acerca de la temperatura y
humedad. En el datasheet se puede apreciar el
funcionamiento de dicho protocolo.
Al tratarse de un único pin de transmisión asíncrona, el
controlador del DHT11 estará siempre a la escucha salvo que
se indique lo contrario. En estado de reposo el
microcontrolador escribe un uno constante, cuando se quiere
recibir un dato este escribe un cero y posteriormente se pone
en modo lectura a pull up, de tal forma que es ahora el
DHT11 quien escribe sobre la línea de datos, enviando así
toda la información referente a los sensores de humedad y Figura 3-3 – Conexión del sensor DHT11
temperatura.
Para su comunicación se dispone de cuatro pines que irán conectados siguiendo la figura 3-3.
En el desarrollo del firmware para las lecturas de temperatura y humedad se ha utilizado una librería para
arduino y una placa donde se pasará de utilizar de cuatro pines a tres pines para simplificar su uso.
La librería permite crear una instancia a un objeto DHT11 que almacena dos variables con la información de la
humedad y la temperatura de la última lectura realizada. Este objeto permite identificar si está conectado el
microcontrolador, así como realizar lecturas cuando el microcontrolador principal lo estime necesario.

3.2.3.2 PIR

Para la detección de presencia se utiliza un sensor infrarrojos o PIR genérico. Se basa en la emisión de luz
infrarroja producida por el calor corporal de los seres vivos, por ello este sensor puede detectar presencia,
aunque no será capaz de saber diferenciar si se trata de personas o animales. Estos sensores tienen dos tipos de
funcionamiento, el primer tipo emite un único pulso con una duración que se puede controlar con un
potenciómetro y el segundo se pone a un nivel alto cuando detecta presencia y no baja hasta que esta no haya
desaparecido. En la realización de este proyecto se utiliza este último modo.
Este tipo de sensores están compuestos por una cúpula
de plástico, que funciona como lente y filtro. En la
figura 3-4 se puede apreciar la vista inferior del sensor
PIR que se utiliza en este proyecto. El jumper permitirá
seleccionar el modo de funcionamiento, si se usa el
modo High (pin central con el pin superior) funcionará
en modo pulso y si se usa en modo Low (pin central
con pin inferior) el sensor funcionará en modo
continuo, si detecta presencia se pondrá a uno.
Existen dos potenciómetros el de la izquierda que
permite establecer el tamaño del pulso, que no se tendrá
en cuenta ya que el sensor está configurado en modo
continuo. Mientras que el de la derecha permite Figura 3-4 – Vista inferior de un sensor PIR
controlar la sensibilidad, que se debe ajustar para no
Red de sensores para monitorización inteligente de vivienda 31

detectar presencia en el exterior del hogar.

3.2.3.3 LDR

Se utilizará para medir la luminosidad, se trata de un LDR GL5528. Se trata de una


resistencia que varía desde 1 Mohm (en oscuridad) y 2 KOhm (100 Lux). Por lo tanto para
conocer la luminosidad es necesario medir el valor de resistencia del LDR. En la figura 3-5
se puede ver como se utiliza un divisor de tensión. De esta forma arduino leerá un valor de
voltaje que se traducirá a Ohm para poteriormente pasarse a luminosidad siguiendo las
siguientes ecuaciones teóricas.
Para poder realizar una lectura en unidades “Lux” será necesario hacer unos cálculos con la
señal leída. Arduino lee una señal entre 0 y 1023, en función de su referencia analógica y del
voltaje de la señal leída. Para saber cuantos Lux corresponden hay que basarla en la figura
3-5, donde es necesario trabajar en unidades de resistencia (ohmios).
Por lo tanto lo primero que se debe calcular es el voltaje leído. Que se puede hacer Figura 3-5
realizando una regla de tres.

𝑉𝑟𝑒𝑓 × 𝐿𝑒𝑐𝑡𝑢𝑟𝑎
𝑉𝐿 =
1023

Donde VL es el voltaje que hemos leído, Vref es el voltaje de referencia y Lectura es el valor leído,
comprendido entre 1 y 1023. Mediante el uso de la figura 3-5, el divisor de tensión y conociendo el valor de la
resistencia R1 y del voltaje de alimentación VS, se puede saber el valor de la resistecia RLDR del LDR.

𝑉𝑆 − 𝑉𝐿
𝑅𝐿𝐷𝑅 = × 𝑅1
𝑉𝐿

Una vez se tiene el valor de la resistencia hay que linealizar la gráfica en una función para obtener la
luminosidad en Lux en función del valor leído. Debido a que se trata de una gráfica logarítmica se tendrá que
trabajar con potencias y logarítmos.
𝐿
log 10 𝐿𝐷𝑅 −𝐵
1000
𝐿𝑢𝑚𝑖𝑛𝑜𝑠𝑖𝑑𝑎𝑑 𝐿𝑢𝑥 = 10 𝑀

Figura 3-6 – Gráfica Lux en función de la resistencia LDR


32 Desarrollo del Hardware

Siendo M el valor de la pendiente y B el valor del offset necesario para la linealización de la figura 3-6. Como
se puede observar existe un error importante, por lo que se trata de un valor aproximado calculado por el punto
medio, el cual no tiene porque ser el valor típico.
Los valores M y B para este LDR son M = -0.715335279 y B = 1.817398, en esta placa VS=Vref=3.3 V . Por
último para maximizar el rango de este LDR se utiliza una resitencia R1 = 22 KΩ.

3.2.3.4 Diseño de la PCB

Se ha optado por diseñar una shield en el programa Eagle, por ser uno de los programas de diseño de PCB más
extendidos y por su licencia gratuita a estudiantes. Existen otros programas, también con licencia gratuita y
algunos con mejores prestaciones que Eagle, como kicad, pero en Eagle existen una gran cantidad de librerías,
lo que permite en muchos casos no tener que crearlas.
Esta shield tiene un diseño simple con dos elementos soldados y sockets para DHT11 y PIR. Por lo tanto no se
requiere de ningún tipo de librería externa de Eagle. En las figuras 3-8 se muestra el esquemático y en la
figura 3-7 la PCB en su parte inferior, ya que tan solo se necesita de una cara de cobre.

Figura 3-7 – PCB de la shield del nodo periférico

Figura 3-8 – Esquemático de la shield del nodo periférico


Red de sensores para monitorización inteligente de vivienda 33

3.2.3.5 Fabricación de la PCB

Para ello se ha optado por el método de la transferencia por calor. Al tratarse de una única capa este método es
adecuado. Se trata de un método económico que permite la fabricación de PCB con una calidad óptima,
siempre que no se requiera de varias capas o vías entre las mismas.
Este método consiste en transferir la tinta de una impresora láser al cobre. La tinta funcionará como protector
del cobre frente al ataque químico. Para entender como ocurre esta transferencia es necesario conocer como
funciona una impresora láser.
En primer lugar, la impresora láser calienta el papel sobre la zona donde se quiere que quede pintado,
posteriormente pasa por un rodillo precalentado con tinta (realmente es una fina capa homogénea de un polvo
muy fino). Esta tinta quedará adherida en la zona previamente calentada. Esta impresión de la PCB debe
realizarse sin modo espejo ya que al tratarse de la capa botton (o inferior) se invetirá en el siguiente paso.
Para realizar la transferencia se enfrenta la capa impresa del papel con la cara de cobre de la PCB virgen con
cuidado para que no quede ningún tipo de arruga ni burbuja. En este proyecto se ha utilizado pegamento en
una zona externa a la PCB para no dañar el diseño, de esta forma no quedan arrugas en cada pasada por la
máquina.
Al pasar por el rodillo se calentará todo el cobre, quedándose la tinta adherida al punto más caluroso, es decir
en el cobre. En condiciones normales se tendría que pasar la PCB al menos tres veces por la máquina, ya que
menos veces podría significar que no se adhiera toda la tinta al cobre. Pero no es recomendable hacer este paso
más de seis veces, esto podría producir un aplastamiento de la tinta produciéndose cortocircuitos no deseados.
Con un poco de agua sin utilizar ningún tipo de jabón se retirará el papel de la PCB, que habrá quedado
pegado al mismo por el calor recibido. Este proceso hay que realizarlo con cuidado para que no se las pistas.
Se utilizará una máquina plastificadora modificada para tener una temperatura estable, en torno a los 200º
grados. Y para facilitar la transferencia se utilizará papel satinado.
Para la realización del ataque se utilizará, en proporciones iguales, agua, peróxido de hidrógeno, ácido
clorhídrico 110%. Este último es el responsable de eliminar el cobre, no obstante, para que se produzca este
ataque es necesario el peróxido de hidrógeno como principio activo. El agua se utiliza para rebajar la fórmula y
hacer que el ataque sea más lento y con mayor control.
Una vez finalizado el ataque, con jabón neutro y estropajo metálico se limpiará la placa hasta tener todo el
cobre visible y libre de tinta. En este momento estará todo preparado para taladrar la placa mediante una
herramienta tipo Dremel o taladro de mano y por último se soldarán los componentes.

3.3 Nodo Central


3.3.1 Microcontrolador
Para este nodo se utilizará un arduino UNO
basado en el Atmel ATmega328p. Este nodo
recibirá toda la información procedente de los
nodos periféricos y de internet a través de la
plataforma. Los requerimientos del sistema
hacen que en este nodo no pase a modo
hibernación.
Toda la información recibida desde los nodos
periféricos será comunicada inmediatamente al
servicio web creado para almacenar toda la
información en la base de datos. Esta
comunicación se realizará mediante MQTT,
para ello se utilizará la librería “pubsubsclient”
para arduino que permitirá gestionar las
publicaciones y subscripciones MQTT.

Figura 3-9 – Nodo central


34 Desarrollo del Hardware

3.3.2 Módulos de comunicación

3.3.2.1 xBee

La placa de desarrollo arduino UNO no dispone de zócalo para los módulos xBee, por lo que será necesario
una shield para esta función, la “Arduino Wireless SD shield”. Esta además de cumplir estos requisitos
gestiona una tarjeta microSD, aunque no será necesaria para este proyecto. Para poder realizar una correcta
comunicación con los nodos periféricos el módulo xBee debe de ser del mismo tipo. En este nodo será xBee
PRO serie 2, configurado como “Coordinator” por asumir funciones de coordinador de la red.
El nodo central es el encargado de generar una
dirección de red, la cual será trasmitida al resto de los
nodos mediante el protocolo de conexión de xBee.
Este nodo está destinado a estar a la espera de recibir
todos los mensajes por parte de los nodos periféricos,
por este motivo no pueden hibernar.
Para su configuración se realizan las mismas acciones
que en el apartado homónimo del nodo periférico a
excepción de dos claras diferencias además del NI
(identificador del módem). En primer lugar que si
utilizará el firmware “ZIGBEE COORDINATOR
API” en lugar del “ZIGBEE ROUTER API” en el
funtion set, se ignorará el registro correspondiente a la
Figura 3-10 – Arduino Wireless SD Shield hibernación de módem, ya que ni siquiera está
disponible al seleccionar el nuevo firmware.

3.3.2.2 WiFi

La comunicación del nodo central al bróker se realiza


mediante WiFi, se debe crear una conexión TCP/IP
mediante una conexión a Internet. Al utilizar el arduino
UNO como base para el nodo central, se elige la
“arduino wifi shield” para crear esta conexión. Este
incluye la gestión de tarjetas SD, aunque no se necesita
para este proyecto. Esta shield se comunica por SPI con
arduino por lo que debe ser la primera en acoplarse al
arduino. El pin digital 4 corresponde tanto en esta shield
como en la Wireles SD shield al control de la tarjeta SD,
por lo tanto, para evitar su uso no se conectará al
arduino.
La wifi shield viene de fábrica con un firmware
específico para conexiones con redes sin DHCP, aunque
Figura 3-11 – Arduino WiFi Shield
supone una mayor seguridad dentro de la red, tiene una
configuración bastante tediosa. Desde la web de arduino se proporciona una guía detallada en donde explica
como actualizar el firmware y poder así conectarse a una red con DHCP [50]. Para ello hay que instalar el
programa flip que proporciona Atmel y conectar el jumper J3. Se conecta la wifi shield ordenador por el puerto
mini-USB de la placa y se ejecuta el siguiente comando en la línea de comandos de windows.

batchisp.exe -device AT32UC3A1512 -hardware usb -operation erase f


memory flash blankcheck loadbuffer
/Arduino/hardware/avr/arduino/firmwares/wifishield/binary/wifi_dnld.el
f program verify start reset 0
Red de sensores para monitorización inteligente de vivienda 35

Se optó por un sistema de subscripcion mediante el protocolo MQTT ya que era necesario un enlace
bidireccional. Esto conlleva una complejidad dentro de la programación del firmware del arduino UNO. La
librería “pubsubsclient.h” permite utilizar este protocolo de una manera sencilla utilizando la librería integrada
desde el IDE de arduino para la gestión de las conexiones WiFi.

3.3.3 Shield de sensores


Se toma como referencia todos los componentes utilizados en la shield de sensores para los nodos periféricos
para su desarrollo, por ello para obtener más datos acerca del DHT11, PIR o LDR se puede acudir a los puntos
3.1.1.3.1, 3.1.1.3.2 y 3.1.1.3.3 respectivamente. A diferencia del periférico, este nodo tiene que estar preparado
para activar una alarma y un sistema de control de accesos. Para lo que se utilizará un zumbador para la alarma
y un módulo RFID RC522 para el control de accesos.

3.3.3.1 RC-522

Es un módulo que permite leer y escribir tarjetas RFID del tipo Mifare.
Este permite comunicarse con la placa arduino mediante el protocolo SPI,
UART o I2C e incluye una antena RF. Para identificar de forma única una
tarjeta Mifare se lee el número de serie de la tarjeta. En este proyecto se
realiza la comunicación mediante SPI. Tiene una transferencia de hasta 10
Mbit/s y funciona a 3.3V por lo que no habría problemas para
comunicarla con arduino. La conexión de los pines SCK, MOSI, MISO,
3V3 y GND deben coincidir con sus homónimos en la placa arduino. El
Figura 3-12 - Módulo RC-522
pin de señal de datos o SS está conectado al pin D6 del arduino mientras
que el pin de reset o RST lo está al pin D8.
Las tarjetas Mifare tienen la capacidad de almacenar entre 1 KB y 4 KB de información. Pero solo se
necesitará leer el identificador único de la tarjeta.

3.3.3.2 Alarma

En este proyecto se utilizará un relé que activará una sirena. El esquema para conectar el relé está basado en un
transistor MOS tipo n, que incluye un diodo de protección de corriente inversa que podría producir un bucle,
algo muy negativo para el circuito y el relé. A nivel de programación, utilizar un relé sería un actuador con
pull-down, el controlador debe ponerse en nivel alto para funcionar. El relé es instalado en la shield mediante
el uso de cables de conexión macho-hembra soldados a la PCB a modo de extensión de los propios pines con
la finalidad de facilitar la instación de la sirena.

3.3.3.3 Diseño de la PCB

Para su diseño se usará Eagle, utilizando como base de la PCB los pines de la placa arduino UNO. A
continuación se muestra un esquemático de los componentes y de la capa bottom de la PCB. Está compuesto
por módulos preconstruidos a excepción del detector de luminosidad.
36 Desarrollo del Hardware

Figura 3-13 – PCB de shield del nodo central

Figura 3-14 Esquemático de la shield del nodo central


Red de sensores para monitorización inteligente de vivienda 37

3.4 Servidor web, base de datos, Bróker MQTT y Node.js


La simulación de un servidor web se hace con una “Raspberry Pi 3 Model B” con sistema operativo Raspbian
Jessie (Debian optimizado para dispositivos Raspberry Pi) sin escritorio. Se ha instalado un servidor SSH y
SFTP para acceder al Sistema Operativo de forma remota solo en Red Local, optimizando la seguridad del
sistema. A partir de este momento se hará referencia a esta raspberry pi como el servidor del sistema o
simplemente como el servidor.
Durante la instalación de la raspberry sin entorno gráfico se configura automáticamente el servicio SSH y
SFTP sin la necesidad de instalar ningún elemento adicional.

3.4.1 Servidor web y base de datos


Es necesario disponer de una base de datos para la gestión de la información mandada por los sensores y para
almacenar la configuración deseada por los usuarios. Para ello se ha instalado un servidor web Apache2, una
base de datos mySQL en el servidor y una interfaz de usuario para trabajar sobre la base de datos,
phpmyadmin. Para esta configuración es necesario instalar el servidor web mediante líneas de comando, más
adelante se describe el proceso realizado.
Para evitar escribir sudo al principio de cada instrucción acceder al modo administrador mediante el siguiente
comando.

$sudo su

Hay que crear un grupo determinado www-data para instalar el servidor. En esta distribución de raspbian
(jessy lite) viene creada y configurada, por lo que se puede proceder directamente a la instalación del servidor.
Para obtener la última versión de todos los componentes y servicios a instalar se actualizan las listas y los
servicios mediente los comandos.

$apt-get update
$apt-get upgrade

Como base de todo lo que se pretende instalar para obtener los servicios necesarios en el proyecto hay que
instalar apache2. Este es el servicio web que permitirá mostrar una página web básica en HTML5 con hojas de
estilos CSS3 y javascript.

$apt-get install apache2

Como es necesario utilizar php hay que instalar php5, con esto ya se tendría un servidor web con páginas
dinámicas mediante el uso de PHP en su última versión. Se pretende utilizar junto con apache y mySQL, por
lo que se instalan los componentes necesarios para que puedan interactuar.

$apt-get install php5


$apt-get install libapache2-mod-auth-php5 php5-cli php5-common php5-
dev php5-mysql

Para que se haga efectiva la instalación de estos complementos se ejecuta el comando “reboot”, que reniniciará
el servidor.

$reboot
38 Desarrollo del Hardware

Una vez reiniciado el servidor se instalará la base de datos mySQL y el cliente mySQL

$apt-get install mysql-server mysql-client

Durante la instalación del servidor se pedirá el nombre de usuario administrador de la base de datos, root por
defecto y la contraseña deseada. Una vez finalizada la instalación será necesario volver a reiniciar el servidor,
en adelante ejecutar el comando reboot será mencionado como reiniciar el servidor.
Tras reiniciarlo solo queda instalar phpmyadmin para gestionar la base de datos mediante el uso de una página
web. Durante la instación pedirá que se introduzca el usuario y contraseña de la base de datos mysql.

$apt-get install phpmyadmin

Para poder configurarlo y acceder desde una página web se debe modificar el archivo de configuración de php.

$nano /etc/php5/apache2/php.ini

Una vez abierto, al final del código se añade una línea con lo siguiente:

extensión=mysql.so

Se guarda el archivo pulsando la tecla control y la tecla "x" simultáneamente, se aceptan los cambios y no se
debe modificar el nombre del archivo. Finalmente se realiza una operación muy parecida a la anterior, en este
caso se accede al archivo de configuración de apache2.

$nano /etc/apache2/apache2.conf

Y de la misma forma que ocurre con el archivo anterior, al final del archivo se crea una nueva línea:

Include /etc/phpmyadmin/apache.conf

Por último se reinicia el servidor y ya se tiene el servidor web y la base de datos mySQL instalados. En cuanto
al uso de las tablas necesarias para el funcionamiento del proyecto será detallado en el sub-apartado backend
del capitulo 5 (Desarrollo Software).

3.4.2 Bróker MQTT


Sirve para dar soporte a los servicios MQTT. De esta forma se pueden crear tantas subscripciones como sean
necesarias. El bróker que se utiliza en este proyecto es el bróker Mosquitto. La elección de este bróker se debe
a que “Apache ActiveMQ Apollo 1.7.1” (apollo en adelante) requiere de JAVA para su instalación. Y
Mosquitto no necesita prácticamente nada adicional para funcionar, aunque su configuración es mas tediosa
que apollo.
Su instalación en el servidor se realiza mediante líneas de comando, ya que no se dispone de un escritorio. Para
realizar la instalación de Mosquitto en el servidor es necesario descargar y actualizar los repositorios.

curl -O http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
Red de sensores para monitorización inteligente de vivienda 39

apt-key add mosquitto-repo.gpg.key


rm mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
curl -O http://repo.mosquitto.org/debian/mosquitto-jessie.list
apt-get update

Una vez preparado mediante apt-get se instala Mosquitto y sus dependencias.

$apt-get install mosquitto mosquitto-client python-mosquitto

Tras la instalación se reinicia el servidor y el bróker se ejecutará adecuadamente. Este bróker no está
configurado para que sea necesario utilizar un usuario y una contraseña. Para poder instalar una nueva
contraseña será necesario utilizar un recurso que incluye Mosquitto para crear y codificar una pareja
usuario/contraseña.

$mosquito_passwd -b /etc/mosquitto/passwd.pw admin password

En este caso mosquito_passwd es el recurso que proporciona Mosquitto, -b permite poner usuario y contraseña
en la misma línea de comando, lo que simplifica su configuración, /etc/mosquitto/passwd.pw es la dirección
completa del archivo donde se almacena el usuario y la contraseña para acceder al bróker y por ultimo admin y
password son el usuario y la contraseña respectivamente.
Con esto se obtiene un archivo que almacena un usuario con su contraseña codificada, posteriormenete hay
que especificar al bróker que solo permita el acceso a los usuarios que existan dentro de este archivo y para
ello es necesario acceder al archivo de configuración.

$nano /etc/mosquitto/mosquito.conf

Al final del archivo hay que agregar las siguientes líneas:

allow_anonymous false
password_file /etc/mosquitto/passwd.pw

Tras reiniciar el servidor estará configurado el bróker.

3.4.3 Node.js
Para poder utilizar los servicios o daemons en Node.js es necesario la instalación de node y npm mediante apt-
get.

$sudo su
$apt-get install node
$apt-get install npm

Con estas instalaciones el servidor está preparado para ejecutar servicios programados en node. Y con npm se
pueden descargar librerías para utilizar entre otros mysql o mqtt.
40 Desarrollo del Hardware

Será necesario que el node se ejecute como un daemon, para simplificar este cometido se instala en el servidor
la aplicación forever para node. No obstante, será necesaria una instalación compatible con raspberry pi y por
ello se debe ejecutar el siguiente comando.

$sudo -i npm install forever -g

Para ejecutar un script en background se realiza con el siguiente comando

$forever start script.js


Red de sensores para monitorización inteligente de vivienda 41
42 Desarrollo del Firmware

4 DESARROLLO DEL FIRMWARE

La creatividad simplemente consiste en juntar cosas


- Steve Jobs-

l firmware es un software específico que se encarga de la programación correspondiente a la parte del

E hardware. Es programado en bajo nivel, generalmente en lenguaje Ensablador, C o como en este caso
Programing.
El firmware que está programado tanto en los nodos periféricos como en el nodo central se ha desarrollado con
el IDE de Arduino. Este IDE permite programar el microcontrolador de una forma muy sencilla ya que
permite una programacion a nivel relativamente alto, permitiendo abstraerse del uso de registros. El IDE de
arduino permite alternar la programación en programing, en C++ orientada a objetos y en C con programación
estructurada. De esta forma se pueden modificar los registros siempre que sea necesario o la programación lo
requiera, sin perder las ventajas de la programación con programing.
Debido a la extensa comunidad y a los propios desarrolladores de arduino existen cientos de librerías para
facilitar la programación de las placas arduino. Además se dispone de las librerías que facilita el fabricante de
estos microcontroladores, Atmel, que permiten usar funciones avanzadas tales como operaciones matemáticas
complejas, el uso del wachtdog o poner a hibernar el microcontrolador.
Se pueden distinguir tres tipos de librerías:
Librerías internas: son las que vienen preinstaladas en el IDE de arduino, no necesitan instalación y
se puede acceder desde el IDE de arduino. Estas librerías están realizadas por los desarrolladores de
arduino. Por lo general están diseñadas para utilizar elementos muy comunes, como SPI o I2C por
ejemplo, o para utilizar Shields propias, como la shield wifi o la shield Ethernet.
Librerías externas: son las desarrolladas por la comunidad, es necesaria su instalación, aunque una
vez instalada se puede acceder a ellas desde el IDE de arduino. Al estar desarrolladas por la
comunidad y tratarse de un recurso open-source, si lleva mucho tiempo en la red es difícil que tengan
algún error, ya que la propia comunidad está mejorando continuamente estas librerías. Es la principal
ventaja del IDE de arduino ya que casi todos los componentes o módulos genéricos disponen ya de su
propia librería para ahorrar tiempo y esfuerzo en la programación del firmware.
Librerías AVR: las que facilitan el fabricante del microcontrolador. No necesitan instalación, pero no
se puede acceder a ellas desde el IDE, sino que es necesario visitar la web del fabricante y ver que
librerías están disponibles para el microcontrolador que se está utilizando e invocarla de forma manual
al principio del código siguiendo el siguiente ejemplo.
Red de sensores para monitorización inteligente de vivienda 43

#include <avr/librería.h>

Este IDE se puede descargar de forma gratuita de la web oficial de arduino y está disponible para los tres
sistemas opertativos más importantes: Windows, Linux y MacOS.

4.1 Nodo periférico


La función de este nodo es la de leer los datos obtenidos de los sensores y transmitirlos al nodo central
mediante una comunicación inalámbrica xBee. El firmware está desarrollado en el entorno de programación
de arduino ya que simplifica notablemente su programación.

4.1.1 Sensores
El nodo periférico dispone de tres sensores, que generarán cuatro datos. Estos tres sensores son el sensor
digital, el sensor analógico y el sensor digital booleano.

4.1.1.1 Sensor de Luminosidad

Para la lectura del sensor de luminosidad, tan solo se leerá el pin de entrada analógico A0. Debido a la
dificultad de transmitir un dato con coma flotante, se ha decidido mandar el dato de la lectura correspondiente
a los valores entre 0 y 1023 que corresponden a 0 y 5 V respectivamente. Y será más adelante cuando estos
datos sean transformados a un valor de luminosidad en Lux.

4.1.1.2 Sensor de presencia

Es un sensor booleano por lo tanto su lectura corresponde al sistema binario „detecta‟ o „no detecta‟ algún tipo
de presencia. Cuando se recibe un nivel alto se considera que existe algún tipo de presencia.
Debido a que este sensor se utiliza en primera medida para el sistema de alarma, al detectar todo tipo de
movimiento de un cuerpo que genere temperatura propia (principio de funcionamiento del sensor de presencia)
deberá de saltar la alarma siempre que esta este activa.
Sin embargo debido a que un ladrón, en casos generales, no tarda menos de 30 segundos dentro del hogar, para
conseguir una mayor autonomía, se realizará esta lectura solo cuando el nodo sea despertado por el watchdog,
que como se verá a continuación será cada ocho segundos.
Para evitar algunas falsas alarmas producidas por movimientos indeseados o fallos en la lectura, se realiza una
nueva lectura cuando el módem este operativo después del tiempo de time up, si es positiva, la presencia es
real.
Debido a que el nodo periférico no tiene forma de detectar si está o no la alarma armada, el sensor volverá a
funcionar con normalidad. Este funcionamiento aislado solo se dará cuando se pasa a leer un nivel alto siendo
el último dato leído en un nivel bajo.

4.1.1.3 Sensor de Temperatura y Humedad

La lectura del sensor DHT11 proporciona datos acerca de la temperatura y la humedad, para ello se recurre a
una librería externa. Esta incluye un objeto que permite generar una lectura de ambos sensores, evitando tener
que controlar el pin D2 como entrada o salida según dicta el protocolo. Esta instancia del objeto se creará
mediante el siguiente código:
44 Desarrollo del Firmware

dht11 DHT11;

La función que se utiliza en este proyecto es int read(int pin) que devuelve un valor 0 cuando no ocurre
ningún error y -1 o -2 si ocurre un error de checksum o de tiempo de espera respectivamente. Como variable
de entrada se le dará el valor numérico del pin digital al que está conectado físicamente el sensor DHT11 a la
placa arduino. Esta función tal como se puede intuir por el nombre realiza una lectura de temperatura y
humedad, estas lecturas se almacenan dentro de las variables temperature y humidity respectivamente. Para
acceder a la función de lectura y las variables de la instancia se realizará del siguiente modo:

int chk = DHT11.read(2);


if (!chk) {
humedad = DHT11.humidity;
temperatura = DHT11.temperature;
}

4.1.2 Módulo de comunicación


Una vez obtenidos los datos de los sensores será necesario el envío de los mensajes a través de un módulo
xBee Pro Serie 2. Del mismo modo que ocurre con el sensor DHT11, para la gestión del módulo xBee se
utiliza una librería externa. El uso de este tipo de módulos suele estar gestionado por una serie de comandos
que reciben el nombre de comandos AT y son utilizados en la mayoría de módulos de comunicación. Por
desgracia, al igual que ocurre con las instrucciones en los microcontroladores, estos comandos AT no suelen
ser genéricos y cada fabricante utiliza su propio repositorio de comandos AT.
La librería xBee es bastante grande y abarca los diferentes tipos de módulos xBee comentados en el apartado
2.3.3, así como los diferentes modos de funcionamiento de estos módulos en cada una de sus versiones. Por
ello, se describen a continuación los objetos instanciados, las funciones y variables que se utilizan en el
desarrollo del nodo central.
En primer lugar es necesario instanciar la clase “xBee” que permite enviar y leer a través del microcontrolador,
esta se instancia mediante la llamada:

XBee xbee = XBee();

Los métodos del objeto XBee que se van a utilizar son send(ZBTxRequest zbTx), que permite el envío de
paquetes de datos al nodo central siguiendo una estructura propia de la librería, readPacket(tiempo), que leen
los datos recibidos durante el tiempo definido como variable de entrada, getResponse() que se utiliza para
conocer el resultado de la transmisión, y setSerial(UART), que sirve para establecer una conexión entre el
módulo xBee y el puerto UART indicado.
La estructura de la librería xBee que se va a necesitar a lo largo del programa es XBeeAddress64. Está
compuesta por dos enteros de 32 bits cada uno. Almacena una dirección mac de xBee pudiendo diferenciar
dos variables correspondientes a los 32 bits más significativos y los menos.

XBeeAddress64 addr64 = XBeeAddress64(0x0013A200, 0x40BAAB13);

Como se observa, para enviar datos se necesita una estructura especial que almacene la dirección del envío y la
trama de datos útiles que se desea enviar. Esta estructura es ZBTxRequest.

ZBTxRequest zbTx = ZBTxRequest(addr64, texto, sizeof(texto));


Red de sensores para monitorización inteligente de vivienda 45

Y por último para conocer si se ha recibido o no el paquete en el nodo central se utiliza la estructura
ZBTxStatusResponse.

ZBTxStatusResponse txStatus = ZBTxStatusResponse();

Durante el envío se puede controlar si los datos se han emitido correctamente, en contadas ocaciones, es
posible que este sea erróneo y se reitere constantemente, es por ello que sea necesario resetear la placa. Se
establece un máximo de cincuenta errores para producir este reseteo de software, que salta a la primera
posición de ejecución del programa.

void softReset()
{
asm volatile (" jmp 0");
}

4.1.2.1 Creación y envío de la trama xBee

Para que el servidor pueda parsear los datos de forma correcta se debe montar la trama formando parejas
“tipo=valor” separados por el carácter „&‟. Este tipo de trama es comúnmente utilizado en llamadas GET de
HTML. De hecho, debido a que al principio la idea era transmitir la trama a un webservice en PHP, se pensó
en montar la trama de tal forma que no hiciese falta el parseo desde el nodo central sino que se enviase
directamente al webservice.
Finalmente el envío se realiza por MQTT, por lo que el parseo podría realizarse de diversas formas entre ellas
esta misma. El nodo periférico es transparente al método de comunicación del nodo central con el servidor.
Un ejemplo de trama enviada:

TEM=25&HUM=41&LUZ=386&PIR=1

En el envío hay que especificar cual es la MAC destino en la que está almacenada la variable de tipo estructura
XBeeAddress64 llamada addr64.
Lanzando el mensaje send del objeto xBee se envía la trama. Como detalle importante acerca del
funcionamiento de xBee, el módem tarda hasta treinta segundos en su proceso de wake up desde que envía o
recibe una trama en modo sleep. Por ello, es necesario realizar un envío de una trama, la cual se sabe que no va
a llegar, treinta segundos antes de mandar la trama real. Tras despertar el microcontrolador del estado de
hibernación se manda la trama, durante esa espera se realiza la lectura y el maquetado de la trama. Pasado este
tiempo se envía la trama y se comprueba que ha llegado.

xbee.send(zbTx);
xbee.readPacket(1500);
err = xbee.getResponse().getErrorCode();
stat = xbee.getResponse().getApiId();
if (stat == 0 && err == 0) {
Serial.println("ERROR");
} else if (stat == 117) {
Serial.println("ERROR");
} else {
Serial.println("OK");
}
46 Desarrollo del Firmware

4.1.3 Gestión Energética


Una vez enviados los datos es necesario hibernar el microcontrolador y el módulo xBee para conseguir un
ahorro energético y prolongar durante meses la autonomía de los nodos periféricos.
En el módulo xBee hay que darle al pin DTR nivel bajo, el cual está conectado al pin D3 del microcontrolador.
La hibernación del microcontrolador es una tarea más compleja.
Al contrario de lo que ocurre con el resto de funcionalidades de arduino, no existe la posibilidad de hacer esta
tarea de manera simplificada. Pero existen librerías del fabricante que simplifican provocar la hibernación del
microcontrolador, aunque modificando algunos registros del mismo.
Si se hiberna el microcontrolador deberá existir una manera de interrumpir dicho estado. Por ello es necesario
el uso del timer watchdog incluido en el micrcontrolador. De la misma forma que ocurre con la hibernación
del microcontrolador hay que configurarlo mediante el uso de registros. En este caso no se utilizará la librería
ya que la gestión de estos registros es mas rápida y simple.

4.1.3.1 Hibernación del microcontrolador.

En la gestión de la hibernación se necesitará la librería sleep.h. Esta permite varios modos de ahorro energético
en función de las necesidades del programa ejecutado. En la figura 4-1 se muestra una tabla obtenida del
datasheet del microcontrolador, en ella se puede observar marcada con una “X” los componentes activos con
cada uno de los modos de ahorro energético.

Figura 4-1 – Posibles estados de ahorro de energía del Atmel ATmega328p

El modo de hibernación escogido para ahorrar energía es el modo “Power-Down”. Se recurre a la librería
power.h que proporciona el fabricante para apagar TWI elemento antes de poner el disposivo a dormir,
ahorrando de esta forma una mayor cantidad de energía. Si se apaga mediante este método los timers 0, 1 y 2 y
el SPI y ADC se consigue disminuir a la mitad el consumo energético.
En la hibernación del dispositivo es indispensable cambiar los registros necesarios para su preparación. El
fabricante da la opción de preparar el dispositvo con la función.

sleep_enable();
Red de sensores para monitorización inteligente de vivienda 47

Para que el dispositivo no se duerma por error hay que desactivar este modo mediante:

sleep_disable();

Se ha elegido un modo de ahorro energético con la función:

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

Antes de dormir el dispositivo es necesario apagar los componentes mencionados, para ello se ejecutan los
siguientes comandos:

power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_adc_disable();
power_twi_disable();
power_spi_disable();

Sin embargo, activar todos los componentes simultáneamente es más rápido mediante el comando:

power_all_enable();

Y por último se hiberna el dispositvo:

sleep_mode();

Al despertar, el dispositivo volverá a la siguiente línea, donde será necesario activar todos los componentes del
dispositivo y deshabilitar el modo sleep.
Todo este proceso se realiza con la función duerme(), para facilitar y agilitar la puesta del dispositivo a
hibernar.

4.1.3.2 WachtDog

Es un timer que sirve para liberar la ejecución cuando está por alguna razón, generalmente no deseada,
bloqueada o ha entrado en un bucle infinito. Su funcionamiento es bastante simple, cuando este contador
desborda reinicia el sistema y de esta forma la ejecución sale del bloqueo o del bucle infinito. Para evitar que
este contador desborde, durante la ejecución normal del programa este se restaura a cero en cada interacción
del bucle principal.
La función del wachtdog en este sistema es despertar al microcontrador cuando este se encuentre en modo
sleep, produciendo a su vez una interrupción en la ejecución del programa principal ejecutando una rutina de
interrupción, la cual, se ha definido para evitar que el microcontrolador apage o reinicie el sistema de forma no
deseada cada ocho segundos.
Esta configuración se realiza mediante la escritura de forma directa de los registros. Es recomendable tener
cuidado de no cambiar de forma accidental el estado del resto de bits pertenecientes al registro que deseamos
modificar. Para ello se utilizará los operando “AND” para poner a cero un bit de un registro concreto, y “OR”
para ponerlo a uno.
Lo primero que hay que hacer es dar la orden al microcontrolador de que al saltar la interrupción generada por
48 Desarrollo del Firmware

el wacthdog no se reinicie, sino que se llame a la función ISR (función por defecto de interrupciones). Para
ello es necesario modificar el registro MCUSR.

Figura 4-2 – Registro de estado del microcontrolador Atmel ATmega328p

En la figura 4-2 se puede ver como está formado el registro MCUSR, sin embargo, el único bit de este registro
que interesa para el proyecto es el bit 3, WatchDog system Reset Flag (WDRF). Si este bit está en nivel alto, al
ocurrir una interrupción provocada por el watchdog se reiniciará el microcontrolador, sin embargo, si este bit
se encontrase en nivel bajo, se llamaría a la función ISR. Por lo tanto se tendrá que poner este bit a cero
mediante la siguiente instrucción.

MCUSR = MCUSR & B11110111;

En cuanto a la configuración del watchdog hay que recurrir al registro WDTCSR que se muestra en la figura
4-3. En este caso, si es necesario explicar la función de todos los bits.

Figura 4-3 – Registro de control del temporizador watchdog del microcontrolador Atmel ATmega328p

Bit 7 – WDIF: Indica que se produce una interrupción del watchdog. Esta generalmente se actualiza
directamente cuando desborda el timer del watchdog, no obstante, si se requiere se puede poner este bit a uno
obteniendo el mismo efecto. Durante la ejecución de la configuración inicial no será necesario su modifiación,
pero al llamar a la rutina de interrupción es necesario cambiar este bit a nivel bajo.
Bit 6 - WDIE: Este bit activa el watchdog a nivel alto y lo desativa a nivel bajo. Para evitar problemas durante
la configuración del registro es necesario ponerlo a cero antes de empezarla mediante el siguiente comando:

WDTCSR = WDTCSR & B10111111;

Bits 5, 2, 1 y 0 – WDP3, 2 1, 0: Preescalador del timer, estos bits permiten aumentar el tiempo que tarda el
timer en desbordar. En la figura 4-3 se muestra una tabla con las diferentes posibilidades. Como se puede
apreciar tan solo se dispone de un tiempo máximo de ocho segundos. Aunque utilizando una variable a modo
de contador se controla si se quiere volver a colocar el dispositivo en modo hibernación, o bien se quiere que el
dispositivo ejecute una lectura y envío de datos.
Red de sensores para monitorización inteligente de vivienda 49

Figura 4-4 – Tiempo de preescalado del watchdog del microcontrolador Atmel ATmega328p

Bit 4 – WDCE: Este bit es necesario para realizar los cambios tanto en el WDE como en el preescalador del
registro. Es importante ponerlo en nivel alto para realizar los cambios. Una vez actualizado el preescalador este
bit será reiniciado tras cuatro ciclos de reloj.
Bit 3 - WDE: Este bit tiene la misma función que el bit WDRF del registro MCUSR. Por lo que si se pone a
uno el bit WDRF automáticamente se registrará a uno el bit WDE. Y si se desea cambiar el bit WDE a cero, es
necesario poner a cero el bit MCUSR previamente. Si este bit se encuentra en nivel alto la placa se reiniciará
cuando desborde el watchdog.
A continuación, se muestra el código para la configuración del registro WDRF:

WDTCSR = WDTCSR & B10111111; //Evita interrupciones indeseadas.


WDTCSR = WDTCSR | B00010000; //Permite configurar WDE y WDP.
WDTCSR = WDTCSR & B01110001; //Se establecen los bits a nivel bajo.
WDTCSR = WDTCSR | B00010000; //Permite terminar de configurar WDP.
WDTCSR = WDTCSR | B00100001; //Permite configurar WDE y WDP.
WDTCSR = WDTCSR | B01000000; //Permite interrupciones por watchdog.

4.1.3.3 Rutina de Interrupción ISR.

Una vez producida la interrupción del watchdog se despertará el microcontrolador, esto no tiene porque ser la
función deseada, ya que se requiere que el dispositivo esté en estado de hibernación todo el tiempo que no este
realizando una lectura o emitiendo. Es por ello que se establece una variable a modo de contador que permite
comprobar cuanto tiempo lleva el dispositivo en hibernación. Una vez despertado el dispositivo, este hibernará
en la siguiente ejecución de la rutina principal.
Ya que es necesario tener un control para saber si se detecta alguien en casa cuando la alarma está activa, se
realizará una lectura del sensor de presencia durante la ejecución de esta rutina. Teniendo en cuenta el último
valor leído, se interrumpirá el estado de hibernación o continuará con normalidad.
Esta comprobación basada en la última lectura es debida a que no se puede saber si está armada o desarmada
la alarma, ya que la comunicación está solo disponible desde el nodo periférico al nodo central.
50 Desarrollo del Firmware

4.2 Nodo Central


Este nodo asume toda la responsabilidad del sistema, ya que es el encargado de recibir todas las tramas que
generan los nodos periféricos y transladarlas al bróker MQTT. Debe por lo tanto leer las tramas xBee y tener
conexión a internet. También es el responsable de permitir el acceso de personas al hogar y de la gestión de la
alarma, además de la lectura de los sensores de temperatura, humedad, luminosidad y presencia, al igual que
los nodos periféricos. Por lo que debe de contar además de con los sensores, de un lector RFID y de un relé
para activar la alarma.
En cuanto a la gestión energética, este nodo no puede hibernar en ningún momento ya que podría perder las
tramas de las lecturas de los nodos periféricos y el aviso de activación de la alarma. Su programación será
diferente a la del nodo periférico.

4.2.1 Sensores
El nodo central generará una lectura de temperatura, humedad, luminosidad y presencia igual a la generada en
el nodo periférico, por lo que se acudirá al apartado 4.1.1 para conocer su programación.

4.2.1.1 RFID

Se dispone de un lector de tarjetas RFID RC522 que se conecta mediante I2C al arduino UNO. Para
simplificar su programación se recurre a una librería. En este proyecto solo será necesaria la parte en la que se
detecta una nueva tarjeta Mifare y en la que se lee su identificador.
En primer lugar hay que instanciar o crear el objeto de clase MFRC522 en el cual hay que especificar los pines
SS y RST.

MFRC522 mfrc522(SS_PIN, RST_PIN);

Para conocer si hay una nueva tarjeta RFID se llama al metodo PICC_IsNewCardPresent(). Este devuelve
true cuando se detecta una nueva tarjeta. Sin embargo, no es capaz de diferenciar si esta tarjeta ha sido leída
antes, por lo que es propenso a dar muchos errores por el efecto rebote. Por ello se debe conpaginar con una
variable booleana que haga las veces de bandera. De tal forma que si esta bandera está a false significa que no
hay ninguna tarjeta y true que ya ha sido leída.

if ( mfrc522.PICC_IsNewCardPresent() && !Tpresente) {

·
·
·

Mientras la tarjeta está estabilizada el método devolverá false por como está construido. Por ello la bandera
Tpresente permanecerá activa mientras ocurrá esto. Falta detectar cuando se retira la tarjeta. Esta librería no
recoje ningún método para esta función, no obstante, al retirar la tarjeta se produce el efecto rebote por lo que
en este proceso el método emite true. Por lo que colocando el siguiente if se detecta cuando deja de estar
presente la tarjeta.
Red de sensores para monitorización inteligente de vivienda 51

if (!mfrc522.PICC_IsNewCardPresent() && Tpresente) {


return;
} else {
Tpresente = false;
}

Una vez se ha detectado la tarjeta hay que leer su identificador, que será utilizado para comprobar en el
servidor si está registrado y en tal caso si entra o sale de casa el individuo.
El método PICC_ReadCardSerial() permite hacer una lectura estructurada de la tarjeta RFID, almacenando el
dato de interés para este proyecto en una variable publica uid como un array de tipo byte.
Para evitar cualquier error en la transformación de tipo a uint8_t en el envío por MQTT, se realiza una copia
de estos datos convertidos a char en un nuevo array y posteriormente se manda la trama MQTT.

if ( mfrc522.PICC_ReadCardSerial()) {
for (byte i = 0; i < mfrc522.uid.size; i++) {
RFID_ID[i] =(char) mfrc522.uid.uidByte[i];
}
clientmqtt.publish("pfc/rfid", (uint8_t*)RFID_ID, strlen(RFID_ID),
true);
Tpresente = true;
}

De esta forma se recupera la información que se necesita de la tarjeta RFID, siendo necesario esperar a que se
retire para bajar la bandera Tpresente.

4.2.2 Módulos de comunicaciones.


A diferencia del módulo periférico, el nodo central tiene dos módulos de comunicaciones, el módulo xBee y el
módulo WiFi. Para la programación de ambos se utilizan librerías. Para el xBee se utilizará la misma librería
que en el nodo periférico, aunque en este caso, al estar orientado para realizar lecturas, se utilizarán otras clases
y métodos de la misma que se verán a continuación.
En cuanto al módulo WiFi, al utilizar la shield oficial de arduino, se dispone de una librería interna. Por
supuesto al tratarse de una librería tan extensa es necesario centrarse únicamente en las clases y métodos
utilizados en este proyecto.

4.2.2.1 Módulo xBee

En este caso será necesario el uso de dos clases, cuyas instancias o creaciones de objetos se reflejan en el
código como:

XBee xbee = XBee();


ZBRxResponse rx = ZBRxResponse();

La clase xBee es la clase principal, que va permitir el uso de los métodos begin() para inicializar el objeto con
el puerto serie deseado.

Serial.begin(115200);
xbee.begin(Serial);
52 Desarrollo del Firmware

Y el método readPacket() para obtener el paquete almacenado en el buffer del módem, guardando el socket en
una subclase pública de tipo estructura entre los que se destaca un método para copiar la trama leída a un
objeto del tipo ZBRxResponse.

xbee.readPacket();

Para poder copiar los datos al objeto “rx” será necesario utilizar la subclase mencionada en el párrafo anterior.

if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
xbee.getResponse().getZBRxResponse(rx);

·
·
·

El método getApiId() de la subclase permite conocer cual es el tipo de socket leído, mientras el método
getZBRxResponse() permite copiar el socket al objeto “rx”. Una vez que el socket está dentro de este objeto se
puede obtener el tamaño del mismo mediante el método getDataLength().

tam=rx.getDataLength();

Obtener los datos almacenados en la variable pública getData[].

for(int aux=0;aux<55;aux++){
Trama[aux]=(char)rx.getData(aux);
}

Y obtener la dirección Mac del nodo periférico que emitió la trama para informar al servidor del lugar desde
procedía.

macLsb = rx.getRemoteAddress64().getLsb();

4.2.2.2 Módulo WiFi

Se utiliza una librería interna haciendo que su programación sea más intuitiva. No hace falta instanciar la clase
WiFiclass, sino que se llamarán a sus métodos utilizando el objeto WiFi. Este objeto es instanciado de forma
automática en el mismo momento en el que se utiliza la librería, generalmente al instanciar el cliente WiFi.

WiFiClient client;

Los métodos utilizados con el objeto WiFi son: Status(), permiten saber si está conectada o no la shield;
begin(ssid,pass) permite la conexión al punto de acceso wifi; LocalIP() devuelve la dirección IP que establece
mediante DHCP el punto de acceso para el módem; RSSI() devuelve la calidad de la conexión o cobertura en
dBm.
Red de sensores para monitorización inteligente de vivienda 53

En cuanto al cliente, no se usa directamente ningún método, sino que es la librería pubSubClient.h la que
utiliza este cliente de forma interna.
El objeto WiFiClient hereda la clase Client. Esta define los métodos necesarios para la conexión y envío de
sockets mediante WiFi, por lo que utilizando la librería pubSubClient se consigue un alto nivel de abstracción
ya que no es necesario en ningún momento llamar a los métodos del cliente WiFi.

4.2.2.3 Conexión con el bróker MQTT

Se utiliza el protocolo MQTT para crear un sistema de publicación y subscripición. De tal forma que un
dispositivo que emita un socket en un determinado topic hará que cualquier otro dispositivo subscrito a este
pueda recibir la trama.
La librería pubsubclien.h se usa para la conexión, subscripción y publicación con el bróker MQTT. Está
compuesta por una única clase con sus respectivos métodos.
Hay que instanciar la clase PubSubClient, para ello el constructor requiere un objeto del tipo client, un array de
char para almacenar la dirección del servidor donde se aloja el bróker, un int con el puerto del mismo y la
dirección de una función que se ejecutará cuando se publique en un topic al que se está subscrito.

#define MQTT_SVR_IP "192.168.0.102"


#define MQTT_SVR_PORT 1883
·
·
·
void callback(char* topic, byte* payload, unsigned int length);
·
·
·
WiFiClient client;

PubSubClient clientmqtt(MQTT_SVR_IP,MQTT_SVR_PORT,callback,client);

Mediante el método connect se realiza la conexión al bróker MQTT. Este método va a necesitar un
identificador único, el usuario y la contraseña para registrarse en el bróker, un topic para enviar una trama que
ayude a mantener la conexión y el mensaje que se desea enviar y si se desea que se retenga esta información
en el bróker.
Debido a que no se puede repetir el ID del dispositivo, se genera un ID de forma aleatoria mediante la función
random generando una semilla randomSeed aleatoria leyendo un dato de algún pin analógico no usado.
Para comprobar si se ha desconectado del bróker en cada interación se revisa si se mantiene conectado
mediante el método conected().

if (!clientmqtt.connected()) {
char clientID_buffer[22];
for (int i = 0; i < 22; i++){
clientID_buffer[i] = random('a', 'z');
}
if (clientmqtt.connect(clientID_buffer, MQTT_USER, MQTT_PASS,
"pfc/estado", 0, 1, "0")) {
·
·
·
}
}
54 Desarrollo del Firmware

Y al final de cada bucle se manda una trama de control al bróker, esta es necesaria ya que renueva la conexión
con el bróker. Este envío está recogido en el método loop del objeto.

clientmqtt.loop();

Cada vez que se conecta, al tener un nuevo ID, es necesario volver a subscribirse a los topics donde estaba
subscrito. Para realizarla se utiliza el método subscribe().

clientmqtt.subscribe("pfc/alarma");

Cuando algún dispositivo mande una trama con este topic se llamará a la función callback, como si de una
rutina de interrupcción se tratase. Esta comprobación es posible por el método loop(), que adicionalmente a la
comunicación de mantenimiento de la conexión comprueba si se han enviado datos a los topics en los que está
subscrito el dispositivo.

4.2.2.4 Creación de trama y publicación MQTT

El nodo central tiene la necesidad de crear dos tramas, la primera de ellas es la vista en el apartado 4.2.1.1
donde se manda un socket MQTT con el topic pfc/rfid y el contenido del mensaje es el ID de la tarjeta RDIF
presentada.
Por otro lado, está la trama de los sensores. Debido a que debe seguir el mismo formato que la trama enviada
por los nodos periféricos estará compuesta por pares “tipo=valor” separados con el carácter „&‟. Sin embargo,
a diferencia de lo que ocurre con los nodos periféricos será necesario especificar la MAC, ya que es el nodo
central es el encargado de escribirla en los periféricos. La MAC del propio nodo no es posible de hallar, ya que
se utiliza el propio socket xBee para leerla. Por esta razón es necesario especificar manualmente la MAC del
nodo central.
Para simplificar la creación de la trama y poder reutilizar el código escrito en el nodo periférico la MAC se
suministra como una pareja “tipo=valor” seguido del separador „&‟, tal que lo siguiente sea introducir los
datos leídos por los sensores.
char mac[]="MAC=1085975315&";

Una vez escrita la MAC, reutilizando el mismo código que en el nodo periférico pero sin iniciar la variable que
sirve de índice, se genera la trama que quedaría:

MAC=1085975315&TEM=35&HUM=51&LUZ=561&PIR=0

Una vez generada, el mensaje se envía al socket MQTT con el topic pfc/lectura

clientmqtt.publish("pfc/lectura",(uint8_t*)texto,strlen(texto),true);

Siendo el array de char texto el que almacena la trama que se desea enviar.
Red de sensores para monitorización inteligente de vivienda 55

4.2.2.5 Recepción de tramas xBee y publicacion de MQTT

Para recibir la trama xBee es necesario ejecutar el código utilizando las clases y los métodos explicados en el
apartado 4.2.2.1. Una vez leída la trama es necesario leer la MAC del socket y montar una trama que debe
quedar exactamente igual que el del apartado anterior. La función monta trama simplemente crea una trama
con el siguiente formato:

MAC=”MAC del nodo emisor de la trama recibida”&”Trama recibida”

Que siguiendo el ejemplo de trama del nodo periférico debe quedar:

MAC=1085975325&TEM=25&HUM=41&LUZ=386&PIR=1

Una vez montada la trama el proceso de envío del socket por MQTT es exactamente igual al que se realiza en
el apartado anterior.

4.2.2.6 Recepción de trama por Subscripcion MQTT

Este nodo debe subscribirse a un topic que le avise si debe activar o desactivar la alarma. En el caso de que se
tuviera más de un topic, por la variable topic de la función callback se puede conocer cual es el origen del
mismo.
A partir del mensaje recibido se puede saber si la alarma está desactivada, armada o sonando. Para conocer el
estado de la alarma, se comprobará el mensaje y se actuará conforme al resultado del mensaje.

if (strstr(topic, "alarma") != NULL) {


if (strstr(recibido, "OFF") != NULL) {
Alarma = 0;
} else if (strstr(recibido, "Armar") != NULL) {
Alarma = 1;
} else if (strstr(recibido, "ON") != NULL) {
Alarma = 2;
}
}

En el caso de que el resultado de alarma sea dos se activará el relé para que la alarma empiece a sonar.
56 Desarrollo Software

5 DESARROLLO SOFTWARE

La compresión mutua sería enormemente facilitada por


el uso de una lengua universal
- Nikola Tesla-

entro del diseño software se diferencian varios elementos, la programación de los servicios, la lectura

D de datos desde la base de datos y todo aquello que se ejecuta desde el lado del servidor (backend); el
bróker MQTT para comunicar el hardware con el servidor (middleware) y por último el diseño de una
interfaz web, donde el usuario final pueda tener acceso a estos datos y gestionarlos abstrayéndose de la forma
en que los datos son mostrados en pantalla (frontend).

5.1 Descripción de necesidades software


Para cumplir las necesidades del Sistema hay que dividir por un lado el servicio web y por otro lado la interfaz
web. El servicio debe recoger toda la información entrante por parte del nodo central y gestionarla, si se trata
de una lectura, debe introducir los datos en la base de datos y comprobar si existe presencia, en el caso de que
exista debe comprobar si debe o no encender la alarma. Para realizar este cometido se utilizará NodeJS debido
a las posibilidades que ofrece este lenguaje. El protocolo de intercambio de datos con el nodo central es
MQTT ya que se trata de un protocolo de publicación y subscripción y facilita el envío de datos al nodo
central. Para almacenar los datos se utilizará una base de datos mySQL debido a que será más fácil de obtener
los datos utilizando PHP en la web.
En la página web existen dos tipos de acceso. Para el acceso de usuario, al no necesitar introducir usuario y
contraseña, se realizará una página web básica y mediante una llamada AJAX de JavaScript se mostrarán los
datos de todos los sensores. Para obtener más detalles, con otra llamada AJAX se obtendrán los datos de un
único sensor, y se tratarán los datos para ser mostrados en forma de gráfica.
Para el acceso de administración se realizará una web en PHP para poder interactuar de la forma más eficiente
a la base de datos mySQL, mostrando una interfaz basada en HTML y CSS.

5.2 Backend
5.2.1 Base de datos en mySQL
La programación del backend da soporte a la interfaz de usuario. Por ello es necesario el uso de un servidor
web con base de datos en mySQL. Para entender el uso de los diferentes servicios y recogida de datos es
importante conocer la organización de las tablas del servidor. En este proyecto serán necesarias cinco tablas:
una para almacenar los datos de los sensores, que recibe el nombre de “Sensores”, una segunda tabla orientada
Red de sensores para monitorización inteligente de vivienda 57

a los sensores, pero que establece parejas de nodo con el nombre asignado con el nombre “Registro”; otra para
gestionar el control de acceso, que recibe el nombre de “rfid”; otra pseudo asociada a la anterior para conocer
el estado de la alarma, si está o no armada, que tiene el nombre de “Alarma”; y por último una tabla que
almacena pares de usuarios/contraseña con acceso al panel de administración.

5.2.1.1 Tabla Sensores

En cada fila de esta tabla se almacena el tipo de sensor y su valor. Realizar una tabla para cada nodo sin poder
estimar el número que hay es tedioso e ineficiente. Si se le agregase un valor que indique la mac del nodo de
donde procede la lectura sería necesaria solo una tabla. Como se van a almacenar varios datos
correspondientes a la misma lectura se debe saber la fecha en la que fue escrita y por último obtener un
identificador único de la lectura.
Por lo tanto la estructura en código mySQL será la siguiente:

Sensores` (
`id` int(32) NOT NULL,
`mac` int(32) NOT NULL,
`sensor` varchar(3) COLLATE utf8_spanish_ci NOT NULL,
`valor` float DEFAULT NULL,
`fecha` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
COLLATE=utf8_spanish_ci;

5.2.1.2 Tabla Registro

Se almacenan las direcciones MACs activas con sus respetivas etiquetas. El daemon es el servicio que recoge
las tramas MQTT emitidas por el nodo central. Cuando este detecta una nueva trama, realiza un registro en
esta tabla con la etiqueta “SinAsignar”. De esta forma se mantienen por separados las lecturas de los nodos
disponibles. Una vez eliminado un nodo de esta base de datos, no se mostrará por la interfaz pero si se
mantendrán almacenados los valores leídos. Por ello, si se elimina un nodo por error, será fácil volver a
recuperar todos los datos.
La estructura en código mySQL será la siguiente:

`Registro` (
`mac` int(32) NOT NULL,
`room` varchar(32) COLLATE utf8mb4_spanish_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;

5.2.1.3 Tabla rfid

Está basada en la tabla anterior, por un lado tiene el identificador de la tarjeta RFID y por otro el nombre
asignado por el usuario. No tiene un histórico de cuanto tiempo pasa alguien en casa porque no es necesario
para esta aplicación, ya que solo se requiere conocer si queda alguna persona con permiso en la vivienda, y en
función de esto armar o desarmar la alarma. En este caso, cuando el daemon detecta una nueva ID la registra
con el nombre “SinRegistrar”.
Finalmente la estructura en código mySQL será la siguiente:

`rfid` (
`id` int(11) DEFAULT NULL,
`usuario` varchar(12) DEFAULT NULL,
58 Desarrollo Software

`encasa` int(1) NOT NULL


) ENGINE=MyISAM DEFAULT CHARSET=latin1;

5.2.1.4 Tabla Alarma

En esta tabla solo será necesario utilizar una única fila. Esta servirá para conocer desde el servidor el estado de
la alarma. Como solo se quiere utilizar una fila se pondrá una columna “Alarma", cuyo contenido no puede ser
repetido. Es decir si la fila en esta columna recibe el nombre también de “Alarma”, y la base de datos recibe
una orden de almacenar unos datos cuyo valor en “Alarma” es “Alarma” los datos recibidos sustituirán a los
que ya existen y no se añadirá un nuevo elemento llamado “Alarma". Lo que sería muy confuso.

La estructura en código mySQL será la siguiente:

`Alarma` (
`Alarma` varchar(6) NOT NULL,
`Armado` tinyint(1) NOT NULL,
`Sonando` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

5.2.1.5 Tabla users

Esta tabla almacena parejas de usuario y contraseñas con acceso a la base de datos, de tal forma que cada
usuario está registrado a un ID para aplicaciones futuras propuestas en el capítulo 7. Cuando se realiza la
comprobación de esta tabla, si ambos elementos no coinciden no se permitirá el acceso al panel de
administración como se verá más adelante.
La estructura en código mySQL será la siguiente:

`users` (
`id` int(11) NOT NULL,
`usuario` varchar(11) NOT NULL,
`contrasena` varchar(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

5.2.2 Servicios web


El acceso directo a la base de datos resulta peligroso e inseguro, por ello se establece una serie de servicios
web que accederán a la base de datos y devolverán los datos solicitados. Estos servicios están programados en
PHP. Al no existir la escritura de datos mediante este sistema no supone ningún problema de seguridad grave.

5.2.2.1 get_sensor.php

Sirve para identificar cada MAC física con su etiqueta asociada, haciendo una consulta a la tabla de registro
para conocer todos los datos de la tabla cuya etiqueta es diferente a “SinAsignar”. Para ello se establece una
conexión a la base de datos y se genera una consulta del tipo

$sql = "SELECT * FROM `Registro` WHERE room<>'SinAsignar'";


$consulta = mysqli_query($conexion,$sql);
Red de sensores para monitorización inteligente de vivienda 59

Posteriormente se monta un JSON, que es un formato para pasar una serie de datos legibles por JavaScript.
Para formar el JSON se crea un array de datos formado por ““mac”=“MAC del nodo”, “room”=“Nombre del
nodo””.

$array= array();
while ($fila = mysqli_fetch_array($consulta)){
$dato = array(
"mac"=>$fila['mac'],
"room"=>$fila['room']
);
array_push($array, $dato);
}

Mediante la función json_encode() se pasa la trama al formato JSON, un ejemplo de este formato es:

[{"mac":"1085975339","room":"SALON"},{"mac":"1085975325","room":"COCI
NA"},{"mac":"1235496865","room":"CONTADORES"},{"mac":"2147483647","roo
m":"DORMITORIO"}]

5.2.2.2 get_data.php

Es un archivo que devuelve todos los datos de un único tipo leído por un nodo en concreto en un rango de
fechas dado. El servicio necesita cuatro parámetros para saber que parámetros debe devolver: la mac del nodo,
el tipo de sensor que se desea leer, la fecha mínima y la fecha máxima.
Al igual que se ocurre con get_sensor.php, se almacenan la información en un array de datos para
posteriormente montar un JSON que será devuelto. Un ejemplo de salida de datos de este servicio es:

[["2015-08-14 00:25:54",31],["2015-08-14 00:58:10",31],["2015-08-14


01:30:23",31],["2015-08-14 02:02:38",30],["2015-08-14
02:34:51",30],["2015-08-14 07:42:25",28],["2015-08-14
08:14:35",28],["2015-08-14 08:46:48",28],["2015-08-14
09:18:59",28],["2015-08-14 09:51:12",28],["2015-08-14
10:23:22",28],["2015-08-14 10:55:36",28],["2015-08-14 11:27:47",28]]

Como se puede comprobar en este ejemplo, esta información corresponde a datos leídos entre el día
14/09/2015 a las 00:00 y el día el 14/09/2015 a las 12:00. Aunque el uso que se le dará a este archivo está
orientado a leer por días, se pueden especificar las horas, minutos y segundos en los límites máxímos y
mínimos.

5.2.2.3 SuperConsulta.php

Este servicio devuelve una lista de las últimas lecturas de los sensores de todos los nodos, además genera un
enlace para poder visualizar las gráficas los nodos. No necesita ningún parámetro y su devolución incluye el
código HTML con el formato especificado en la sección de frontend. Se trata de la consulta que se puede
visualizar en la página principal del proyecto final de carrera.
La principal ventaja de este servicio es que con una única conexión a la base de datos se puede acceder a todo
el contenido, aunque se realicen varias consultas. Genera un enlace para poder visualizar el histórico de los
sensores en gráficas.
Adicionalmente devolverá la información de quienes están en la vivienda y si se detecta algún nodo o tarjeta
sin etiqueta generará un enlace al panel de administración.
60 Desarrollo Software

Ejemplo de lista generada:

SALON
PIR : 1 en 2016-02-21 16:52:31
LUZ : 631 en 2016-02-21 16:52:31
HUM : 37 en 2016-02-21 16:52:31
TEM : 20 en 2016-02-21 16:52:31

COCINA
PIR : 1 en 2015-08-13 22:07:03
LUZ : 303 en 2015-08-13 22:07:03
HUM : 29 en 2015-08-13 22:07:03
TEM : 31 en 2015-08-13 22:07:03

CONTADORES
TEM : 100 en 2015-09-15 09:26:34
PIR : 1 en 2015-09-10 10:59:59
LUZ : 253 en 2015-09-10 10:59:59
HUM : 12 en 2015-09-10 10:59:59

DORMITORIO
PIR : 1 en 2015-09-23 09:52:07
LUZ : 350 en 2015-09-23 09:52:07
HUM : 15 en 2015-09-23 09:52:07
TEM : 35 en 2015-09-23 09:52:07

Javier está registrado en casa.


Ver gráficas

5.2.3 Panel de administración


Es una interfaz de usuario que está desarrollada integramente en PHP. Todo código PHP pertenece al backend
de cualquier proyecto independientemente si se trata de servicios webs o de una web completa en PHP.
Debido a su simplicidad de programación, genera de forma automática todo el código HTML necesario para
visualizar la base de datos a excepción del CSS, el cual si será explicado en la sección frontend.

Figura 5-1 – Panel de login de la interfaz de administración.


Red de sensores para monitorización inteligente de vivienda 61

5.2.3.1 Setup.html

Se trata de un formulario para introducir Usuario y Contraseña, así se podrá comprobar de forma segura que el
acceso al panel de administración esté protegido. Estos datos se enviarán al servicio admin.php mediante
HTTP POST para proteger lo datos enviados. Pese a que esta parte pertenecería al frontend se ha decidido
colocar aquí para simplificar su documentación admin.php
Tras recibir los datos de usuario y contraseña se identificará si son válidos. En el caso de que no lo sean se
devolverá el mensaje “Usuario o Contraseña erróneo” junto con la posibilidad de volver a introducir usuario y
contraseña.
En caso contrario generará una lista con todos los datos de la tabla Registro, los usuarios de la tabla rfid, y el
estado de la alarma. Se pueden asignar etiquetas a nuevos nodos o personas con acceso a la vivienda. Y
también corregir de forma remota un descuido al no pasar la tarjeta RFID por el lector y no armar o desarmar
la alarma.

Figura 5-3 – Panel de login con usuario o contraseña erróneo

Figura 5-2 – Panel de administración


62 Desarrollo Software

5.2.3.2 mRegistro.php

Se trata de un archivo similar al anterior, difiere en que los parámetros de entrada son Actualizar o Eliminar en
el registro, de tal forma que se puede efectuar una acción en la base de datos. Para ello es necesario la
dirección MAC del sensor o la ID de la tarjeta RFID y la nueva etiqueta para efectuar los cambios.
Tanto en el archivo admin.php como en el archivo mRegistro.php, los cambios se hacen uno a uno y cada
botón de actualizar funciona como actualizador o eliminador de valores que están asociados a él.

Ejemplo 1 de actualización:

En la figura 5-3 se puede observar como queda el archivo admin.php correctamente logeado.
Se cambian dos elementos simultáneamente en la figura 5-4 y pulsamos actualizar sobre el primero de los
elementos cambiados.

Figura 5-5 – Cambio de dos elementos simultáneos en la interfaz de administración

Tras pulsar el botón actualizar, se puede observar en la figura 5-5 tan solo se actualizó el elemento donde se
pulsa dicho botón.

Figura 5-4 – Solo se actualiza un elemento


Red de sensores para monitorización inteligente de vivienda 63

Ejemplo 2 de actualización:

En la figura 5-3 se puede observar como queda el archivo admin.php correctamente logeado.
Se cambian dos elementos simultáneamente en la figura 5-4 y pulsamos actualizar sobre cualquier elemento
no cambiado.

Figura 5-6 – No se actualiza ningún campo

Tras pulsar el botón actualizar en la tercera opción, se puede observar en la figura 5-6, se pierden ambas
actualizaciones.

Si se refresca el archivo mRegistro.php en el navegador o se intenta acceder directamente mostrará un mensaje


de sesión caducada con la posibilidad de volver a logearse.

Figura 5-7 – Panel de login tras caducar la sesión


64 Desarrollo Software

5.3 Middleware
5.3.1 Servicio NodeJS
Sirve para atender a los datos que se envían desde la placa de arduino desde el lado del servidor. Para ello es
necesario que exista un servicio subscrito a los datos que envía el nodo central. Cuando llega una trama al
servicio, se parsea y se almacenan los datos en la base de datos.
Se necesita un servicio que tenga la capacidad de soportar subscripciones MQTT, que pueda almacenarlas en
una base de datos mySQL y que este corriendo constantemente. Por lo que se tendrá que recurrir a un potente
lenguaje. En este proyecto se ha seleccionado nodeJS por las posibilidades que ofrece.
Su función es almacenar la información recogida en la base de datos y comprobar si la alarma está armada en
caso de que la trama indicase que hay una presencia. Si esto ocurriese se mandaría una trama MQTT avisando
de que la alarma debe ser encendida. Si tras esto se detectase que la alarma es desarmada o cancelada, se
enviaría una nueva trama MQTT para cancelar el proceso de encendido de la sirena
Recibe los datos de los sensores y los de los registros realizados con la tarjeta RFID, comprobando si esa
persona entra, sale o no está registrada.
Se ha incluido un sistema de envío de e-mails para informar cuando se inscribe un nuevo nodo o se registre
una tarjeta, ya sea porque una persona salga o entre de casa o sea una persona sin acceso.
También avisará cuando se arme la alarma y cuando empiece a sonar.

5.3.1.1 MQTT

Es imprescindible para el Proyecto que MQTT este disponible en el servicio, para ello se agrega la librería que
debe estar previamente instalada por npm.

var mqtt = require('mqtt');

Para realizar la conexión es necesario que sea un ID nuevo y por ello se utiliza una función para generar datos
aleatorios para generar un ID aleatorio.

var rand = function(){


return Math.random().toString(36).substr(2);
}
var token = function() {
return rand() + rand();
};
var client_ID = token().toString();

Se genera la conexión mediante el método connect.

client = mqtt.connect("mqtt://127.0.0.1:1883", {username: "admin",


password: "password", clientId: client_ID, keepalive: 5});

Se establece un keepalive de cinco segundos, si durante este tiempo no se envia una señal de ping, se
desconectará del bróker. Una vez conectado se subscribirá a los topics donde publica el nodo central. Y a otros
topics que se usará para generar una espera.
En JavaScript, la ejecución no es totalmente secuencial, por tanto si puede realizar una tarea mientras espera
una respuesta la realiza. Esto conlleva a que mientras esta leiendo de la base de datos, ejecuta el resto del
Red de sensores para monitorización inteligente de vivienda 65

código, aunque se necesiten los datos obtenidos por la base de datos.


Esto en principio no supone un problema si pudieran anidarse una escritura dentro de una lectura, no obstante,
ni es posible en JavaScript ni es recomendado de realizar en otros lenguajes. Por ello se decide enviar los datos
necesarios a la escritura por MQTT.

5.3.1.2 E-Mail

Para enviar e-mails se utiliza la librería nodeMailer

var nodemailer = require('nodemailer');

Una vez configurada con una cuenta de Gmail, único requisito de esta librería, se pueden enviar e-mails de la
siguente forma.

var mailOptions = {from: '"Casa Domotica"


<j.arcenegui.pfc@gmail.com>', to: 'j.arcenegui@gmail.com', subject:
RFID_ID + ' ha intentado acceder a casa', text: RFID_ID + ' ha
intentado acceder a casa, sin embargo el usuario no está registrado en
la base de datos, en caso de que el usuario tenga permisos corríjalo
en el panel de administración', html: '<H3>' + RFID_ID + ' ha
intentado acceder a casa</H3> <p> Sin embargo el usuario no está
registrado en la base de datos, en caso de que el usuario tenga
permisos, por favor, corríjalo en el <a
href="www.ardugeek.es/pfc">panel de administración</a></p> '};

transporter.sendMail(mailOptions, function(error, info){


if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});

5.3.1.3 mySQL

Con esta librería se pueden realizar cualquier consulta en codigo mySQL, una vez realizada se ejecutará una
función definida por el programador.

5.4 Frontend
En esta sección se describen las diferentes interfaces con las se va a visualizar y gestionar los datos obtenidos
por los sensores. En la página web del proyecto hay tres secciones principales, un menú para acceder a las
secciones y un pie de página con el enlace a la web de la Escuela Técnica Superior de Ingenieros de la
Universidad de Sevilla. La primera sección muestra una pequeña introducción del proyecto, la segunda
muestra los datos de los sensores y la tercera información personal del autor del proyecto.
Para acceder a la información de la base de datos se usa la programación. Se utilizará un archivo escrito en
JavaScript con una llamada AJAX a los servicios PHP comentados en el apartado 5.1.2. Para realizar este tipo
de llamada es necesario el uso de jQuery, un framework de JavaScript que habilita la utilización de AJAX.
El uso de un framework CSS como boopstrap sirve para que la web se adapte a todo tipo de dispositivos. Este
ripo de páginas se denominan páginas web responsivas.
66 Desarrollo Software

5.4.1 HTML y CSS


El diseño de la web HTML está formado por tres cuerpos de página en una única página y un pie de página.
En el menú se podrá leer el título de las tres secciones: Introducción, Sensores y Acerca de.

5.4.1.1 Introducción

En ella se establecen tres textos, un breve resumen del proyecto, su funcionamiento y una descripción del
sistema de alarma, esta página es totalmente estática y no dispone de ningún enlace.

Figura 5-8 – Sección introducción de la interfaz de usuario

5.4.1.2 Sensores

En esta página se hará la llamada a SuperConsulta.php. Mostrará la información de los sensores de todos los

Figura 5-9 – Sección sensores de la interfaz de usuario


Red de sensores para monitorización inteligente de vivienda 67

nodos y mostrará un enlace del histórico de los sensores en forma de gráfica. De la misma forma informará de
que personas están en la vivienda y si existe algún nodo o tarjeta RFID sin identificar. En tal caso se mostrará
un enlace al panel de administración. Se mostrará por pantalla la salida del servicio superconsulta pero con el
formato que se puede apreciar en la siguiente figura.

5.4.1.3 Acerca de

Se mostrarán los datos del autor, así como los datos del proyecto final de carrera. Tras esta información se
muesta el logo de la Escuela Superior de Ingenieros de la Universidad de Sevilla y del departamento de
Ingeniería Electrónica. Al igual que la sección de introducción es totalmente estática, aunque los logos serán
enlaces a las webs oficiales del organismo que representan.

Figura 5-10- Popup con las gráficas de los nodos.

5.4.1.4 Pop-Up gráfica

Se trata de un DIV oculto en el que se mostrará la gráfica de histórico. Para acceder al contenido de este DIV
es necesario pulsar sobre el botón de Ver gráficas. Además de la gráfica, este DIV contiene un pequeño
formulario que permite ver los gráficos de los nodos de los sensores en la fecha que se desee.

5.4.1.5 CSS

CSS es un pseudo lenguaje para definir un diseño a una web ya maquetada. Las hojas de estilos CSS permiten
darle color y forma a los diferentes elementos que componen la pagina web. Para el desarrollo de la web se
optado por un color verde #4fab2f y negro.
La pagina web tiene un diseño basodo en tres cuerpos cada uno de ellos representa una sección diferente por lo
que tendrán un color de fondo propio cada una de estas secciones.
En cambio la web de administración, al estar formada por diversos div, se ha optado por hacer cuadrados con
esquinas redondeadas verdes sobre fondo negro.
68 Desarrollo Software

5.4.2 JavaScript

Figura 5-11 – Sección Acerca de de la interfaz de usuario

Existen dos códigos de javascript adicionales a los necesarios para poder trabajar con jQuery. Uno alojado en
un documento externo al index llamado javascript.js y otro llamado grafica.js.

5.4.2.1 javascript.js

Este código es el encargado de colocar dentro del div subdivdatos todo el contenido devuelto por el servicio
superConsulta.php. Se utilizará la función get() basada en AJAX para obtener estos datos. Para mostrarlo en el
div se utiliza la función getElementById(). Mientras se cargan los datos, se mostrará un mensaje que dice
"Cargando datos, por favor espere".

$.get("SuperConsulta.php",function(datos, status){
texto = datos;
document.getElementById("subdivdatos").innerHTML = texto;
});

Se llamará al servicio superConsulta.php cada diez segundos para mantener actualizados los datos alojados en
la base de datos y detectar los cambios de los mismos. Se utilizará la función SetInterval():

setInterval(function (){ · · · }, 10000);

5.4.2.2 JavaScript para la insercción de fechas

Es un pequeño código insertado en el propio index.html. Contiene la información para generar la gráfica del
histórico de los sensores seleccionando las fechas máximas y mínimas. Este formulario de selección está
incluido dentro del framework de jQuery User Interface (jQuery UI). Su función se puede ver en la figura 5-
12. En este archivo JS se puede iniciar la fecha actual con la clase date de JS. Con los métodos getDay(),
getMonth() y getFullYear(), se elige el día, el mes y el año en cuatro cifras respectivamente. Sin embargo con
Red de sensores para monitorización inteligente de vivienda 69

este método se obtiene únicamente la fecha actual, e interesa conseguir el día posterior. Por ello se utilizará
getDay()+1. De esta forma siempre se tendrá un día posterior, pese a que sea el 31 de Julio, la propia función
datepicker, al detectar 32 de Julio, actualizará la fecha a 1 de Agosto. De esta forma siempre se tendrá el día
posterior.
<script>
$(function() {
$( "#desde" ).datepicker();
$( "#hasta" ).datepicker();
$( "#desde" ).datepicker("option", "dateFormat", "yy-mm-dd");
$( "#hasta" ).datepicker("option", "dateFormat", "yy-mm-dd");
var f = new Date();
$('#desde').datepicker("setDate", new Date(f.getFullYear() ,
f.getMonth() , f.getDate()) );
$('#hasta').datepicker("setDate", new Date(f.getFullYear() ,
f.getMonth() , (f.getDate()+1)) );
});
</script>

El formato de la fecha es año, mes, día. La razón de esto es porque es la forma más cercana al TIMESTAMP,
donde se define una fecha de forma única como un entero, AAAAMMDDHHMMSS. AAAA es el año en
cuatro cifras, MM el mes en dos cifras, DD el dia, HH las horas, MM los minutos y SS los segundos. La
llamada se realizará con el año, mes y día elegidos seguidos de seis ceros para contar con todos los datos del
día elegido.

Desde: 20160624000000
Hasta: 20160624000000
Ofrecerá los datos desde el 24 de Junio de 2016 hasta 30 junio de 2016 a las 00:00:00 o lo que podría
traducirse como 29 de junio de 2016 en la práctica.

5.4.2.3 grafica.js

Este archivo contiene toda la programación necesaria para realizar las gráficas. Se utiliza un API de Google
para generar diferentes tipos de gráficas pasándole como parámetro un array en formato JSON. Tal como se
genera a la salida del servicio get_data.php, este se utilizará para obtener los datos que se desean mostrar en la
gráfica.
Antes de dibujar la gráfica será necesario especificar el sensor del nodo y el rango de fechas a mostrar. Para
seleccionarla se utiliza el script especificado en el apartado anterior. Aprovechando que todos los nodos tienen
los mismos sensores se pondrá un menú de selección desplegable con los sensores de temperatura, humedad,
luminosidad y presencia.
Como el número de sensores es variable, se requiere acceder a la base de datos para conocer que nodos están
disponibles con su correspondiente etiqueta. Esta información es generada por el servivio get_sensor.php.

var url_data = "get_sensor.php";


70 Desarrollo Software

La salida de este servicio es un JSON, por lo que hay que convertirlo en array y parsearlo para que desde el
menú desplegable se pueda seleccionar el nodo del sensor seleccionado.

Figura 5-12 – Formulario con los nodos y sensores disponibles

function cargaHabitaciones(){
var url_data = "get_sensor.php";

$.get(url_data, function( data ) {


var array = JSON.parse(data);
$.each(array, function (i, item) {
var o = new Option(item.room, item.mac);
$(o).html(item.room);
$('#habitacion').append(o);
});
});
}

Con toda esta información se tiene completado el formulario, se puede apreciar en la figura 5.12.
El botón cargar ejecuta los datos necesarios para generar la gráfica. En primer lugar llama al servicio
get_data.php para recibir los datos mostrados en la gráfica.

var d = $( "#desde" ).val();


d=d.replace(new RegExp("-", 'g'), '') + "000000";
var h = $( "#hasta" ).val();
h=h.replace(new RegExp("-", 'g'), '') + "000000";
Red de sensores para monitorización inteligente de vivienda 71

var url_data =
"get_data.php?MAC="+$("#habitacion").val()+"&SENSOR="+$("#sensor").val
()+"&FROM="+d+"&TO="+h;

Donde d y h son las conversiones de las fechas desde y hasta consecutivamente para que la entienda el
servicio php. Los datos recibidos hay que convertirlos en un array y pasárselo a la función dibujaGrafica()
como único parámetro.

Figura 5-13 – Calendario para seleccionar el rango de fechas a mostrar.

Esta función llamará al servicio de google chart y con los parámetros especificados generará una gráfica de
histórico con los datos requeridos.
Se accede al popup para mostrar una gráfica. Para que no quede vacío en la primera visita se genera una con el
primer sensor del primer nodo detectado. Esto se realiza con la función cargaPrimeraVez(), la cual es llamada
cuando se abre la página.
72 Pruebas y validación

6 PRUEBAS Y VALIDACIÓN

Si cuando hablas nadie se molesta, eso es que no has


dicho absolutamente nada.
- Risto Mejide-

na vez finalizado el desarrollo del sistema, este se somete a una serie de problemas que se llevan a

U cabo emulando todos los posibles casos de error. El objetivo es cuantificar la robustez del mismo y
demostrar que cumple los objetivos del proyecto, esperando que el sistema responda adecuadamente.

6.1 Pruebas de conexión


6.1.1 Conexión del nodo central con la red WiFi
Se comprueba que la placa se conecta de forma correcta utilizando el puerto serie de arduino. En el cual como
se puede observar en la figura 6-1 muestra por pantalla la IP asignada mediante el protocolo DHCP. Para
contrastar esta información se accede a la interfaz de administración del router utilizado, donde se puede
comprobar que la IP conrresponde con la dirección MAC de la shield WiFi. Otra forma de comprobarlo es
mediante el comando ping en la consola de comandos.

Figura 6-1 – Conexión a la red wifi y al bróker MQTT


Red de sensores para monitorización inteligente de vivienda 73

6.1.1.1 Reconexión a la red WiFi frente a caídas

Es importante que cuando exista un problema con el router y este se apague o deje de dar señal WiFi por un
periodo limitado de tiempo, el nodo central pueda volver a conectarse. Para realizar esta comprobación se
apaga el router esperando una reconexión.

Figura 6-2 – Reconexión del nodo central al modem wifi

Figura 6-3 – Reconexión del nodo central al bróker MQTT

6.1.2 Conexión de nodo central con el bróker MQTT


Para comprobar la conexión con el bróker MQTT se utiliza de nuevo el puerto serie ya que existe una función
que permite comprobar si está o no conectado al bróker. Mirando la figura 6-1 se puede apreciar dos líneas,
una de ellas que expresa “desconectado” indicando que el dispositivo no está conectado al bróker, y “Se ha
conectado al bróker” indicando que se acaba de conectar al bróker.
74 Pruebas y validación

6.1.2.1 Reconexión al bróker frente a caídas

El bróker MQTT se sirve de conexiones ininterrumpidas, por lo tanto es necesario que exista una
comunicación de comprobación de conexión. Esta comprobación recibe el nombre “ping”, y tiene la misma
función que un ping de ethernet. Si durante un tiempo acordado entre el cliente y bróker no se recibe ninguna
trama de ping se corta la conexión. En ciertas ocaciones las tareas ejecutadas por arduino llevan un tiempo
superior al tiempo de desconexión o keep alive. Es por esta razón que es importante que exista una reconexión
al bróker antes de mandar cualquier trama. Esta se sirve de una comprobación del estado de la conexión y en el
caso que no esté conectado, realizará una conexión MQTT. Si esta conexión no es posible se comprobará que
existe conexión con el router. En el caso de que no exista no volverá a intentar una conexión al bróker hasta no
encontrar una conexión con el router. Para simular la pérdida de conexión con el bróker se desconecta la
raspberry de la red. Produciendo una caída del bróker.

6.1.3 Conexión de los nodos periféricos con el nodo central


Para que el sistema funcione correctamente es fundamental que los nodos periféricos estén conectados al nodo
central. Al contrario de lo que ocurre con las conexiones de los puntos anteriores, no existe una conexión
ininterrumpida debido a que los nodos periféricos entran en modo ahorro. Por lo tanto, la única forma de
comprobarla es comparar la trama que sale del nodo periférico con la que entra al nodo central. Para averiguar
la trama enviada y la recibida se utiliza el puerto serie de ambas placas y se comprueban.

Figura 6-4 – (A) Recepción de datos en el nodo central, (B) Envío de datos desde el nodo periférico

6.1.4 Conexión del servicio con la base de datos


Como ocurre en el apartado anterior, el servicio no está constantemente conectado a la base de datos, sino que
realiza una conexión con la misma cada vez que recibe una trama MQTT. Está programado para escribir por
pantalla la existencia de algún error, por lo tanto, si en la consola de comando no se muestra ningún error y
realiza los cambios oportunos en la base de datos se da por sentado que el servicio se conecta correctamente.
Como se conecta cada vez que llega una trama MQTT no se realizan pruebas para comprobar las
reconexiones, ya que las mismas realizadas para la conexión indican que se reconecta adecuadamente.

6.1.5 Conexión del servicio con el bróker MQTT


El servicio debe estar constantemente conectado al bróker MQTT, por ello es necesario comprobar que esta
conexión se lleva a cabo. Para comprobarlo se dispone de un mensaje en la consola de comando que indica
que se ha conectado al bróker. Esta librería permite que el servicio se reconecte automáticamente ante
Red de sensores para monitorización inteligente de vivienda 75

cualquier caída, por lo que no es necesario realizar pruebas de reconexión.


Otra forma de comprobar que el servicio está activo es comparando las tramas enviadas por el nodo central
con la información escrita en la base de datos.

6.1.6 Conexión de la web con la base de datos


La página web se sirve constantemente de la información almacenada en la base de datos, es por ello que se
debe realizar una comprobación de esta conexión. Es fácil comprobar que si la página web muestra los datos
actualizados de los diferentes sensores y nodos existe una comunicación correcta. Esta conexión no es
continua, sino que periódicamente se conecta para actualizar los datos. Por lo que está en constante
reconexión.

6.2 Pruebas y calibración de los sensores


Para conocer el estado de los parámetros leídos por los diferentes sensores es necesaria una calibración óptima
de los mismos. Una vez calibrados es necesario realizar una serie de pruebas para comprobar que los datos
obtenidos son los reales, o al menos están dentro de su margen de error.

6.2.1 Sensor DHT11


Este sensor no permite ser calibrado internamente, aunque si se puede comprobar si el sensor funciona
correctamente. El rango de temperatura del sensor es de 0 ºC a 50 ºC. Para conseguir 0 ºC basta con poner en
un recipiente una gran cantidad de hielo y un poco de agua. A 0 ºC el hielo empieza a convertirse en agua, por
lo que esta se encuentra a esa temperatura, debido a que el sensor no es impermeable se introduce dentro de un
plástico impermeable. Pasado unos minutos el sensor se encontrará a la misma temperatura del agua con lo
que se podrá realizar una medición de la temperatura comprobando si se encuentra entre -2ºC y 2ºC. Para
obtener 50 ºC es necesario el uso de otro sensor de temperatura ya calibrado. Se va agregando agua hirviendo
(cercana a los 100 ºC) hasta obtener un valor de temperatura de 50ºC y se introduce el sensor DHT11 dentro
de un plástico impermeable para obtener la medición. Para que la temperatura se mantenga sobre los 50ºC hay
que ir echando más agua hirviendo cuando baje de los 50 ºC intentando mantener esta temperatura lo más
estable posible. Por último, utilizando el mismo sensor de temperatura ya calibrado se realiza una medida.
Para comprobar la medición de la humedad se tiene una mayor limitación, ya que no es fácil encontrar
entornos controlados. Por ello se realiza la medición comparándolo con una estación meteorológica comercial,
la cual viene ya calibrada.

6.2.2 Sensor PIR


El sensor de presencia hay que calibrarlo de forma manual en cada una de las habitaciones debido a que cada
una de estas habitaciones tiene un tamaño y dimensión diferente. Para realizar esta calibración es necesario
ajustar el potenciómetro de sensibilidad. Con la ayuda de otra persona situada en el extremo más alejado del
sensor se ajusta para que la detecte. El sensor debe estar dirigido hacia esa persona ya que la que ajuste el
sensor podría influir en la medida. La persona debe estar agitando los brazos para que el sensor detecte el
movimiento.
Para comprobar que no se ha excedido en cuanto a sensibilidad se comprueba que no se detecta a nadie fuera
de la habitacón pasando por la puerta o ventana, si así fuera se debe ajustar el sensor hasta que no se detecten
personas en los puntos críticos. Esto supone la existencia de puntos ciegos dentro de la habitación, pero no
detectará falsos positivos, lo cual puede alarmar erróneamente al usuario.
76 Pruebas y validación

6.2.3 Sensor LDR


Para realizar la comprobación de las medidas del sensor LDR es necesario un luxómetro, y mediante las
ecuaciones proporcionadas en la sección 3.1.3.3 se obtienen el rango de valores del Sensor LDR. Estas
medidas se realizan a oscuras y bajo la luz de una bombilla de alta luminosidad. De esta forma se pueden
generar valores para M y L que se ajusten perfectamente al sensor LDR en cuestión.

6.2.4 Pruebas RC-522


No existe un método para calibrar este sensor ni su sensibilidad, es por por ello que se debe realizar diferentes
pruebas para identificar cual es el alcance y las posibilidades de este sensor. La primera prueba a la que se
somete este sensor es la de utilizar diversas tarjetas y comprobar que su número de ID siempre es el mismo
para cada una. Es posible que dos tarjetas dispongan del mismo ID, pese a existir una baja probabilidad es un
parámetro a tener en cuenta. En esta prueba hay que tener en cuenta que existen dos escrituras por el puerto
serie, una correspondiente al ID, y la segunda escritura es la correspondiente al ID invirtiendo sus caracteres.
Si se pasa la misma tarjeta varias veces seguidas en un corto espacio de tiempo durante las primeras lecturas
funciona correctamente. Sin embargo al saturar el sistema de publicación del bróker, este desconecta la
conexión al mismo por parte del nodo central. Sin embargo, como el sistema es fuerte frente a este tipo de
caídas es capaz de reconectarse al bróker.
En segundo lugar, se hacen pruebas intentando reconocer la tarjeta metiéndola dentro de una billetera, siendo
esta la única tarjeta en la misma. El resultado en este caso es positivo siempre que no se intente realizar con un
tarjetero metálico.
Posteriormente se introduce en otra billetera con más tarjetas. El resultado de estas pruebas como cabe esperar
es negativo, recoge el resultado de la tarjeta RFID más cercana al sensor. Si se tienen más de tres tarjetas con
RFID no será capaz de reconocer ninguna de ellas. Por ello se comprueba la lectura al pasar varias tarjetas
simultáneamente comprobando cual es el límite de tarjetas.
Para saber si el relé funciona, se conecta un zumbador en el cual el terminal negativo del mismo va conectado
a una resistencia a tierra mientras que el positivo irá conectado al terminal CC del relé. El relé debe tener
conectado tierra en NC y 5V en NO. Cuando se active el relé empezará a sonar el zumbador y cuando este se
desativa parará de sonar. Si esto funciona la sirena que se conecte al relé funcionará.

6.3 Pruebas del sistema completo


Una vez realizadas todas las pruebas de los módulos de comunicación, sensores y del relé de forma unitaria, se
realizan una serie de pruebas que verifiquen el correcto funcionamiento del sistema completo. Para realizar
estas pruebas se pone en funcionamiento la web, la base de datos, el bróker MQTT y el servicio o daemon.

Figura 6-5 – Aviso de nuevo dispositivo


Red de sensores para monitorización inteligente de vivienda 77

En primer lugar, se enciende el nodo central. Este nodo debe conectarse a la red y enviar los datos de lectura
de sus sensores mediante una publicación MQTT. El daemon debe leer la trama, meterla en la base de datos.
Al ser un nodo que no está registrado, el daemon enviará un e-mail al usuario que indicará que se ha agregado
un nuevo nodo al sistema. Desde la página web del sistema no se debe observar ningún dato hasta que sea
modificado el nombre en el panel de administración. Una vez cambiado el nombre se verán todos los datos
registrados con este módulo incluso si este ha sido borrado alguna vez. Para poder ver el historial completo del
sistema hay que pulsar sobre “ver gráficas” y seleccionar el nodo, el sensor y el rango de fechas que se desea
conocer, al pulsar sobre “Cargar” se podrán ver los datos del sensor a modo de gráfica.

Figura 6-6 – Histórico del nodo central

Una vez puesto en marcha el nodo central, al no existir ninguna persona registrada mediante una tarjeta RFID,
no debe de empezar a sonar la alarma. Para que pueda activarse será necesario registrar una tarjeta RFID.
Pasándola sobre el lector RFID instalado en el nodo central, se registrará la tarjeta y se notificará por e-mail.
Se activa la tarjeta cambiando su nombre desde el panel de administración. Una vez activado, cada vez que se
pase la tarjeta por el lectro RFID avisará por e-mail si esa persona sale o entra de casa. Si por algún motivo
uno de usuarios olvida registrar una salida o entrada se producirá un desfase el cual puede ser arreglado en el
panel de control.

Figura 6-7 – Aviso de entrada, salida y armado de la alarma

Cuando todos los usuarios registran una salida y no queda nadie en casa se arma la alarma, la cual empezará a
sonar si se detecta a alguien. Para evitar falsas alarma se esperará treinta segundos desde que se detecta una
presencia, si transcurrido este tiempo se sigue detectando la presencia se activará la alarma.
78 Pruebas y validación

Figura 6-8 – Vista final y verificando el correcto funcionamiento del sistema

Se van agregando nodos periféricos y se le van asignando nombres a cada uno de ellos, de esta forma se
comprueba que el sistema puede aceptar de forma automática tantos nodos como se necesiten hasta un
máximo de 254 nodos periféricos.
Red de sensores para monitorización inteligente de vivienda 79
80 Conclusiones y desarrollos futuros

7 CONCLUSIONES Y DESARROLLOS FUTUROS

El éxito es la habilidad de ir de fracaso en fracaso sin


perder el entusiasmo.
- Winston Churchill-

urante el desarrollo el proyecto ha sufrido varias modificaciones desde la idea original. Al inicio

D consistía en una red de sensores completamente cerrada para una casa en concreto con tres nodos
periféricos (baño, cocina y dormitorio) y un nodo central (salón). Cuyo único cometido era las
lecturas de los sensores en una red tipo estrella, donde los nodos periféricos enviarían tramas con las lecturas
de los sensores de luminosidad, humedad y temperatura junto con una interfaz gráfica en Fi-Ware. Por el
cierre de las licencias gratuitas de servidores Fi-Ware se optó por diseñar una interfaz gráfica web para la
lectura de sensores por HTML y PHP. Tras la aceptación del proyecto por parte del tutor Antonio Luque, se
desarrolló una prueba de concepto donde se podían leer los datos de los sensores junto a un plano de la casa, y
junto a estos datos se mostraba las gráficas de histórico de los sensores.
Cuando se realizó y presentó la prueba de concepto a Antonio Luque, se plantearon tres mejoras del proyecto.
En primer lugar, se plantea que se tratase de una red de sensores abierta y que desde la interfaz web se
gestionase el nombre de estos dispositivos en función de la mac del módem de comunicación xBee. En
segundo lugar, la gestión de una alarma mediante sensores RFID en el nodo central para la gestión de las
entradas y salidas de la vivienda. Así como los sensores de presencia por infrarrojos (PIR) en todos los nodos
de la red. Y como tercera y última mejora se encuentra la posibilidad de modificar el rango temporal de las
gráficas.
La primera mejora estaba ideada para que el nodo central reconociera de forma automática a los nodos
periféricos, y estos reconocieran de la misma forma al nodo central. Por el diseño de la librería no es factible
cambiar la dirección de envío de las tramas de los nodos periféricos, ya que esto desconfiguraría otros
parámetros de la red impidiendo realizar la conexión. El nodo central si es capaz de averiguar cual es el nodo
emisor, de tal forma que se puede obtener la mac del módem como identificador único del nodo periférico.
La segunda mejora se realiza mediante la lectura de los identificadores de la tarjeta RFID, pudiéndose
identificar también de forma única. Se pensaba utilizar algunos espacios de su memoria para la comprobación
de que es una tarjeta real y no copiada. Finalmente se prefiere no utilizar esta opción, ya que si el suplantador
de identidad entra antes que el usuario real podría generar problemas de accesos. En lugar de ello se decidió
utilizar un servicio de e-mail que avisará a tiempo real de quien entra y quien sale de casa. Aprovechando este
servicio se ofrece también el envío de avisos de la alarma, así como de detección de nuevos sensores o nuevas
tarjetas RFID.
Para realizar la selección de la fecha sobre la gráfica, se ha optado por generar un JSON en el servicio PHP.
Debido a que realizar una llamada a un servicio PHP de forma recurrente desde un javascript era poco
eficiente y generaba una serie de errores. Con el uso de JSON se dibuja la gráfica mediante un pop-up interno
en el HTML. Durante el desarrollo de las gráficas Google restringió estas a solo una por página. Por lo que se
Red de sensores para monitorización inteligente de vivienda 81

decidió que desde el mismo pop-up se pudiera ver una gráfica seleccionando un nodo, un sensor y un rango de
fechas.

7.1 Desarrollos futuros


El potencial implícito en el Sistema permite una serie de mejoras que implicarían un valor añadido.

7.1.1 GSM
Esta sería la actualización más importante. Este sistema ha sido diseñado mediante un módulo WiFi para que
cumpliera los objetivos al menor coste de mantenimiento. Si se desea mayor funcionalidad un sistema con
conexión GSM y gestión de batería permitiría informar si se ha desconectado la corriente eléctrica entre otras
muchas posibilidades.

7.1.2 Actuación
Actuar con elementos de climatización o de iluminación del hogar combinan bien con los sensores instalados
en los diferentes nodos, esto proporcionaría un valor añadido que beneficia al usuario permitiendo gestionar su
estado de bienestar de forma automática.

7.1.3 App Movil


Mediante el uso de PhoneGap o Cordova se puede realizar una aplicación móvil desde HTML. Con pequeñas
modificaciones a la página principal se puede obtener una interfaz móvil sencilla con la posibilidad de recibir
notificaciones desde la propia aplicación, mucho más rápido que el sistema de e-mail actual.
82 Referencias bibliográficas

8 REFERENCIAS BIBLIOGRÁFICAS
[1] Isabel Yanez. “La domótica, un bien para todos”. Revista digital - Innovación y Experiencias Educativas,
Nº30, Mayo 2010.
[2] David A. Wheeler, “Why Open-source Software/ Free Software (OSS/FS, FLOSS, or FOSS)?Look at the
Numbres!” July 18,2015 [online] Disponible en: http://www.dwheeler.com/oss_fs_why.html
[3] Iván González, Juan González, Francisco Gómez-Arribas. ”Hardware libre: Clasificación y desarrollo de
hardware reconfigurable en entornos GNU/Linuz", 06 de Septiembre de 2016 [online] Disponible en:
http://es.tldp.org/Presentaciones/200309hispalinux/8/8.pdf
[4] Sección “About Us” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/AboutUs
[5] Massimo Banzi. ”Fighting for Arduino”. Make Magazine (Makezine). March 19, 2015 [online] Disponible
en: http://makezine.com/2015/03/19/massimo-banzi-fighting-for-arduino/
[6] Sección “Older Boards” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/Boards
[7] Sección “Arduino UNO” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardUno
[8] Datasheet Atmel ATmega48A/PA/88A/PA/168A/PA/328/P
[9] Sección “Products” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/Products
[10] Sección “Arduino Leonardo” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-leonardo
[11] Datasheet Atmel ATmega16U4/ATmega32U4
[12] Sección “Arduino Mega” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardMega2560
[13] Datasheet Atmel ATmega640/V-1280/V-1281/V-2560/V-2561/V
[14] Sección “Arduino Pro” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardPro
[15] Sección “Arduino Pro Mini” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardProMini
[16] Sección “Arduino Nano” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardNano
[17] Sección “Arduino Micro” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardMicro
[18] Sección “Arduino Fio” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardFio
[19] Sección “Arduino Due” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-due
[20] Datasheet Atmel SAM3X / SAM3A Series
Red de sensores para monitorización inteligente de vivienda 83

[21] Sección “Arduino Zero” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoBoardZero
[22] Sección “Arduino M0 Pro” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-M0-pro
[23] Sección “Arduino M0” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-M0
[24] Sección “Arduino 101” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/Arduino101
[25] Sección “Arduino MKR1000” página web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Main/ArduinoMKR1000
[26] Sección “Arduino Yún” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-yun
[27] Sección “Arduino Tian” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-tian
[28] Sección “Arduino Industrial 101” página web www.arduino.org [online] Disponible en:
http://www.arduino.org/products/boards/arduino-industrial-101
[29] Matt Sarnoff. ”Why I‟m Excited That Microchip Is Buying Atmel”. Make Magazine (Makezine), January
25, 2016 [online] Disponible en: http://makezine.com/2016/01/25/why-im-excited-that-microchip-is-buying-
Atmel/
[30] Seccion “Pinguino” pagina web www.hackinlab.org, creadores de arduino [online] Disponible en:
http://www.hackinglab.org/pinguino/index_pinguino.html
[31] Sección “UNO32” página web www.chipkit.net [online] Disponible en:
http://chipkit.net/wpcproduct/chipkit-uno32/
[32] Sección “MAX32” página web www.chipkit.net [online] Disponible en:
http://chipkit.net/wpcproduct/chipkit-max32/
[33] Sección “waspmote” página web www.libelium.com [online] Disponible en:
http://www.libelium.com/products/waspmote/
[34] Pagina web www.energia.nu [online]
[35] Sección “launchpad” página web www.ti.com [online] Disponible en:
http://www.ti.com/ww/en/launchpad/launchpad.html?DCMP=mcu-launchpad&HQS=launchpad
[36] IEEE Std 802.11, 2012
[37] IEEE Std 802.15.1 , 2005
[38] Sección “Basic Rate/Enhanced Data Rate” página web www.bluetooth.com [online] Disponible en:
https://www.bluetooth.com/what-is-bluetooth-technology/bluetooth-technology-basics/br-edr
[39] Sección “Bluetooth High Speed” página web www.bluetooth.com [online] Disponible en:
https://www.bluetooth.com/what-is-bluetooth-technology/bluetooth-technology-basics/bluetooth-high-speed
[40] Sección “Bluetooth Low Energy” página web www.bluetooth.com [online] Disponible en:
https://www.bluetooth.com/what-is-bluetooth-technology/bluetooth-technology-basics/low-energy
[41] IEEE Std 802.15.4, 2003
[42] Seccion “xBee” página web www.digi.com [online] Disponible en: http://www.digi.com/lp/xbee
[43] Seccion “xBee” página web www.digi.com [online] Disponible en: http://www.digi.com/products/xbee-
rf-solutions/modules/xbee-802-15-4
[44] Seccion “ZigBee” página web www.digi.com [online] Disponible en:
http://www.digi.com/products/xbee-rf-solutions/rf-modules/xbee-zigbee
84 Referencias bibliográficas

[45] Antonio Perez Yuste. "El proceso de implantación de la telefonía móvil en España". Revista Antena del
COITT. Septiembre 2002.
[46] Sección “about” página web www.sigfox.com [online] Disponible en: http://makers.sigfox.com/#about
[47] Telit LE51 868S RF Module User Guide Rev.1, 2014
[48] "La mayoría de los operadores móviles fijan el fin de las redes GSM en 2017", Revista PCworld España,
Junio 2015 [online] disponible en: http://www.pcworld.es/movilidad/la-mayoria-de-los-operadores-moviles-fijan-el-
fin-de-las-redes-gsm-en-2017
[49] Sección “About” página web www.nodejs.org [online] Disponible en: https://nodejs.org/es/about/
[50] Sección “Upgrading the WiFi shield firmware” pagina web www.arduino.cc [online] Disponible en:
https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading
Red de sensores para monitorización inteligente de vivienda 85
86 Anexos

9 ANEXOS
9.1 Anexo I - Código del nodo central
/******************************************************************

Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa

Nodo central:
El nodo central es el encargado en primer lugar de comunicar
la red de sensores con la nube. En segunda instancia se encarga
del sistema de alarma. Si estando el sistema de alarma activo
se detecta una persona sin autentificacion RFID, la alarma
sonará e informará al inquilino/propietario. En último lugar,
al igual que el resto de nodos, se encargara tambien de las
mediciones de Luz, Humedad, Temperatura y Presencia.

El nodo consta:
Arduino Uno
Shield WiFi
Shield xBee
Módulo xBee Serie 2 (ZigBee)
Módulo RFID-RC522
Sensor PIR
Sensor DHT11
LDR
Módulo Relé

******************************************************************/

//Librerías incorporadas de arduino


#include <WiFi.h>
#include <SPI.h>

//librerias del microcontrolador/compilador


#include <stdlib.h>

//librerias externas
#include <XBee.h>
#include <PubSubClient.h>
#include <dht11.h>
#include <MFRC522.h>

//Constantes necesarias para la conexión con el servidor MQTT


#define MQTT_SERVER_IP "192.168.0.102"
// Dirección del servidor MQTT que vamos a utilizar
#define MQTT_SERVER_PORT 1883
// Puerto del servidor MQTT
#define MQTT_USER "admin"
// Usuario de MQTT
Red de sensores para monitorización inteligente de vivienda 87

#define MQTT_PASS "password"


// Password del usuario de MQTT

//Constantes necesarias para RFID


#define RST_PIN 8
// Pin Reset del del módulo RFID
#define SS_PIN 6
// Pin de control del módulo RFID

//Variable para la lectura de los sensores


unsigned int temperatura;
// Variable donde se almacena la temperatura leída
unsigned int humedad;
// Variable donde se almacena la humedad leída
dht11 DHT11;
// Instancia del objeto DHT11

float luminosidad;
// Variable donde se almacena la luminosidad leída

boolean presencia;
// Variable donde se almacena la presencia leída

//Variables necesarias para WiFi:

//Datos de conexion
char ssid[] = "JAVIER";
// SSID de la red a conectar.
char pass[] = "password";
// Password de la red a conectar
char tramaGet[100];
// Array de caracteres donde almacenar la trama recibida
char MAC[10];
// Array de caracteres donde almacenar la MAC del emisor

//variable de estado:
int status = WL_IDLE_STATUS;
// Varlor de estado de la Shield WiFi

//Inicializamos la variable de cliente WiFi.


WiFiClient client;
// Instancia del cliente WiFi
WiFiClass clase;
// instacia de la clase WiFi
uint8_t * MACWIFI;
// Puntero para almacenar la MAC de la Shield WiFi

long int tactual = 0;


// Variable para almacenar el tiempo de ejecución actual
long int tantiguo = 0;
// Variable para almacenar el tiempo de ejecución antiguo

//declaración de funciones:

void callback(char* topic, byte* payload, unsigned int length);


void conectarRed();
void creaTrama();
void lectura();
int leeXBee();
void montaTrama();
void suenaAlarma();
88 Anexos

void long2Char(unsigned long int largo, char * caracter);


void softReset();

//variables necesarias para la conexión MQTT


PubSubClient clientmqtt(MQTT_SERVER_IP, MQTT_SERVER_PORT, callback, client);
// Para el uso como cliente MQTT, callback es la función a la que se llama
cuando llega un mensaje al arduino.

//Variables necesarias para la lectura del xBee


char Trama[55];
// Creamos una trama vacía de 55 caracteres
uint8_t tam = 0;
// Nos dirá el tamaño de la trama recibida
int RxFlag = 0;
// Bandera que avisa si se ha recubido una trama xBee
int SendFlag = 0;
// Bandera que avisa que se tiene que enviar una trama por WiFi
uint32_t macLsb = 0;
// Variable que almacena los bits menos significativos de la MAC

XBee xbee = XBee();


// Instancia del objeto XBee

XBeeResponse response = XBeeResponse();


// Instancia del objeto XBeeResponse
ZBRxResponse rx = ZBRxResponse();
// Instancia del objeto ZBRxResponse
ModemStatusResponse msr = ModemStatusResponse();
// Instancia del objeto ModemStatusResponse

char texto[55] ;
// Array donde almacenar la trama a enviar por WiFi

//Variables para detectar tarjetas RFID


MFRC522 mfrc522(SS_PIN, RST_PIN);
// Instancia del objetoo MFRC522
unsigned long int IDcard = 0;
// Varibale para almacenar el valor del ID de la tarjet RFID

//Otras variables
boolean Alarma = false;
// Bandera que activa la Alarma
boolean Tpresente = false;
// Bandara que avisa de que existe una tarjeta presente
boolean primero = false;
// Bandera que avisa si se ha enviado la primera trama MQTT
int cuentaIntentos = 0;
// Variable que cuenta los intentos de reconexión

/*
* Función que se ejecuta una sola vez al iniciar la ejecución del programa
o tras un reset
*/
void setup() {
//Inicializamos el puerto Serie a 115200 ya que es el BaudRate configurado
con los xBee.
Serial.begin(115200);

//llamamos a la funcion conectarRed.


conectarRed();

//Inicializamos el xBee
Red de sensores para monitorización inteligente de vivienda 89

xbee.begin(Serial);

//Inicializamos el RFID
SPI.begin();
mfrc522.PCD_Init();

//Especificamos que es la primera conexión


primero = true;
}

/*
* Función principal, se ejecuta en bucle
*/
void loop() {
//Se realiza una lectura de los sensores
lectura();
//Se comprueba el estado de la conexión MQTT
if (!clientmqtt.connected()) {
//Si está desconectado, intentamos reconectarlo.
Serial.println(clientmqtt.state());
Serial.println("desconectado");
char clientID_buffer[22];
//Se genera un ID aleatorio para el servidor MQTT
for (int i = 0; i < 22; i++)
clientID_buffer[i] = random('a', 'z');
//Se realiza la conexión MQTT
if (clientmqtt.connect(clientID_buffer, MQTT_USER, MQTT_PASS,
"pfc/estado", 0, 1, "0")) {
//Se subscribe a la alarma y se publica un estado ON.
clientmqtt.publish("pfc/estado", (uint8_t*)"on", strlen("on"), true);
clientmqtt.subscribe("pfc/alarma");
Serial.println("Se ha conectado al broker");
cuentaIntentos = 0;
//Se comprueba si es la primera conexión de ser así se envía una
lectura
if (primero) {
creaTrama();
Serial.println(texto);
clientmqtt.publish("pfc/lectura", (uint8_t*)texto, strlen(texto),
true);
tantiguo = millis();
primero = false;
}
} else {
Serial.println("No se pudo conectar al broker");
//Si no puede conectarse, lo intentará nuevamente en la prózima
iteración
delay(6000);
//Si fallan 10 intentos se reinicia la placa
if (cuentaIntentos++ > 10) {
softReset();
}
//Se imprime el buffer del modem
while (client.available()) {
char c = client.read();
Serial.write(c);
}
//Se comprueba el estado de la conexión
status = WiFi.status();
while ( status != WL_CONNECTED ) {
// Serial.print/println solo activo para debugear el programa
Serial.println("Reiniciando conexion a la red");
//Realizamos la conexion mediante el siguiente comando:
90 Anexos

conectarRed();
}
}
} else {
//Si esta conectado comprueba si ha recibido algún paquete xBee
if (leeXBee()) {
Serial.println("Paquete Recibido:");
Serial.println(Trama);
//Monta la trama con la MAC
montaTrama();
Serial.println(tramaGet);
//Publica la trama por MQTT
clientmqtt.publish("pfc/lectura", (uint8_t*)tramaGet,
strlen(tramaGet), true);
Serial.println("ok");
}
//Realiza una lectura de los sensores
lectura();
tactual = millis();
//Se comprueba si millis() ha desbordado
if (tactual < tantiguo) {
tantiguo = tactual;
creaTrama();
Serial.println(texto);
/Se publica la trama
clientmqtt.publish("pfc/lectura", (uint8_t*)texto, strlen(texto),
true);
}

//Se comprueba si tiene que volver a mandar una trama por MQTT
if ( (tactual - tantiguo >= 900000) || (Alarma && (tactual - tantiguo >=
60000)) ) {
tantiguo = tactual;
creaTrama();
Serial.println(texto);
//Se publica la trama
clientmqtt.publish("pfc/lectura", (uint8_t*)texto, strlen(texto),
true);
}
}
/*
* Se comprueba si hay una tarjeta en el sensor RFID
*/
if ( mfrc522.PICC_IsNewCardPresent() && !Tpresente) {
IDcard = 0;
char RFID_ID[10];
if ( mfrc522.PICC_ReadCardSerial()) {
for (byte i = 0; i < mfrc522.uid.size; i++) {
RFID_ID[i] = (char) mfrc522.uid.uidByte[i];
IDcard += RFID_ID[i] * pow(10, (mfrc522.uid.size - i - 1));
}
Serial.println(IDcard);
long2Char(IDcard, RFID_ID);
Serial.println(RFID_ID);
clientmqtt.publish("pfc/rfid", (uint8_t*)RFID_ID, strlen(RFID_ID),
true);
Tpresente = true;
}
}
No aceptara una nueva tarjeta hasta que no se retire la anterior
if (!mfrc522.PICC_IsNewCardPresent() && Tpresente) {
return;
Red de sensores para monitorización inteligente de vivienda 91

} else {
Tpresente = false;
}
//Se realiza un ping al broker MQTT
clientmqtt.loop();
if (Alarma) {
suenaAlarma();
}
}

/*
Esta función es obligatoria para poder utilizar la librería MQTT. Esta
función permite trabajar con los datos recibidos de una subscripcción MQTT.
Para saber que hacer con el mensaje es necesrio comprobar el topic.
Una vez comprobado el Topic se realiza la tarea indicada.
*/
void callback(char* topic, byte* payload, unsigned int length) {
//Se copia la trama recibida en una variable local
char recibido[128];
int i = 0;
for (i = 0; i < length; i++) {
recibido[i] = payload[i];
}

//Se borran los datos sobrantes de la variable local


for (i; i < 128 ; i++) {
recibido[i] = 0;
}

// Se comprueba si es el topic alarma.


// En este caso se podría omitir esta comprobación ya que solo está
subscrito a este topic.
if (strstr(topic, "alarma") != NULL) {
//Una vez comprobado el Topic se comprueba el mensaje para saber que
acción realizar
if (strstr(recibido, "ON") != NULL) {
//Enciende la alarma
Alarma = true;
Serial.println("Alarma encendida");
} else if (strstr(recibido, "OFF") != NULL) {
//Apaga la alarma
Alarma = false;
Serial.println("Alarma Apagada");
} else {
//Se trata de un comando no válido, se muestra por pantalla para
conocerel dato recibido.
Serial.println(recibido);
}
}
}
/*
La funcion conectarRed(); nos permite conectarnos a una red WiFi con los
datos
introducidos en las variables ssid[] y pass[]. No requiere ningun atributo y
será
de tipo void. Por lo que no será necesario la devolución de ningún dato.
*/
void conectarRed(){
//Comprobamos si la Shield WiFi está instalada en el arduino.
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("Shield WiFi no instalada en el arduino, instalela por
favor.");
//Se realiza un delay para que el mensaje se imprima completo
92 Anexos

delay(1000);
//Se reseteará sola para comprobar si se ha instalado.
softReset();
}

//Una vez comprobado que tenemos la placa instalada, realizamos la


conexión
while( status != WL_CONNECTED ){

// Serial.print/println solo activo para debugear el programa


Serial.println("Iniciando conexion a la red");

//Realizamos la conexion mediante el siguiente comando:


status = WiFi.begin(ssid, pass);
delay(30000);

//Si en diez intentos no se ha conectado, se resetea la placa


if(cuentaIntentos++ > 10){
softReset();
}

//Si se ha conectado se muestra por pantalla los datos de la conexión


Serial.println("El dispositivo esta conectado");
Serial.print("Direccion IP: ");
Serial.println(WiFi.localIP());
Serial.print("Potencia de Senal (RSSI): ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");

/*
* Se genera la trama, en este caso es necesario incluir el valor LSB de la
MAC
*/
void creaTrama() {
//definimos las variables que vamos a utilizar y las inicializamos
int trama = 0;
int auxtrama = 0;
uint8_t tam;
uint8_t ASCII = B10000000;
char datos[4] = {0, 0, 0, 0};
char pir[]="PIR";
char tem[]="TEM";
char hum[]="HUM";
char luz[]="LUZ";
char mac[]="MAC=1085975315&";

uint8_t i = 0;
uint8_t j = 0;

//borrado de trama.

for (i = 0; i < 55; i++) {


texto[i] = 0x00;
}

//Se pone el valor de la MAC


for(i=0;i<15;i++,j++){
texto[j] = mac[i];
Red de sensores para monitorización inteligente de vivienda 93

//Se pone el nombre del sensor de tempertatura y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = tem[i];
}
texto[j++] = '=';
//Escribimos el valor leido de temperatura
trama = temperatura;
if (trama >= 100 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 100) {
texto[j] += 1;
trama -= 100;
}
j++;
auxtrama = 1;
}
if (trama >= 10 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 10) {
texto[j] += 1;
trama -= 10;
}
j++;
auxtrama = 1;
}
texto[j] = 0x30;
while (trama >= 1) {
texto[j] += 1;
trama -= 1;
}
j++;
auxtrama = 0;

texto[j++] = '&';

//Se pone el nombre del sensor de humedad y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = hum[i];
}
texto[j++] = '=';
//Escribimos el valor leido de humedad
trama = humedad;
if (trama >= 100 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 100) {
texto[j] += 1;
trama -= 100;
}
j++;
auxtrama = 1;
}
if (trama >= 10 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 10) {
texto[j] += 1;
trama -= 10;
}
j++;
auxtrama = 1;
}
texto[j] = 0x30;
94 Anexos

while (trama >= 1) {


texto[j] += 1;
trama -= 1;
}
j++;
auxtrama = 0;

texto[j++] = '&';

//Se pone el nombre del sensor de luminosidad y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = luz[i];
}
texto[j++] = '=';

//Escribimos el valor leido de luminosidad


trama = luminosidad;
if (trama >= 1000) {
texto[j] = 0x30;
while (trama >= 1000) {
texto[j] += 1;
trama -= 1000;
}
j++;
auxtrama = 1;
}
if (trama >= 100 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 100) {
texto[j] += 1;
trama -= 100;
}
j++;
auxtrama = 1;
}
if (trama >= 10 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 10) {
texto[j] += 1;
trama -= 10;
}
j++;
auxtrama = 1;
}
texto[j] = 0x30;
while (trama >= 1) {
texto[j] += 1;
trama -= 1;
}
j++;
auxtrama = 0;

texto[j++] = '&';

//Se pone el nombre del sensor de presencia y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = pir[i];
}
texto[j++] = '=';
//Escribimos el valor leido de presencia
if(presencia)
texto[j++]='1';
Red de sensores para monitorización inteligente de vivienda 95

else
texto[j++]='0';

texto[j] = 0x00;

/*
* Función que realiza la lectura de los sensores
*/
void lectura() {
int chk = DHT11.read(2);
humedad = DHT11.humidity;
temperatura = DHT11.temperature;
presencia = 0;
if (digitalRead(5)) {
presencia = 5;
}
luminosidad = analogRead(A0);
}

/*
* Se ejecuta la funcion lee xBee para leer, en el caso de que halla alguna
trama
* Devuelve como resultado el tamaño de la trama. Quedandose almacenada la
trama en
* la variable vacía Trama
*/
int leeXBee() {
//Leemos el Paquete
int existe=0;
xbee.readPacket();
RxFlag=0;
if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
xbee.getResponse().getZBRxResponse(rx);
RxFlag=1;
SendFlag=1;

}
if (SendFlag==1){
if(RxFlag=0){
Serial.println("Paquete Recibido");
tam=rx.getDataLength();
//Serial.println(tam);
for(int aux=0;aux<55;aux++){
Trama[aux]=(char)rx.getData(aux);
}
macLsb = rx.getRemoteAddress64().getLsb();
Serial.println(macLsb);
for(int aux=0;aux<10;aux++){
MAC[aux]=0x00;
}

long2Char(macLsb, MAC);
Serial.write(MAC);

Serial.println();
SendFlag=0;
existe=1;
}
}
return existe;
}
96 Anexos

/*
* La funcion montaTrama, genera una trama para poder hacer la llamada al
* webservice, que introducirá los datos en una base de datos.
*/
void montaTrama(){
char cabecera[]="MAC=";
int i = 0;
int j = 0;

//Borramos la trama.
for (i = 0; i < 100; i++) {
tramaGet[i] = 0x00;
}
for(i = 0 ; i < 4 ; i++,j++){
tramaGet[j] = cabecera[i];
}
for(i = 0; i<10; i++ , j++){
tramaGet[j] = MAC[9-i];
}
tramaGet[j++] = '&';
for(i = 0 ; Trama[i] != 0x00 ; i++,j++){
tramaGet[j] = Trama[i];
}
}

/*
Variable que pasa una variable del tipo long a una cadena de caracteres.
Tiene dos parametros, el primero es la variable, y el segundo
es la dirección de la cadenna donde se quiere almacenar.
*/
void long2Char(unsigned long int largo, char * caracter) {
int subvalor = 0;
while (largo >= 1000000000) {
largo -= 1000000000;
subvalor++;
}
if (subvalor) {
caracter[9] = subvalor + '0';
} else {
caracter[9] = '\0';
}
subvalor = 0;
while (largo >= 100000000) {
largo -= 100000000;
subvalor++;
}
if (subvalor == 0 && caracter[9] == '\0') {
caracter[8] = '\0';
} else {
caracter[8] = subvalor + '0';
}
subvalor = 0;
while (largo >= 10000000) {
largo -= 10000000;
subvalor++;
}
if (subvalor == 0 && caracter[8] == '\0') {
caracter[7] = '\0';
} else {
caracter[7] = subvalor + '0';
}
Red de sensores para monitorización inteligente de vivienda 97

subvalor = 0;
while (largo >= 1000000) {
largo -= 1000000;
subvalor++;
}
if (subvalor == 0 && caracter[7] == '\0') {
caracter[6] = '\0';
} else {
caracter[6] = subvalor + '0';
}
subvalor = 0;
while (largo >= 100000) {
largo -= 100000;
subvalor++;
}
if (subvalor == 0 && caracter[6] == '\0') {
caracter[5] = '\0';
} else {
caracter[5] = subvalor + '0';
}
subvalor = 0;
while (largo >= 10000) {
largo -= 10000;
subvalor++;
}
if (subvalor == 0 && caracter[5] == '\0') {
caracter[4] = '\0';
} else {
caracter[4] = subvalor + '0';
}
subvalor = 0;
while (largo >= 1000) {
largo -= 1000;
subvalor++;
}
if (subvalor == 0 && caracter[4] == '\0') {
caracter[3] = '\0';
} else {
caracter[3] = subvalor + '0';
}
subvalor = 0;
while (largo >= 100) {
largo -= 100;
subvalor++;
}
if (subvalor == 0 && caracter[3] == '\0') {
caracter[2] = '\0';
} else {
caracter[2] = subvalor + '0';
}
subvalor = 0;
while (largo >= 10) {
largo -= 10;
subvalor++;
}
if (subvalor == 0 && caracter[2] == '\0') {
caracter[1] = '\0';
} else {
caracter[1] = subvalor + '0';
}
subvalor = 0;
while (largo >= 1) {
largo -= 1;
98 Anexos

subvalor++;
}
if (subvalor == 0 && caracter[1] == '\0') {
caracter[0] = '\0';
} else {
caracter[0] = subvalor + '0';
}
}

/*
Función que realiza un reset software. El programa empieza desde cero, pero
no resetea ni los perifericos ni los registros
*/
void softReset()
{
asm volatile (" jmp 0");
}
Red de sensores para monitorización inteligente de vivienda 99
100 Anexos

9.2 Anexo II - Código del nodo periférico


/******************************************************************

Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa
`
Nodo periférico:
Es el encargado de recopiilar la lectura de los sensores y
mandarla al nodo central mediante xBee.
Este nodo funciona con una bater'ia por lo que es necesario
poner el microcntrolador en modo ahorro de energ'ia.
Como el nodo central es el encargado de reconocer quién
envía la trama, no será necesario descrubir la MAC
del modem xBee desde este nodo.
******************************************************************/

//Librerías del microcontrolador/compilador


#include <avr/sleep.h>
#include <avr/power.h>
#include <stdlib.h>

//Librerías externas
#include <XBee.h>
#include <dht11.h>

//Variables a modificar
int minutos = 30; // Minutos
entre envíos
int horas = 1; // Horas
entre envíos
boolean repetirPIR = false; // Bandera
para repetir lectura
boolean ultimaLectura =false; // Bandera
de presencia

//Variables necesarias para xBee


XBee xbee = XBee(); // Instancia
del objeto XBee
int TAM_MAX = 55; // Tamaño
máximo de la trama
uint8_t texto[TAM_MAX] ; // Array del
mensaje enviado
XBeeAddress64 addr64 = XBeeAddress64(0x0013A200, 0x40BAAB13); // MAC del
CORDINATOR
ZBTxRequest zbTx = ZBTxRequest(addr64, texto, sizeof(texto)); // Socket a
enviar
ZBTxStatusResponse txStatus = ZBTxStatusResponse(); // Estado de
la respuesta

//Variables para el DHT11


dht11 DHT11; // Instancia
del objeto DHT11

//Variables
Red de sensores para monitorización inteligente de vivienda 101

int temperatura; // Variable


para almacenar la temperatura
int humedad; // Variable
para almacenar la humedad
int luminosidad; // Variable
para almacenar la luminosidad
boolean presencia; // Variable
para almacenar la presencia
int contador = 1; // Contador
decreciente para despertar el xBee
int stat = 0; // Para
comprobar el estado de la respuesta
int err = 0; // Para
comprobar si existe un error en la transmision
int errores=0; // Contador
de errores de transmion
int DTR=3; // PIN para
despertar o dormir el modem xBee
int tiempo=0; // Para
saber que el dispositivo no se ha quedado bloqueado
int cuenta; // Variable
para comprobar si ha existido algun reinicio

/*
* Función setup, solo se ejecuta una vez al inicio de la ejecución del
programa
*/
void setup() {
//Se configura el PIN del DTR como salida
pinMode(DTR,OUTPUT);
//Iniciamos el puerto serie al BR del xBee
Serial.begin(115200);
//Inicializamos el xBee.
xbee.setSerial(Serial);
//Comando de prueba
Serial.println("Activo");
//Esperamos a que se inicialize la comunicación del xBee en su PAN ID.
delay(5000);
//Iniciamos el contador de errores.
errores=0;
//Encendemos el temporizador del wdt
watchDogOn();
//Para comprobar reinicios.
tiempo= millis();
}

/*
* Función que se ejecuta en bucle constantemente cuando el dispositivo
* está funcionando.
*/

void loop() {
WDTCSR=0x00; //desactivo el wdt
// Cada 25 ciclos del watchdog se envía un dato a pantalla para saber
// si se ha quedado bloqueado
if(contador == cuenta){
Serial.println(contador);
delay(1);
cuenta = contador-25;
}
//Comprobamos si hay que volver a dormir el dispositivo
if (contador > 1) {
WDTCSR=0x71; //activo el wdt
102 Anexos

duerme();
} else {
//Si no hay que dormirlo, se despierta con el DTR
digitalWrite(DTR,LOW);
delay(100);
//Reenvía la ultima trama, no debe de llegar
xbee.send(zbTx);
//Se espera suficiente tiempo para despertar el xBee
delay(30000);
//Se realiza una lectura de los sensores
lectura();
//Se crea la trama a enviar
CreaTrama();
//Se env´ia la trama que s´i debe de llegar
xbee.send(zbTx);

//comprobamos los errores


xbee.readPacket(1500);
Serial.println();
//Se obtienen los errores si existen
err = xbee.getResponse().getErrorCode();
//Se comprueba el estado del env´io
stat = xbee.getResponse().getApiId();
if (stat == 0 && err == 0) {
Serial.println("ERROR");
errores++;
} else if (stat == 117) {
Serial.println("ERRROR");
errores++;
} else {
Serial.println("OK");
}
//Si se acumulan 50 errores se resetea la placa
if(errores>50){
softReset();
}

delay(500);

// Se calcula el n´umero de veces que debe dormir el nodo antes de cada


reenv´io
contador = (60 * minutos)/8; // Minutos
cuenta = contador-25;
WDTCSR=0x71; //activo el wdt
duerme();
}
}
/*
* Una vez obtenidos los datos de la lecturra monta una trama para enciar
con el formato
* TEM=XX&HUM=XX&LUZ=XXXX&PIR=X
*/
void CreaTrama() {
//definimos las variables que vamos a utilizar y las inicializamos
int trama = 0;
int auxtrama = 0;
uint8_t tam;
uint8_t ASCII = B10000000;
char datos[4] = {0, 0, 0, 0};
//Nombres de cada sensor
char pir[]="PIR";
Red de sensores para monitorización inteligente de vivienda 103

char tem[]="TEM";
char hum[]="HUM";
char luz[]="LUZ";
//variables auxiliares
uint8_t i = 0;
uint8_t j = 0;

//borrado de trama.

for (i = 0; i < TAM_MAX; i++) {


texto[i] = 0x00;
}

//Se pone el nombre del sensor de tempertatura y el simbolo =.


for(i=0;i<3;i++,j++){
texto[j] = tem[i];
}
texto[j++] = '=';

//Escribimos el valor leido de temperatura.


trama = temperatura;
if (trama >= 100 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 100) {
texto[j] += 1;
trama -= 100;
}
j++;
auxtrama = 1;
}
if (trama >= 10 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 10) {
texto[j] += 1;
trama -= 10;
}
j++;
auxtrama = 1;
}
texto[j] = 0x30;
while (trama >= 1) {
texto[j] += 1;
trama -= 1;
}
j++;
auxtrama = 0;

texto[j++] = '&';

//Se pone el nombre del sensor de humedad y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = hum[i];
}
texto[j++] = '=';
//Escribimos el valor leido de humedad
trama = humedad;
if (trama >= 100 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 100) {
texto[j] += 1;
trama -= 100;
}
j++;
104 Anexos

auxtrama = 1;
}
if (trama >= 10 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 10) {
texto[j] += 1;
trama -= 10;
}
j++;
auxtrama = 1;
}
texto[j] = 0x30;
while (trama >= 1) {
texto[j] += 1;
trama -= 1;
}
j++;
auxtrama = 0;

texto[j++] = '&';

//Se pone el nombre del sensor de luminosidad y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = luz[i];
}
texto[j++] = '=';

//Escribimos el valor leido de luminosidad


trama = luminosidad;
if (trama >= 1000) {
texto[j] = 0x30;
while (trama >= 1000) {
texto[j] += 1;
trama -= 1000;
}
j++;
auxtrama = 1;
}
if (trama >= 100 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 100) {
texto[j] += 1;
trama -= 100;
}
j++;
auxtrama = 1;
}
if (trama >= 10 || auxtrama == 1) {
texto[j] = 0x30;
while (trama >= 10) {
texto[j] += 1;
trama -= 10;
}
j++;
auxtrama = 1;
}
texto[j] = 0x30;
while (trama >= 1) {
texto[j] += 1;
trama -= 1;
}
j++;
Red de sensores para monitorización inteligente de vivienda 105

auxtrama = 0;

texto[j++] = '&';

//Se pone el nombre del sensor de presencia y el simbolo =


for(i=0;i<3;i++,j++){
texto[j] = pir[i];
}
texto[j++] = '=';
//Escribimos el valor leido de presencia
if(presencia)
texto[j++]='1';
else
texto[j++]='0';

texto[j] = 0x00;

}
/*
* Función que permite que el dispositivo entre en modo de ahorro
* de energía.
*/
void duerme() {
//Se pone el dispositivo a dormir
digitalWrite(DTR,HIGH);
//Se establece el modo ahorro de energía que nos interese
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable(); //lo ponemos para que pueda dormir
//apagamos todos los modulos
PRR=B11111111;
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_adc_disable();
power_twi_disable();
power_spi_disable();
//duerme
sleep_mode();
//------->despierta Se encienden todos los modulos
PRR=B00000000;
power_all_enable();
sleep_disable();
}

/*
* Función que se ejecuta al desbordar el watchdog, comprueba
* si hay alguna presencia nueva para alarmar al nodo central
*/
ISR(WDT_vect)
{
contador--;
if (digitalRead(4) && !ultimaLectura) {
contador = 0;
}
}

/*
* Función donde se realizan las lecturas de los sensores
*/

void lectura() {
// Se comprueba si existe el sensor DHT11 asociado al pin 4
int chk = DHT11.read(4);
106 Anexos

if (!chk) {
// Si existe se almacenan los datos de tempereratura y humedad
humedad = DHT11.humidity;
temperatura = DHT11.temperature;
}
// Se comprueba si existe presencia
presencia = 0;
if (digitalRead(2)) {
presencia = 5;
}
// Se lee el valor de luminosidad
luminosidad = analogRead(A0);
// Se establece el valor de presencia como última lectura
ultimaLectura = presencia;
}

/*
* Función para hacer un reset software
*/
void softReset()
{
asm volatile (" jmp 0");
}

/*
* Sirve para configurar y activar el watchdog
*/
void watchDogOn(){
// Borra la marca de reinicio, el bit WDRF (bit 3) de MCUSR
MCUSR = MCUSR & B11110111;
/*
Coloca el bit WDCE (bit 4) y el bit WDE bit (bit 3)
de WDTCSR. El bit WDCE debe ser colocado en orden a
a cambiar WDE o los preescaladores del watchdog. Configurando el
bit WDCE permitirá actualizar a los preescaladores y
WDE para 4 ciclos de reloj, luego será reiniciado por hardware.
*/
WDTCSR = WDTCSR | B00011000;
// Establce el preescalador de tiempo de espera de vigilancia a un valor
de 1024k
// el cual rentabilizará el intervalo de tiempo de espera sobre los
8seg.
WDTCSR = B00100001;
// Activa la interrupción por temporizador.
WDTCSR = WDTCSR | B01000000;
MCUSR = MCUSR & B11110111;
}
Red de sensores para monitorización inteligente de vivienda 107
108 Anexos

9.3 Anexo III - Código del servicio NodeJS


/*
Es necesario tener nodeJS instalado y descargar el paquete mqtt (npm install
mqtt --save)
*/
var mqtt = require('mqtt');
/*
Para realizar la conexion con la base de datos en mySQL es necesario tener
el paquete de
mysql instalado (npm install mysql --save)
*/
var mysql = require('mysql');
/*
Para realizar avisos por e-mail es necesario tener el paquete nodeMailer.
(npm install nodemailer --Save)
*/
var nodemailer = require('nodemailer');

/*
Definimos el usuario, contraseña y servidor de correos de la cuenta que
vamos a utilizar para mandar el e-mail.
*/
var transporter =
nodemailer.createTransport('smtps://j.arcenegui.pfc%40gmail.com:password@smtp
.gmail.com');

/*
Genera un valor aleatorio. Sera utilizado para generar una palabra aleatoria
como usuario
que servira para subscribirse al broker de MQTT.
*/
var rand = function(){
return Math.random().toString(36).substr(2);
}
/*
Genera la palabra aleatoria basandose en la funcion rand();
*/
var token = function() {
return rand() + rand();
};
/*
Pasa la palabra generada de forma aleatoria a String para convertirlo en una
palabra
lejible para el broker
*/
var client_ID = token().toString();
/*
Se hace la conexion al MQTT , como primer objeto le pasamos la direccion del
broker con
su puerto. El usuario y el password que se necesita en el broker para su
conexion. El
identificador del cliente (el cual hemos generados de forma aleatoria). Y
por ultimo
el keepalive.
*/
client = mqtt.connect("mqtt://127.0.0.1:1883", {username: "admin",
password: "123456jaa", clientId: client_ID, keepalive: 5});
/*
Nos subscribimos a todos los topics necesarios.
*/
Red de sensores para monitorización inteligente de vivienda 109

client.on('connect', function () {
client.subscribe("pfc/lectura");
client.subscribe("pfc/rfid");
client.subscribe("pfc/rfidFB");
client.subscribe("pfc/macFB");
client.subscribe("pfc/alarma");
});
/*
Por cada mensaje que llege lo vamos a ir parseando
*/
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString());
/*
Implementamos una variable que servira para registrar la conexion mySQL, en
principio no
vamos a estar constantemente conectado, tan solo cuando una trama
*/

var connection = mysql.createConnection({


host: 'localhost',
user: 'root',
password: 'password',
database: 'PFC',
port: 3306
});

/*
Realizamos la conexion a la base de datos, es necesario tener el paquete
mysql instalado y requerido para ello. Si la conexion se puede realizar se
ejecuta
el parseado de los elementos, en caso contrario, dara un mensaje de error
*/
connection.connect(function(error){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de conexion");
throw error;
}else{
/*
Se comprueba que si se ha recibido una lectura o una identificación
*/
var array = topic.split('/');
console.log(array[1]);
if(array[1] == "lectura"){
console.log("Se ha recibido una lectura");
var array2 = message.toString().split('&');
var array3 = array2[0].split('=');
if (array3[0] == "MAC"){
var MAC = array3[1];
for(i = 1 ; i < array2.length ; i++){
var array3 = array2[i].split('=');
var query = connection.query('INSERT INTO Sensores(mac, sensor, valor)
VALUES(?, ?, ?)' , [ MAC , array3[0] , array3[1] ], function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
110 Anexos

console.log("ok");
}
});
if(array3[0] == 'PIR' && array3[1] == '1'){
console.log(array3[1]);
var query = connection.query("SELECT * FROM Alarma WHERE Armado = 1",
function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de petición");
throw error;
}else{
resultado = result;
if(resultado.length > 0){
if(resultado[0].Sonando){
}else {
client.publish('pfc/alarma',"Sonar");
}
}
}
});
}
}
console.log("mac:"+MAC);
var query = connection.query("SELECT * FROM Registro WHERE mac = "+MAC,
function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de petición");
throw error;
}else{
resultado = result;
if(resultado.length > 0){
console.log(resultado.length);
}else{
client.publish('pfc/macFB',"ID:"+ MAC + '&NAME:SinAsignar');
}
}
});
}
}else if(array[1] == "rfid"){
console.log("Se ha recibido una identificacion");
var array2 = message.toString()
console.log(array2);
var query = connection.query("SELECT * FROM rfid WHERE ID = "+array2,
function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de peticion");
throw error;
}else{
resultado = result;
if(resultado.length > 0){
var estado = resultado[0].encasa;
var nombre = resultado[0].usuario;
Red de sensores para monitorización inteligente de vivienda 111

client.publish('pfc/rfidFB',"ID:"+ array2 + "&NAME:" + nombre


+"&STT:" + estado );
}else{
client.publish('pfc/rfidFB',"ID:"+ array2 + '&NAME:SinRegistrar');
}
}
});
}else if(array[1] == "rfidFB"){
var array2 = message.toString().split('&');
var array3 = array2[0].split(':');
if(array3[0]== "ID"){
var RFID_ID = array3[1];
array3 = array2[1].split(':');
if(array3[0] == 'NAME'){
var NAME_R = array3[1];
if(array3[1] == 'SinRegistrar'){
if(array2[2]){
console.log("Usuario registrado");
/*
Se ha escrito los datos en la base de datos, vamos a mandar la
confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: RFID_ID + ' ha intentado acceder a casa', // Subject line
text: RFID_ID + ' ha intentado acceder a casa, sin embargo el
usuario no está registrado en la base de datos, en caso de que el usuario
tenga permisos corríjalo en el panel de administración', // plaintext body
html: '<H3>' + RFID_ID + ' ha intentado acceder a casa</H3> <p> Sin
embargo el usuario no está registrado en la base de datos, en caso de que el
usuario tenga permisos, por favor, corríjalo en el <a
href="www.ardugeek.es/pfc">panel de administración</a></p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
}else{
var query = connection.query('INSERT INTO rfid(id, usuario, encasa)
VALUES(?, ?, ?)' , [ RFID_ID , array3[1] , '0'], function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Usuario registrado");
/*
Se ha escrito los datos en la base de datos, vamos a mandar la
confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: 'Se ha registrado un nuevo usuario con ID: ' +RFID_ID,
// Subject line
112 Anexos

text: 'Se ha registrado un nuevo usuario con ID: ' +RFID_ID + '.
Puede asignarle un nombre de usuario en el panel de administración para que
el usuario pueda registrarse en casa.', // plaintext body
html: '<H3>Se ha registrado un nuevo usuario con ID: ' + RFID_ID
+ '</H3> <p>Puede asignarle un nombre de usuario en el <a
href="www.ardugeek.es/pfc">panel de administración</a> para que el usuario
pueda registrarse en casa.</p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
}
});
}
}else{
array3 = array2[2].split(':');
if(array3[0] == 'STT'){
if(array3[1] == '0'){
var query = connection.query('UPDATE rfid SET encasa = 1 WHERE id
=' + RFID_ID, function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Usuario registrado");
/*
Se ha escrito los datos en la base de datos, vamos a mandar la
confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: NAME_R + ' se ha registrado en casa', // Subject line
text: NAME_R + ' se ha registrado en casa, si el usuario ha
salido de casa corríjalo en el panel de administración', // plaintext body
html: '<H3>' + NAME_R + ' se ha registrado en casa</H3> <p> Si
el usuario ha salido de casa, por favor, corríjalo en el <a
href="www.ardugeek.es/pfc">panel de administración</a></p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
}
});
client.publish('pfc/alarma',"OFF");
var query = connection.query('UPDATE Alarma SET Armado = 0 ,
Activado = 0 , Sonando = 0 WHERE Alarma = Alarma', function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
Red de sensores para monitorización inteligente de vivienda 113

throw error;
}else{
console.log("Alarma Desarmada y a apagada");
}
});
}else if(array3[1] == '1'){
var query = connection.query('UPDATE rfid SET encasa = 0 WHERE id
=' + RFID_ID, function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Usuario registrado");
/*
Se ha escrito los datos en la base de datos, vamos a mandar la
confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: NAME_R + ' ha salido de casa', // Subject line
text: NAME_R + ' ha salido de casa, si el usuario se ha
registrado en casa corríjalo en el panel de administración', // plaintext
body
html: '<H3>' + NAME_R + ' ha salido de casa</H3> <p> Si el
usuario e ha registrado en casa, por favor, corríjalo en el <a
href="www.ardugeek.es/pfc">panel de administración</a></p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}else{
console.log('Message sent: ' + info.response);
}
});
}
});
var query = connection.query("SELECT * FROM rfid WHERE encasa =
1", function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de petición");
throw error;
}else{
resultado = result;
if(resultado.length == 0){
client.publish('pfc/alarma',"Armar");
}
}
});
}else {
console.log(array3[1]);
}
}
}
}
}
114 Anexos

}else if(array[1] == "macFB"){


var array2 = message.toString().split('&');
var array3 = array2[0].split(':');
if(array3[0]== "ID"){
var MAC_ID = array3[1];
array3 = array2[1].split(':');
if(array3[0] == 'NAME'){
if(array3[1] == 'SinAsignar'){
var query = connection.query('INSERT INTO Registro(mac, room)
VALUES(?, ?)' , [ MAC_ID , array3[1] ], function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Dispositivo registrado");
/*
Se ha escrito los datos en la base de datos, vamos a mandar la
confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: 'Se ha registrado un nuevo dispositivo con MAC: ' +
MAC_ID, // Subject line
text: 'Se ha registrado un nuevo dispositivo con MAC: ' + MAC_ID +
'. Puede asignarle un nombre al nodo en el panel de administración para leer
los datos desde la interfaz web.', // plaintext body
html: '<H3>Se ha registrado un nuevo dispositivo con MAC: ' +
MAC_ID + '</H3> <p>Puede asignarle un nombre al nodo en el <a
href="www.ardugeek.es/pfc">panel de administración</a> para leer los datos
desde la interfaz web.</p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
}
});
}
}
}
}else if(array[1] == "alarma"){
array2 = message.toString();
if (array2 == "Armar"){
var query = connection.query('UPDATE Alarma SET Armado = 1 WHERE Alarma
= Alarma', function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Alarma Armada");
/*
Red de sensores para monitorización inteligente de vivienda 115

Se ha escrito los datos en la base de datos, vamos a mandar la


confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: 'Alarma Armada', // Subject line
text: 'Alarma Armada. Recuerde que si espera una visita sin
identificación debe desarmar la alarma en el panel de administración.', //
plaintext body
html: '<H3>Alarma armada</H3> <p>Recuerde que si espera una visita
sin identificación debe desarmar la alarma en el <a
href="www.ardugeek.es/pfc">panel de administración</a>.</p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
}
});
}else if (array2 == "Activar"){
var query = connection.query('UPDATE Alarma SET Activado = 1 WHERE
Alarma = Alarma', function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Alarma Activada");
}
});
}else if (array2 == "Sonar"){
var query = connection.query('UPDATE Alarma SET Sonando = 1 WHERE
Alarma = Alarma', function(error, result){
if(error){
/*
Al no haberse podido conectar enviara un mensaje de error
*/
console.log("error de insercion");
throw error;
}else{
console.log("Alarma Sonando");
client.publish('pfc/alarma',"ON");
/*
Se ha escrito los datos en la base de datos, vamos a mandar la
confirmación por e-mail
*/
var mailOptions = {
from: '"Casa Domotica" <j.arcenegui.pfc@gmail.com>', // sender
address
to: 'j.arcenegui@gmail.com', // list of receivers
subject: 'Ha Saltado la Alarma', // Subject line
text: 'Ha saltado la Alarma, avise de inmediato a la policía.', //
plaintext body
html: '<H3>Ha saltado la alarma</H3> <p>Avise de inmediato a la
policía</p> ' // html body
};
transporter.sendMail(mailOptions, function(error, info){
116 Anexos

if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
}
});
}
}
}
/*
Finalizada la lectura de la trama, sea correcta o erronea se desconecta de
la
base de datos.
*/
connection.end();
});
});
Red de sensores para monitorización inteligente de vivienda 117
118 Anexos

9.4 Anexo IV - Código Index.hml


<!DOCTYPE html>
<html>
<head lang="es">
<link rel="icon" type="image/png" href="mifavicon.png" />
<meta charset="utf-8" />
<title>Casa domótica</title>
<link rel="stylesheet" type="text/css" href="estilos.css">
<!--google-->
<link href='http://fonts.googleapis.com/css?family=Roboto'
rel='stylesheet' type='text/css'>
<!--jquery-->
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<!--jquery ui-->
<link rel="stylesheet"
href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<!--google chart-->
<script type="text/javascript"
src="https://www.google.com/jsapi"></script>
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<!--bootstrap-->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-
theme.min.css">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></s
cript>
<!--mi codigo-->
<script type="text/javascript" src="javascript.js"></script>
<!--carga de los datepiker de jquery UI-->
<script>
$(function() {
$( "#desde" ).datepicker();
$( "#hasta" ).datepicker();
$( "#desde" ).datepicker("option", "dateFormat", "yy-mm-dd");
$( "#hasta" ).datepicker("option", "dateFormat", "yy-mm-dd");
var f = new Date();
$('#desde').datepicker("setDate", new
Date(f.getFullYear(),f.getMonth(),f.getDate()) );
$('#hasta').datepicker("setDate", new
Date(f.getFullYear(),f.getMonth(),(f.getDate()+1)) );
//$('#desde').datepicker("setDate", new Date(2016,05,21) ); //ojo! el mes
07 es agosto (valor = mes-1!)
//$('#hasta').datepicker("setDate", new Date(2016,05,22) );
});
</script>
<!--script para mostrar la grafica (gestion de la la pagina grafica.html)-
->
<script type="text/javascript">
//var cargaPrimeraVezTimer = window.setTimeout(cargaPrimeraVez, 1000);
//funcion que carga la lista de habitaciones con sensores activos
function cargaHabitaciones(){
var url_data = "get_sensor.php";
//invocamos al php de cargar datos con AJAX.
//Cuando nos devuelva los datos los convertimos el json a array
//y pintamos el select box de habitaciones
Red de sensores para monitorización inteligente de vivienda 119

$.get(url_data, function( data ) {


var array = JSON.parse(data);
$.each(array, function (i, item) {
var o = new Option(item.room, item.mac);
$(o).html(item.room);
$('#habitacion').append(o);
});
});
}
//funcion que hace la carga por primera vez
function cargaPrimeraVez(){
cargaGrafica();
}
//funcion para pedir los datos
//primero leemos con datepiker con las fechas desde/hastar
//y el combo con la grafica a mostrar
function cargaGrafica(){
var d = $( "#desde" ).val();
d=d.replace(new RegExp("-", 'g'), '') + "000000";
var h = $( "#hasta" ).val();
h=h.replace(new RegExp("-", 'g'), '') + "000000";
var url_data =
"get_data.php?MAC="+$("#habitacion").val()+"&SENSOR="+$("#sensor").val()+"&FR
OM="+d+"&TO="+h;
//invocamos al php de cargar datos con AJAX.
//Cuando nos devuelva los datos los convertimos el json a array
//y se lo pasamos a la funcion para pintar la grafica
$.get(url_data, function( data ) {
var array = JSON.parse(data);
dibujaGrafica(array);
});
}
//funcion para dibujar la grafica
function dibujaGrafica(datos) {
var data = new google.visualization.DataTable();
data.addColumn("string", "Fecha");
data.addColumn("number", "X");
data.addRows(datos);
var options = {
height: 400,
width: 870,
legend: {
position: 'none'
},
hAxis: {
slantedText: true,
slantedTextAngle: 30,
//showTextEvery: 3
}
};
// var chart = new google.charts.Line(document.getElementById('chart'));
var chart = new
google.visualization.LineChart(document.getElementById('chart'));
chart.draw(data, options);
}
//cargamos!!
//google.load("visualization", "1.1", {packages: ["line"]});
google.charts.load('current', {packages: ['corechart', 'line']});
</script>
</head>
<body onload="cargaHabitaciones()">
<header>
<nav id="barranav">
120 Anexos

<ul>
<li><a href="#inicio">Inicio</a></li>
<li><a href="#sensores">Sensores</a></li>
<li><a href="#acercade">Acerca De</a></li>
</ul>
</nav>
</header>
<section id="inicio">
<div class="container-flow divinicio">
<div class="row">
<div class="col-sm-10 col-md-10 col-sm-offset-1 col-md-offset-1">
<div class="container-flow">
<div class="row">
<div class="subdivc col-xs-12 col-md-4">
<div id="divintrologo"></div>
<h3>Introducción</h3>
<p>SenHome es el nombre comercial del proyecto final de carrera
"Red de sensores para domótica y sistemas de alarma". Está realizado por
Javier Arcenegui Almenara y tutorizado por Antonio Luque Estepa (Dpto. de
Electrónica de la Escuela Superior de Ingenieros de la Universidad de
Sevilla).</p>
<p>Es un proyecto de domótica dirigido a personas concienciadas con
el medio ambiente y la eficiencia energética. Está formado por un conjunto de
sensores repartidos por diferentes habitaciones del hogar como son, el
dormitorio, la cocina, el baño y el salón; y una alarma antirrobo de registro
de presencia.</p>
</div>
<div class="subdivc col-xs-12 col-md-4">
<div id="divtaplogo"></div>
<h3>Funcionamiento</h3>
<p>Su objetivo es medir las principales variables relacionadas con
la eficiencia energética, como son, la humedad, la temperatura, la
luminosidad y la presencia. La utilización de este servicio es muy intuitivo
y accesible. El usuario podrá acceder a la sección de sensores donde
aparecerá una lista con la última lectura realizada, un enlace para ver las
gráficas en tiempo real y también aparecerán si existen elementos sin
etiquetar, en dicho caso se podrá acceder al panel de administrador. Al
seleccionar las gráficas se generará la del sensor que se quiera del nodo
elegido, se puede además seleccionar un rango de fechas concreto a
mostrar.</p>
</div>
<div class="subdivc col-xs-12 col-md-4">
<div id="divalarmlogo"></div>
<h3>Alarma</h3>
<p>El sistema detecta personas en su interior. Funciona mediante un
sistema de tarjetas con lector RFID, con el que se puede saber quién se
encuentra en casa y por lo tanto si hay alguien ajeno a ella. Para la
seguridad de la vivienda y por tanto de los propietarios, se les avisará por
e-mail si entra alguien en casa.</p>
<p>Además de para el uso antirrobo, este sistema es útil para saber
si los hijos, los trabajadores del hogar o cualquier persona que el
propietario desee saber están en la vivienda.</p>
<p>Si en un futuro se quisiese añadir un sensor de movimiento para
encender la luz, se podría añadir a dicho sistema.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="sensores">
Red de sensores para monitorización inteligente de vivienda 121

<div class="container-flow">
<div class="row">
<div class="col-sm-10 col-md-10 col-sm-offset-1 col-md-offset-1
titulosensor">
<h3>Sensores</h3>
<div class="container-flow">
<div id="subdivdatos" class="row">
</div>
</div>
</div>
</div>
</div>
</section>
<section id="acercade">
<div class="container-flow">
<div class="row">
<div class="col-sm-10 col-md-10 col-sm-offset-1 col-md-offset-1">
<div class="container-flow">
<div class="col-xs-12 col-md-6 acerca">
<h3>Javier Arcenegui Almenara</h3>
<p>Estudiante de Ingeniero en Telecomunicación en la Universidad de
Sevilla</p>
<p>Investigador del departamento de I+D+i en TopDigital consulting
especializado en hardware para dispositivos IoT y M2M.
<p>j.arcenegui@xxmail.com</p>
<p>+34 647 8xx xxx</p>
</div>
<div class="col-xs-12 col-md-6 acerca">
<h3>Red de sensores para domótica y sistemas de alarma</h3>
<p>Proyecto de Fin de Carrera del curso 2015-2016</p>
<p>Tutor del proyecto: Antonio Luque Estepa</p>
<p>Escuela Técnica Superior de Ingenieros</p>
<p>Escuela Superior de Ingenieros</p>
<p>Universidad de sevilla</p>
</div>

<div id="LogoESI" class="col-xs-4 col-md-4"></div>


<div id="LogoUS" class="col-xs-4 col-md-4"></div>
<div id="Logodep" class="col-xs-4 col-md-4"></div>
</div>
</div>
</div>
</div>
</section>
<footer id="pie">
<a href="http://www.esi.us.es" target="_blank" >Escuela Técnica Superior
de Ingenieros 2016</a>
</footer>
<!-- Modal -->
<div id="graficas" class="modal fade" role="dialog">
<div class="modal-dialog" style="width: 900px;">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-
dismiss="modal">&times;</button>
<h4 class="modal-title">Graficas de Sensores</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-6">
<form class="form-horizontal">
<div class="form-group">
122 Anexos

<label for="habitacion" class="col-sm-2 control-


label">Habitaci&oacute;n</label>
<div class="col-sm-8">
<select id="habitacion" name="habitacion" class="form-control">
</select>
</div>
</div>
<div class="form-group">
<label for="sensor" class="col-sm-2 control-label">Sensor</label>
<div class="col-sm-8">
<select id="sensor" class="form-control">
<option value="TEM">Temperatura</option>
<option value="HUM">Humedad</option>
<option value="LUZ">Luminosidad</option>
<option value="PIR">Presencia</option>
</select>
</div>
</div>
</form>
</div>
<div class="col-sm-6">
<form class="form-horizontal">
<div class="form-group">
<label for="desde" class="col-sm-2 control-label">Desde</label>
<div class="col-sm-8">
<input type="text" id="desde" class="form-control">
</div>
</div>
<div class="form-group">
<label for="hasta" class="col-sm-2 control-label">Hasta</label>
<div class="col-sm-8">
<input type="text" id="hasta" class="form-control">
</div>
</div>
</form>
</div>
<div class="row" style="text-align: center;">
<button class="btn btn-primary"
onclick="cargaGrafica()">Cargar</button>
</div>
</div>
<div class="row">
<div id='chart'></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Red de sensores para monitorización inteligente de vivienda 123
124 Anexos

9.5 Anexo V - Código estilos.css


body{
background: #eee;
margin: 0;
border: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
}

header{
background: #111;
padding: 0;
margin: 0;
height: 50px;
width: 100%;
z-index: 300;
}

#barranav{
padding: 0;
margin: 0;
background: #4fab2f;
height: 50px;
top:0;
width: 100%;
position: fixed;
border-bottom: solid black 1px;
z-index: 300;
}

#barranav ul{
list-style-type: none;
text-align: center;
margin-top: 12px;
}

#barranav li{
display: inline;
text-align: center;
}

#barranav a{
font-family: 'Roboto', sans-serif;
color: white;
text-decoration: none;
margin: 0 40px 0 40px;

#inicio{
background: #222;
color: white;
height: 100%;
width: 100%;
float: left;
}

.divinicio{
width: 100%;
}
Red de sensores para monitorización inteligente de vivienda 125

.subdivc{

margin-top: 100px;
margin-bottom: 180px;
text-align: center;

.subdivc p{
text-align: justify;
}

#divintrologo{
width: 100px;
height: 100px;
background-image: url(Info.png);
background-size: 100px 100px;
background-repeat: no-repeat;
margin-bottom: 20px;
left: 50%;
margin-left: -50px;
position: relative;
}

#divtaplogo{
width: 100px;
height: 100px;
background-image: url(tap.png);
background-size: 100px 100px;
background-repeat: no-repeat;
margin-bottom: 20px;
left: 50%;
margin-left: -50px;
position: relative;
}
#divalarmlogo{
width: 100px;
height: 100px;
background-image: url(alarm.png);
background-size: 100px 100px;
background-repeat: no-repeat;
margin-bottom: 20px;
left: 50%;
margin-left: -50px;
position: relative;
}
#sensores{
background:#4fab2f;.
position: relative;
color:black;
height: 100%;
width: 100%;
float: left;
}

#divsensores{
width: 100%;
}

.datos{
padding-top: 10px;
padding-bottom: 10px;
126 Anexos

padding: 10px;
text-align: center;

#subdivdatos{
text-align: center;
margin-top: 100px;
width: 100%;
height: 100%;
margin-bottom: 150px;

#sensorBano{
margin-top: 110px;
margin-left: 250px;
width: 25px;
height:25px;
background-image: url(sensor.png);
background-size: 25px 25px;
background-repeat: no-repeat;
position: relative;
}

#sensorDormitorio{
margin-top: -25px;
margin-left: 400px;
width: 25px;
height:25px;
background-image: url(sensor.png);
background-size: 25px 25px;
background-repeat: no-repeat;
position: relative;
}

#sensorSalon{
margin-top: 155px;
margin-left: 130px;
width: 25px;
height:25px;
background-image: url(sensor.png);
background-size: 25px 25px;
background-repeat: no-repeat;
position: relative;
}

.piesensor{
margin-top: 30px;
}
.titulosensor{
margin-top: 50px;
margin-left: 50px;
}

#sensorCocina{
width: 25px;
height:25px;
margin-left: 290px;
margin-top: -25px;
background-image: url(sensor.png);
background-size: 25px 25px;
Red de sensores para monitorización inteligente de vivienda 127

background-repeat: no-repeat;
position: relative;
}

#acercade{
background:#fff;
color:black;
height: 100%;
width: 100%;
float: left;
}

.acerca{
padding: 50px 50px 50px 50px;
margin-bottom: 50px;
}

#LogoUS{
width: 30%;
height: 100px;
background-image: url(LogoUS.png);
float: left;
background-repeat: no-repeat;
background-position: center;
background-size: 100px 100px;
}#Logodep{
width: 30%;
height: 100px;
background-image: url(Logodep.png);
float: left;
background-repeat: no-repeat;
background-position: center;
background-size: 100px 100px;
margin-bottom: 100px;
}
#LogoESI{
width: 30%;
height: 100px;
background-image: url(LogoESI.png);
float: left;
background-repeat: no-repeat;
background-position: center;
background-size: 100px 100px;

#pie{
background: #4fab2f;
text-align: center;
}

#pie a{
color: white;
text-decoration: underline;
font-size: 80%;
}

.piesensor a{
color: #111;
}
128 Anexos

.piesensor a:hover {
color:#333;
text-decoration: none;
}

.subdivdatos a{
color: #111;
}

.subdivdatos a:hover {
color:#333;
text-decoration: none;
}
.bodygraf{
background-color: white;
overflow: hidden;

.grafico{
position: relative;
margin-top: 3%;
height: 45%;
padding-left:3%;
width: 98%;
padding-right: 3%;
}
Red de sensores para monitorización inteligente de vivienda 129
130 Anexos

9.6 Anexo VI - Código javascript.js


$(document).ready(function init()
{
var texto = new Array;

document.getElementById("subdivdatos").innerHTML = "Cargando datos, por


favor espere";
$.get("SuperConsulta.php",function(datos, status){
texto = datos;
document.getElementById("subdivdatos").innerHTML = texto;
});
setInterval(function (){
$.get("SuperConsulta.php",function(datos, status){
texto = datos;
document.getElementById("subdivdatos").innerHTML = texto;
});
return false;
}, 10000);
});
Red de sensores para monitorización inteligente de vivienda 131
132 Anexos

9.7 Anexo VII - Código SuperConsulta.php


<?php
header("Access-Control-Allow-Origin: *");
/***************************************************************************
****************************************
Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa

*****************************************************************************
**************************************/

$conexion = mysqli_connect('127.0.0.1','root' ,'password','PFC');


echo '<br>';
$Nuevos = 0;
if($conexion ==false){
echo('Error al conectar con la base de datos');
}else{

$sql = "SELECT * FROM `Registro`";


$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}

while ($fila = mysqli_fetch_array($consulta)){


if(strnatcmp ( $fila['room'] , 'SinAsignar') != 0){
echo '<div class="col-sm-6 col-md-3 col-lg-3 datos">
<b>'.$fila['room'].'</b><br><br>';
$sql2 = "SELECT * FROM `Sensores` WHERE mac = '".$fila['mac']."' ORDER
BY `id` DESC LIMIT 4 ";
$consulta2 = mysqli_query($conexion,$sql2);
if (!$consulta2) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}

while ($fila2 = mysqli_fetch_array($consulta2)){


echo $fila2['sensor'].' : '.$fila2['valor'].' en
'.$fila2['fecha'].'<br>';
}
echo '</div>';
}else{
$Nuevos++;
}

}
echo'<div class="col-lg-12 piesensor"> <p>';
$sql = "SELECT * FROM `rfid` WHERE encasa=1";
$consulta = mysqli_query($conexion,$sql);
$auxiliar = 1;
Red de sensores para monitorización inteligente de vivienda 133

while ($fila = mysqli_fetch_array($consulta)){


if(!$auxiliar){
echo ", ";
}
$auxiliar = 0;
echo $fila['usuario'];
}
if($auxiliar){
echo "No hay personas registradas en casa.</p>";
}else{
echo " estan registrados en casa.</p>";
}
echo '<br><br><p>';
if($Nuevos>0){
echo 'Hay '.$Nuevos.' dispositivos sin asignar. ';
}

$sql = "SELECT * FROM `rfid` WHERE usuario='SinRegistrar'";


$consulta = mysqli_query($conexion,$sql);
$auxiliar = 0;
while ($fila = mysqli_fetch_array($consulta)){
$auxiliar++;
}
if($auxiliar>0){
echo 'Hay '.$auxiliar.' usuarios sin registrar. ';
}
if($auxiliar>0||$Nuevos>0){
echo '</p><p>Acceda al <a href="Setup.html">Panel de
Administracion</a>.</p>';
}
echo '<div class="row" style="text-align: center;">
<button type="button" class="btn btn-default" data-toggle="modal" data-
target="#graficas" onClick="cargaPrimeraVez()">Ver graficas</button>
</div>';

echo '</div>';
}

mysqli_close($conexion);

?>
134 Anexos

9.8 Anexo VIII - Código get_sensor.php


<?php
header("Access-Control-Allow-Origin: *");
/***************************************************************************
****************************************
Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa

*****************************************************************************
**************************************/

//$conexion = mysqli_connect('10.6.64.25','u3227504_pfc'
,'B8Iov*c<;z','db3227504_sense');
$conexion = mysqli_connect('127.0.0.1','root' ,'password','PFC');

if($conexion ==false){
echo('Error al conectar con la base de datos');
}else{

$sql = "SELECT * FROM `Registro` WHERE room<>'SinAsignar'";


$consulta = mysqli_query($conexion,$sql);
$array= array();
while ($fila = mysqli_fetch_array($consulta)){
$dato = array(
"mac"=>$fila['mac'],
"room"=>$fila['room']
);
array_push($array, $dato);
}
echo json_encode($array);

mysqli_close($conexion);

?>
Red de sensores para monitorización inteligente de vivienda 135
136 Anexos

9.9 Anexo IX - Código get_data.php


<?php
header("Access-Control-Allow-Origin: *");
/***************************************************************************
****************************************
Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa

*****************************************************************************
**************************************/

$conexion = mysqli_connect('127.0.0.1','root' ,'password','PFC');


//$conexion = mysqli_connect('10.6.64.25','u3227504_pfc'
,'B8Iov*c<;z','db3227504_sense');

if($conexion ==false){
echo('Error al conectar con la base de datos');
}else{
$MAC = $_GET['MAC'];
$SENSOR = $_GET['SENSOR'];
$FROM = $_GET['FROM'];
$TO = $_GET['TO'];

$sql = "SELECT * FROM `Sensores` WHERE mac = '".$MAC."' AND sensor =


'".$SENSOR."' AND fecha > ".$FROM." AND fecha < ".$TO." ORDER BY `id`";
$consulta = mysqli_query($conexion,$sql);
$array= array();
while ($fila = mysqli_fetch_array($consulta)){
$dato = array();
array_push($dato, $fila['fecha']);
array_push($dato, (int)$fila['valor']);

array_push($array, $dato);
}
echo json_encode($array);

mysqli_close($conexion);

?>
Red de sensores para monitorización inteligente de vivienda 137
138 Anexos

9.10 Anexo X - Código setup.html


<!DOCTYPE html>
<html>
<head lang="es">
<meta charset="utf-8" />
<title>Panel de Administración</title>
<link rel="icon" type="image/png" href="mifavicon.png" />
<link href='http://fonts.googleapis.com/css?family=Roboto'
rel='stylesheet' type='text/css'>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></s
cript>
<link rel="stylesheet" type="text/css" href="estilosAdmin.css">
</head>

<body>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-sm-6 col-md-4 col-xs-offset-2 col-sm-offset-3
col-md-offset-4 login">
<div class="container-flow divinicio">
<div class="row">
<div class="tittle_Admin">
</div>
</div>
</div>
<div class="container-flow">
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<form method="post" action="admin.php">
<div class="container-flow recuadroAdmin">
<div class="row">
<div class="col-xs-4">
<label for="user">Usuario : </label>
</div>
<div class="col-xs-8">
<input type="text" name="user" id="user"
class="rellenaAdmin"></input>
</div>
</div>
</div>
<div class="container-flow recuadroAdmin">
<div class="row">
<div class="col-xs-4">
<label for="password">Contraseña : </label>
</div>
<div class="col-xs-8">
<input type="password" name="password" id="password"
class="rellenaAdmin"></input>
</div>
</div>
</div>
<div class="botonAdmin">
<input type="submit" value="Acceder"></input>
</div>
</form>
</div>
</div>
</div>
Red de sensores para monitorización inteligente de vivienda 139

</div>
</div>
</div>
</body>
</html>
140 Anexos

9.11 Anexo XI - Código estilosAdmin.css


body{
background: #222;
margin: 0;
border: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
}

.login{
background: #4fab2f;
margin-top: 150px;
border-radius: 20px 20px 20px 20px;
padding-top: 20px;
}

.admin{
background: #4fab2f;
margin-top: 10px;
border-radius: 20px 20px 20px 20px;
padding-top: 20px;
}

.tittle_Admin h1{
text-align: left;
font-weight: bold;
}

.tittle_Admin h5{
font-weight: bold;
text-align: right;
margin-top: -10px;
}

.tittle_Admin{
background-image: url("logoPanel.jpg");
background-size: 380px 108px;
background-repeat: no-repeat;
background-position: center;
width: 100%;
margin-bottom: 30px;
height: 108px;
}
.tittle_Admin2 h1{
text-align: left;
font-weight: bold;
}

.tittle_Admin2 h5{
font-weight: bold;
text-align: right;
margin-top: -10px;
}

.tittle_Admin2{
max-width: 380px;
margin-bottom: 30px;
float: center;
}
Red de sensores para monitorización inteligente de vivienda 141

.recuadroAdmin{
margin-bottom: 20px;
}

.rellenaAdmin{
width: 100%;
border: 0;
box-shadow: inset 1px 2px 0px 0px #555 ;
background-color: white;
text-align: center;
font-weight: bold;
padding-top: 5px;
margin-top: -5px;
}

.NOrellena{
width: 100%;
border: 0;
box-shadow: inset 0px 0px 0px 0px #4fab2f ;
background-color: #4fab2f;
text-align: center;
font-weight: bold;
padding-top: 5px;
margin-top: -5px;
}

.botonAdmin{
float: right;
margin-top: 10px;
margin-right: -10px;
margin-bottom: 30px;
}

.botonAdmin input{
background-color: white;
border-radius: 5px 5px 5px 5px;
padding: 7px;
padding-left: 20px;
padding-right: 20px;
font-weight: bold;
}

.botonAtualizar{
margin-top: -8px;
}

.botonAtualizar input{
background-color: white;
border-radius: 5px 5px 5px 5px;
padding: 7px;
padding-left: 20px;
padding-right: 20px;
font-weight: bold;
}

.sensores h4{
text-align: center;
font-weight: bold;
margin-top: 0px;
margin-bottom: 20px;
}
.sensores p{
142 Anexos

text-align: center;
}

.leyenda{
text-align: center;
font-weight: bold;
}

.formulario{

padding-top: 50px;
}
.nota{
padding-top: 20px;
}
Red de sensores para monitorización inteligente de vivienda 143
144 Anexos

9.12 Anexo XII - Código admin.php


<?php
header("Access-Control-Allow-Origin: *");
/***************************************************************************
****************************************
Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa

*****************************************************************************
**************************************/
session_start();

//$conexion = mysqli_connect('46.37.71.48','root' ,'password','PFC');


$conexion = mysqli_connect('127.0.0.1','root' ,'password','PFC');

$usuario = $_POST['user'];
$contrasena = $_POST['password'];

if($conexion ==false){
echo('Error al conectar con la base de datos');
}else{

//Realizamos la consulta
$query = "SELECT * FROM users WHERE usuario = '$usuario' AND contrasena =
'$contrasena'";

//Lanzamos la consulta
$resultado = $conexion->query($query);

//Comprobamos el resultado
if(mysqli_num_rows($resultado) > 0){
//login correcto

$sql = "SELECT * FROM `Registro`";


$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}
echo '<!DOCTYPE html>
<html>
<head lang="es">
<meta charset="utf-8" />
<title>Panel de Administración</title>
<link rel="icon" type="image/png" href="mifavicon.png" />
<link href="http://fonts.googleapis.com/css?family=Roboto"
rel="stylesheet" type="text/css">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></s
cript>
<link rel="stylesheet" type="text/css" href="estilosAdmin.css">
Red de sensores para monitorización inteligente de vivienda 145

</head>

<body>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin">
<div class="container-flow divinicio">
<div class="row">
<div class="tittle_Admin">
</div>
</div>
</div>
</div>
</div>
</div>

<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Nodos de sensores</h4>
<div class="container-flow">
<div class="row">
<div class="col-sm-3 col-sm-offset-1 leyenda">
<p>MAC</p>
</div>
<div class="col-sm-3 leyenda">
<p>HABITACIÓN</p>
</div>
<div class="col-sm-1 leyenda">
<p>BORRAR</p>
</div>
<div class="col-sm-3 leyenda">
<p>ACTUALIZAR</p>
</div>';
$indice = 0;
while ($fila = mysqli_fetch_array($consulta)){
echo '<div class="formulario">
<form method="post" action="mRegistro.php">
<div class="col-sm-3 col-sm-offset-1 leyenda">
<input for="mac" id="mac" name="mac" class="NOrellena"
value="'.$fila['mac'].'" readonly="readonly"></input>
</div>
<div class="col-sm-3 leyenda">
<input type="text" name="room" id="room"
class="rellenaAdmin" value="'.$fila['room'].'"></input>
</div>
<div class="col-sm-1 leyenda">
<input type="checkbox" name="borrar"></input>
</div>
<div class="col-sm-3 leyenda">
<div class="botonAtualizar">
<input type="submit" name="registro"
value="Actualizar"></input>
</div>
</div>
</form>
</div>'
;
}
$sql = "SELECT * FROM `rfid`";
$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
146 Anexos

$message = 'Invalid query: ' . mysql_error() . " ";


$message .= 'Whole query: ' . $sql;
die($message);
}
echo '<div class="formulario">
</div>
<div class="formulario">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Usuarios RFID</h4>
<div class="container-flow">
<div class="row">
<div class="col-xs-3 leyenda">
<p>ID</p>
</div>
<div class="col-xs-3 leyenda">
<p>INQUILINO</p>
</div>
<div class="col-xs-1 leyenda">
<p>CASA</p>
</div>
<div class="col-xs-1 leyenda">
<p>BORRAR</p>
</div>
<div class="col-xs-4 leyenda">
<p>ACTUALIZAR</p>
</div>';
$indice = 0;
while ($fila = mysqli_fetch_array($consulta)){
echo '<div class="formulario">
<form method="post" action="mRegistro.php">
<div class="col-xs-3 leyenda">
<input for="mac" id="id" name="id" value="'.$fila['id'].'"
class="NOrellena" readonly="readonly"></input>
</div>
<div class="col-xs-3 leyenda">
<input type="text" name="usuario" id="usuario"
value='.$fila['usuario'].' class="rellenaAdmin"></input>
</div>
<div class="col-xs-1 leyenda">';
if($fila['encasa']){
echo '<input type="checkbox" name="encasa" checked></imput>';
}else{
echo '<input type="checkbox" name="encasa"></imput>';
}
echo '</div>
<div class="col-xs-1 leyenda">
<input type="checkbox" name="borrar"></imput>
</div>
<div class="col-xs-4 leyenda">
<div class="botonAtualizar">
<input type="submit" name="rfid"
value="Actualizar"></input>
</div>
</div>
Red de sensores para monitorización inteligente de vivienda 147

</form>
</div>';
}
echo '<div class="formulario">
</div>
<div class="formulario">
</div>
</div>
</div>
</div>
</div>';
$sql = "SELECT * FROM `Alarma`";
$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}

echo '<div class="container-flow">


<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Gestión de la alarma</h4>
<div class="container-flow">
<div class="row">
<form method="post" action="mRegistro.php">';
$fila = mysqli_fetch_array($consulta);
if($fila['Armado']){
echo '<div class="col-xs-3 col-xs-offset-2 leyenda">
<p>DESARMAR ALARMA</p>
</div>
<div class="col-xs-2 leyenda">
<input type="checkbox" name="desarmar"></imput>
</div>
<div class="col-xs-3 leyenda">
<div class="botonAtualizar">
<input type="submit" name="Alarma"
value="Actualizar"></input>
</div>
</div>';
}else{
echo '<div class="col-xs-3 col-xs-offset-2 leyenda">
<p>ARMAR ALARMA</p>
</div>
<div class="col-xs-2 leyenda">
<input type="checkbox" name="armar"></imput>
</div>
<div class="col-xs-3 leyenda">
<div class="botonAtualizar">
<input type="submit" name="Alarma"
value="Actualizar"></input>
</div>
</div>';
}

echo '</form>
</div>
</div>
<br>
<p>Nota: Desarmar la alarma también desactiva la sirena si esta
estuviera sonando</p>
</div>
</div>
148 Anexos

</div>
</body>
</html>';
}else{
//Usuario o Contrasena incorrecto
echo '<!DOCTYPE html>
<html>
<head lang="es">
<meta charset="utf-8" />
<title>Panel de Administración</title>
<link rel="icon" type="image/png" href="mifavicon.png" />
<link href="http://fonts.googleapis.com/css?family=Roboto"
rel="stylesheet" type="text/css">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></s
cript>
<link rel="stylesheet" type="text/css" href="estilosAdmin.css">
</head>

<body>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-sm-6 col-md-4 col-xs-offset-2 col-sm-offset-3
col-md-offset-4 login">
<div class="container-flow divinicio">
<div class="row">
<div class="tittle_Admin">
</div>
</div>
</div>
<div class="container-flow">
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<form method="post" action="admin.php">
<div class="container-flow recuadroAdmin">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Usuario o contraseña erroneo.</h4>
</div>
<div class="col-xs-4">
<label for="user">Usuario : </label>
</div>
<div class="col-xs-8">
<input type="text" name="user" id="user"
class="rellenaAdmin"></input>
</div>
</div>
</div>
<div class="container-flow recuadroAdmin">
<div class="row">
<div class="col-xs-4">
<label for="password">Contraseña : </label>
</div>
<div class="col-xs-8">
<input type="password" name="password" id="password"
class="rellenaAdmin"></input>
</div>
</div>
</div>
<div class="botonAdmin">
Red de sensores para monitorización inteligente de vivienda 149

<input type="submit" value="Acceder"></input>


</div>
</form>
</div>
</div>
</div>

</div>
</div>
</div>
</body>
</html>';
}
}

mysqli_close($conexion);

?>
150 Anexos

9.13 Anexo XIII - Código mRegistro.php


<?php
header("Access-Control-Allow-Origin: *");
/*

Red de sensores para monitorización inteligente de vivienda.

Proyecto fin de carrera


Ingeniero de Telecomunicación, Plan del 98
Universidad de Sevilla

Alumno: Javier Arcenegui Almenara


Tutor: Antonio Luque Estepa

*/

//$conexion = mysqli_connect('46.37.71.48','root' ,'password','PFC');


$conexion = mysqli_connect('127.0.0.1','root' ,'password','PFC');

if($conexion ==false){

echo('Error al conectar con la base de datos');

}else{
if($_POST['registro'] == 'Actualizar') {
$dispositivo = $_POST['mac'];
$room = $_POST['room'];
if($dispositivo){
if(isset($_POST['borrar'])){
$sql = "DELETE FROM Registro WHERE mac = '".$dispositivo."' ";
$consulta = mysqli_query($conexion, $sql);
$escribe = 1;
}else{
if(!($_POST['room']))
{
$room='SinAsignar';
}
$sql = "UPDATE Registro SET room = '".$room."' WHERE mac =
'".$dispositivo."' ";
$consulta = mysqli_query($conexion, $sql);
}
$escribe = 1;
}else{
$escribe = 0;
}
}else if($_POST['rfid'] == 'Actualizar') {
$id= $_POST['id'];
$usuario = $_POST['usuario'];
if(isset($_POST['encasa'])){
$encasa = '1';
}else{
$encasa = '0';
}
if($id){
if(isset($_POST['borrar'])){
$sql = "DELETE FROM rfid WHERE id = '".$id."' ";
$consulta = mysqli_query($conexion, $sql);
$escribe = 1;
}else{
if(!($_POST['usuario']))
Red de sensores para monitorización inteligente de vivienda 151

{
$usuario='SinRegistrar';
}
$sql = "UPDATE rfid SET usuario = '".$usuario."' , encasa =".$encasa."
WHERE id = '".$id."' ";
$consulta = mysqli_query($conexion, $sql);
$escribe = 1;
}
}else{
$escribe = 0;
}
}else if($_POST['Alarma'] == 'Actualizar') {
if(isset($_POST['armar'])){
$sql = "UPDATE Alarma SET Armado = 1 WHERE Alarma = Alarma";
$consulta = mysqli_query($conexion, $sql);
$escribe = 1;
}else if(isset($_POST['desarmar'])){
$sql = "UPDATE Alarma SET Armado = 0 , Activado = 0 , Sonando = 0 WHERE
Alarma = Alarma";
$consulta = mysqli_query($conexion, $sql);
$escribe = 1;
}else{
$escribe = 1;
}
}else{
$escribe = 0;
}
//echo $escribe;

//Comprobamos el resultado
if($escribe){
//login correcto

$sql = "SELECT * FROM `Registro`";


$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}
echo '<!DOCTYPE html>
<html>
<head lang="es">
<meta charset="utf-8" />
<title>Panel de Administración</title>
<link rel="icon" type="image/png" href="mifavicon.png" />
<link href="http://fonts.googleapis.com/css?family=Roboto"
rel="stylesheet" type="text/css">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></s
cript>
<link rel="stylesheet" type="text/css" href="estilosAdmin.css">
</head>

<body>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin">
<div class="container-flow divinicio">
<div class="row">
<div class="tittle_Admin">
152 Anexos

</div>
</div>
</div>
</div>
</div>
</div>

<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Nodos de sensores</h4>
<div class="container-flow">
<div class="row">
<div class="col-sm-3 col-sm-offset-1 leyenda">
<p>MAC</p>
</div>
<div class="col-sm-3 leyenda">
<p>HABITACIÓN</p>
</div>
<div class="col-sm-1 leyenda">
<p>BORRAR</p>
</div>
<div class="col-sm-3 leyenda">
<p>ACTUALIZAR</p>
</div>';
$indice = 0;
while ($fila = mysqli_fetch_array($consulta)){
echo '<div class="formulario">
<form method="post" action="mRegistro.php">
<div class="col-sm-3 col-sm-offset-1 leyenda">
<input for="mac" id="mac" name="mac" class="NOrellena"
value="'.$fila['mac'].'" readonly="readonly"></input>
</div>
<div class="col-sm-3 leyenda">
<input type="text" name="room" id="room"
class="rellenaAdmin" value="'.$fila['room'].'"></input>
</div>
<div class="col-sm-1 leyenda">
<input type="checkbox" name="borrar"></input>
</div>
<div class="col-sm-3 leyenda">
<div class="botonAtualizar">
<input type="submit" name="registro"
value="Actualizar"></input>
</div>
</div>
</form>
</div>'
;
}
$sql = "SELECT * FROM `rfid`";
$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}
echo '<div class="formulario">
</div>
<div class="formulario">
</div>
Red de sensores para monitorización inteligente de vivienda 153

</div>
</div>
</div>
</div>
</div>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Usuarios RFID</h4>
<div class="container-flow">
<div class="row">
<div class="col-xs-3 leyenda">
<p>ID</p>
</div>
<div class="col-xs-3 leyenda">
<p>INQUILINO</p>
</div>
<div class="col-xs-1 leyenda">
<p>CASA</p>
</div>
<div class="col-xs-1 leyenda">
<p>BORRAR</p>
</div>
<div class="col-xs-4 leyenda">
<p>ACTUALIZAR</p>
</div>';
$indice = 0;
while ($fila = mysqli_fetch_array($consulta)){
echo '<div class="formulario">
<form method="post" action="mRegistro.php">
<div class="col-xs-3 leyenda">
<input for="mac" id="id" name="id" value="'.$fila['id'].'"
class="NOrellena" readonly="readonly"></input>
</div>
<div class="col-xs-3 leyenda">
<input type="text" name="usuario" id="usuario"
value='.$fila['usuario'].' class="rellenaAdmin"></input>
</div>
<div class="col-xs-1 leyenda">';
if($fila['encasa']){
echo '<input type="checkbox" name="encasa" checked></imput>';
}else{
echo '<input type="checkbox" name="encasa"></imput>';
}
echo '</div>
<div class="col-xs-1 leyenda">
<input type="checkbox" name="borrar"></imput>
</div>
<div class="col-xs-4 leyenda">
<div class="botonAtualizar">
<input type="submit" name="rfid"
value="Actualizar"></input>
</div>
</div>
</form>
</div>';
}
echo '<div class="formulario">
</div>
<div class="formulario">
</div>
</div>
</div>
154 Anexos

</div>
</div>';
$sql = "SELECT * FROM `Alarma`";
$consulta = mysqli_query($conexion,$sql);
if (!$consulta) {
$message = 'Invalid query: ' . mysql_error() . " ";
$message .= 'Whole query: ' . $sql;
die($message);
}

echo '<div class="container-flow">


<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Gestión de la alarma</h4>
<div class="container-flow">
<div class="row">
<form method="post" action="mRegistro.php">';
$fila = mysqli_fetch_array($consulta);
if($fila['Armado']){
echo '<div class="col-xs-3 col-xs-offset-2 leyenda">
<p>DESARMAR ALARMA</p>
</div>
<div class="col-xs-2 leyenda">
<input type="checkbox" name="desarmar"></imput>
</div>
<div class="col-xs-3 leyenda">
<div class="botonAtualizar">
<input type="submit" name="Alarma"
value="Actualizar"></input>
</div>
</div>';
}else{
echo '<div class="col-xs-3 col-xs-offset-2 leyenda">
<p>ARMAR ALARMA</p>
</div>
<div class="col-xs-2 leyenda">
<input type="checkbox" name="armar"></imput>
</div>
<div class="col-xs-3 leyenda">
<div class="botonAtualizar">
<input type="submit" name="Alarma"
value="Actualizar"></input>
</div>
</div>';
}

echo '</form>
</div>
</div>
<br>
<p>Nota: Desarmar la alarma también desactiva la sirena si esta
estuviera sonando</p>
</div>
</div>
</div>
</body>
</html>';
}else{
//Usuario o Contrasena incorrecto
echo '<!DOCTYPE html>
<html>
<head lang="es">
Red de sensores para monitorización inteligente de vivienda 155

<meta charset="utf-8" />


<title>Panel de Administración</title>
<link rel="icon" type="image/png" href="mifavicon.png" />
<link href="http://fonts.googleapis.com/css?family=Roboto"
rel="stylesheet" type="text/css">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></s
cript>
<link rel="stylesheet" type="text/css" href="estilosAdmin.css">
</head>

<body>
<div class="container-flow">
<div class="row">
<div class="col-xs-8 col-sm-6 col-md-4 col-xs-offset-2 col-sm-
offset-3 col-md-offset-4 login">
<div class="container-flow divinicio">
<div class="row">
<div class="tittle_Admin">
</div>
</div>
</div>
<div class="container-flow">
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<form method="post" action="admin.php">
<div class="container-flow recuadroAdmin">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 admin sensores">
<h4>Sesión caducada.</h4>
</div>
<div class="col-xs-4">
<label for="user">Usuario : </label>
</div>
<div class="col-xs-8">
<input type="text" name="user" id="user"
class="rellenaAdmin"></input>
</div>
</div>
</div>
<div class="container-flow recuadroAdmin">
<div class="row">
<div class="col-xs-4">
<label for="password">Contraseña : </label>
</div>
<div class="col-xs-8">
<input type="password" name="password" id="password"
class="rellenaAdmin"></input>
</div>
</div>
</div>
<div class="botonAdmin">
<input type="submit" value="Acceder"></input>
</div>
</form>
</div>
</div>
</div>

</div>
</div>
156 Anexos

</div>
</body>
</html>';
}
}
mysqli_close($conexion);
?>
Red de sensores para monitorización inteligente de vivienda 157
158 Anexos

9.14 Anexo XIV - Datasheet Atmel ATmega328P


Red de sensores para monitorización inteligente de vivienda 159
160 Anexos

9.15 Anexo XV - Datasheet GL55


Red de sensores para monitorización inteligente de vivienda 161
162 Anexos

9.16 Anexo XVI - Datasheet DHT11


Red de sensores para monitorización inteligente de vivienda 163

También podría gustarte