Sistema de Control de Piscina con Azure IoT: Sensores Inteligentes y Monitorización Remota
Componentes y materiales
| Componente | Cantidad | Notas |
|---|---|---|
| Sensor de temperatura digital DS18B20 sumergible | 2 | Rojo: 3-5V, Azul/Negro: GND, Amarillo/Blanco: datos |
| Relé de potencia IoT | 1 | |
| Resistencia 4.75k ohm 1/4W 5% | 2 | |
| Raspberry Pi 2 Model B | 1 | |
| Arduino UNO R3 | 1 |
Aplicaciones y servicios online
- Microsoft Azure
- Microsoft Windows 10 IoT Core
- Arduino IDE
- Microsoft Visual Studio 2015
- Azure IoT Hub Device Explorer
- Fritzing
- Power BI
Descripción del proyecto
Resumen
El objetivo de este proyecto es controlar y monitorizar una piscina usando sensores de temperatura, relés y Microsoft Azure.
La inspiración surgió de la necesidad de operar y monitorizar remotamente la piscina de nuestros hijos, una Intex redonda de 15' x 48" con unos 19.000 litros. Está conectada a un filtro de arena/bomba, un calentador de 11kW y un sistema de agua salada. La meta era monitorizar la temperatura del agua y del aire, y controlar la bomba, el calentador y el sistema de sal para mantener la piscina a buena temperatura sin sobrecargar el equipo.
El siguiente diagrama arquitectónico muestra todos los componentes principales:
La Raspberry Pi, Arduino, relé IoT y protoboard van dentro de un contenedor plástico estanco con orificios para cables y ventilación:
Sensores
La monitorización de temperatura del agua y del aire se realiza con dos sensores DS18B20 sumergibles conectados a un Arduino Uno R3 usando las librerías Dallas Controls y OneWire. Los datos de temperatura (en Celsius) se envían a la Raspberry Pi cada segundo por I2C, delimitados con "|".
temperatureData = padRight(String(poolSensor.getTempCByIndex(0)) + "|" + String(outsideSensor.getTempCByIndex(0)), I2C_BUFFER_LEN);
Los sensores DS18B20 vienen precableados: Rojo a 3V/5V, Azul/Negro a GND, Amarillo/Blanco a datos. Usé cable de timbre barato (20 AWG) para extender el sensor de agua, que va sumergido en la piscina. El segundo sensor, para temperatura ambiente, está pegado al exterior del contenedor.
Relé
La Raspberry Pi controla un relé de potencia IoT (regleta) al que van conectados la bomba y el sistema de agua salada a 110V, usando el pin de 3V de la Pi. Alternar el pin de 3V habilita/deshabilita un par de tomas de 110V en el relé IoT (apagadas por defecto).
No fue necesario conectar relé al calentador porque tiene sensor de flujo interno y se enciende/apaga según haya o no flujo de agua. Además, no encontré fácilmente un relé para 220V/60A controlable con 3V o 5V. En el futuro añadiré sensores para medir consumo eléctrico de los circuitos de 110V y 220V.
Raspberry Pi
La Raspberry Pi ejecuta Windows IoT Core Build 10.0.10586.0 y realiza:
- Ejecuta la aplicación en segundo plano IoTPoolRaspiBackgroundApp
- Actúa como gateway de campo IoT (opaco)
- Alimenta el Arduino Uno por USB (5V)
- Recibe temperaturas de piscina y aire (en °C) del Arduino por I2C
- Controla el relé IoT usando pin de 3V
- Envía nombre de piscina, temperatura agua, temperatura aire, estado del relé y timestamp (UTC) cada minuto a Azure IoT Hub
La aplicación IoTPoolRaspiBackgroundApp es una aplicación C# headless, creada con la plantilla Background Application (IoT) en Visual Studio 2015 Update 3.
Envía el siguiente payload JSON a Azure IoT Hub cada minuto vía AMQP (configurable a HTTPS o MQTT):
{ "PoolName" : "iotpool", "PoolWaterTempC" : 30, "OutsideAirTempC" : 27, "IsPoolPowerOn" : false, "SampleDateTime" : "2016-07-05T23:35:58.0882185Z" }
La Raspberry Pi se registra como dispositivo en Azure IoT Hub. La forma más fácil es usar Device Explorer, que también sirve para obtener la cadena de conexión, monitorizar mensajes D2C (Device-to-Cloud) y probar mensajes C2D (Cloud-to-Device).
Edita en StartupTask.cs para conectar a tu IoT Hub:
static string iotPoolConnString = "HostName=<iothubname>.azure-devices.net;DeviceId=iotpool;SharedAccessKey=<key>";
static string deviceName = "iotpool";
Arduino Uno
El Arduino Uno R3 está conectado a dos sensores DS18B20 usando las librerías Dallas Controls y OneWire. Se alimenta por USB (5V) desde la Raspberry Pi y envía las lecturas por I2C (pines SDA y SCL). Ver diagrama Fritzing para el esquemático.
Usa el código Two-DS18B20-I2C.ino para el Arduino.
Azure
Todos los componentes de Azure se crearon en la misma región (West US) para minimizar costes de tráfico de salida.
Azure IoT Hub
Se usó la edición gratuita: límite de 8.000 mensajes/día a 500 bytes cada uno. La app envía 1.440 mensajes/día a 158 bytes cada uno, dejando margen para mensajes C2D.
Primero registra el dispositivo en Azure IoT Hub (Device Explorer es lo más fácil). Una vez registrado, obtén la cadena de conexión con Device Explorer.
Azure Streaming Analytics
El trabajo de Azure Streaming Analytics (ASA) conecta la entrada de IoT Hub con la salida a Azure SQL Database usando esta consulta:
SELECT PoolName, PoolWaterTempC, OutsideAirTempC, IsPoolPowerOn, SampleDateTime INTO sql FROM iothub
Esta consulta escribe cada mensaje D2C JSON (1 por minuto) en una tabla llamada Pools en Azure SQL Database. Futuras mejoras podrían incluir funciones de agregación para alertas (ej. temperatura media > 35°C indica agua demasiado caliente).
Azure SQL Database
Para minimizar coste y por requisitos mínimos de rendimiento, la base de datos es S0 Standard (10 DTUs). Una sola base de datos con una tabla para almacenar todos los mensajes D2C.
Esquema:
CREATE TABLE [dbo].[Pools] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[PoolName] NVARCHAR (MAX) NULL,
[PoolWaterTempC] FLOAT (53) NOT NULL,
[OutsideAirTempC] FLOAT (53) NOT NULL,
[IsPoolPowerOn] INT NOT NULL,
[SampleDateTime] DATETIME NOT NULL,
CONSTRAINT [PK_dbo.Pools] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Azure API App
API RESTful construida con ASP.NET Web API. Los clientes deben autenticarse con API key en cabecera HTTP:
api-key : {tu API key}
La API key se define en IoTPoolAPI\Controllers\PoolControllers.cs. La app móvil y web deben usar esta key.
Métodos soportados:
Mejoras futuras: poner detrás de Azure API Management y añadir autenticación Azure Active Directory.
Azure Web App
La IoTPoolWebApp contiene una aplicación ASP.NET Web Forms para interactuar con la API.
Hay versión mobile-friendly. Edita default.aspx.cs y cambia:
private static string apiKey = "";
HttpRequestMessage requestMessage = ...."https://<yourwebsite>.azurewebsites.net/api/pool/poweroff");
HttpRequestMessage requestMessage = ...."https://<yourwebsite>.azurewebsites.net/api/pool/poweron");
HttpRequestMessage requestMessage = ...."https://<yourwebsite>.azurewebsites.net/api/pool/getlatest");
La web app se integra con Azure Active Directory (AAD) para autenticación. Todos los usuarios deben autenticarse con AAD. Registra tu web app en tu tenant AAD (ej. tenant_name.onmicrosoft.com) via Azure Portal o Visual Studio. Copia el Client ID del portal y modifica web.config:
<appSettings>
<add key="ida:ClientId" value="<AAD client ID>" />
<add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
</appSettings>
App Móvil
Escrita con Xamarin Forms. Compilada para Windows Phone y Windows 10, pero debería compilar en iOS y Android.
Edita Core.cs:
string queryString = "https://<yourwebsite>azurewebsites.net/api/pool/getlatest"
Edita DataService.cs:
private static string apiKey = "";
Edita PoolPage.xaml.cs:
private static string apiKey = "";
HttpRequestMessage requestMessage = ...."https://<yourwebsite>.azurewebsites.net/api/pool/poweroff");
HttpRequestMessage requestMessage = ...."https://<yourwebsite>.azurewebsites.net/api/pool/poweron");
Power BI
Power BI (edición gratuita) para crear y publicar un dashboard en tiempo real con datos de IoT Pool.
Proceso: descargar Power BI Desktop, conectar a Azure SQL DB (DirectQuery), crear informes con visuales, publicar .pbix en PowerBI.com, anclar al dashboard. En el futuro podría usar Power BI Embedded para integrar el dashboard en la web app. Por ahora se ve en PowerBI.com o app móvil gratuita Power BI.
Referencias
- https://developer.microsoft.com/en-us/windows/iot/win10/samples/blinky
- https://create.arduino.cc/projecthub/mmackes/pool-controller-8dfa69?ref=tag&ref_id=relays&offset=0
- https://azure.microsoft.com/en-us/documentation/articles/iot-hub-csharp-csharp-getstarted/
- https://azure.microsoft.com/en-us/documentation/articles/iot-hub-csharp-csharp-c2d/
- https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-rest-service-aspnet-api-sql-database/
- https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started/
- https://msdn.microsoft.com/en-us/library/hh975357.aspx
- https://www.arduino.cc/en/Guide/Windows
- https://playground.arduino.cc/Learning/OneWire
- https://milesburton.com/Dallas_Temperature_Control_Library
- https://learn.sparkfun.com/tutorials/i2c
Agradecimientos a Miles Burton (librería Dallas Controls) y Mike Mackes (código Arduino/I2C/DS18B20 e inspiración).
Código
Formato JSON para mensajes Device-to-Cloud (D2C)
Nota: "IsPoolPowerOn" - 0 = apagado; 1 = encendido
{ "PoolName" : "IoTPool", "PoolWaterTempC" : 30, "OutsideAirTempC" : 27, "IsPoolPowerOn" : false, "SampleDateTime" : "2016-07-05T23:35:58.0882185Z" }
Esquema tabla "Pools" en SQL Database
CREATE TABLE [dbo].[Pools] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[PoolName] NVARCHAR (MAX) NULL,
[PoolWaterTempC] FLOAT (53) NOT NULL,
[OutsideAirTempC] FLOAT (53) NOT NULL,
[IsPoolPowerOn] INT NOT NULL,
[SampleDateTime] DATETIME NOT NULL,
CONSTRAINT [PK_dbo.Pools] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Repositorio GitHub del proyecto
Todo el código fuente: https://github.com/khilscher/iotpool
Esquemáticos
Conexión Raspberry Pi - Arduino por I2C con 2 sensores DS18B20 (RaspiArduinoTwoDS18B20.fzz)
Diagrama arquitectónico general:
Proceso de manufactura
- Guía completa de diseño y construcción de piscinas enterradas y elevadas
- Registrador GPS con Análisis Espacial en Azure IoT Hub
- Monitorización IoT y IA de calidad del agua para proteger la vida acuática
- Monitor de Frecuencia Cardíaca IoT en Tiempo Real con Arduino y MAX30100
- Control Remoto IoT de Brazo Robótico Personalizado con Arduino MKR1000 y ThingSpeak
- Construye un tarro inteligente IoT con ESP8266, Arduino y sensor ultrasónico: Monitorización en tiempo real
- Seguidor Solar IoT: Gestión Inteligente de Energía con Arduino
- Crear un medidor IoT web con Arduino, Yaler e IFTTT
- Arduino lanza Portenta H7: Board IoT industrial‑grade debuta en CES
- Azure RTOS se expande en plataformas embebidas principales con nuevos kits de desarrollo
- Azure vs AWS: ¿Qué Plataforma Cloud Gana para IoT?