Smart Plant IoT
Componentes y suministros
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Aplicaciones y servicios en línea
| ||||
|
Acerca de este proyecto
Actualizado para el Concurso de Jóvenes Creadores China-EE. UU. De 2019
Introducción
La jardinería puede ser un pasatiempo divertido para algunos, pero para muchos otros es una molestia. En este artículo, estoy escribiendo una guía simple sobre cómo construir una planta de IoT inteligente que enviaría datos de sensores a Azure IoT Hub y los almacenaría en Azure SQL a través de funciones de Azure, al mismo tiempo que controla el agua de forma automática y remota para la planta.
Helium IoT Hub se conecta a Azure IoT Hub de manera fluida, en este artículo explicaremos cómo funciona todo el proceso. Dado que todo el proyecto no tiene servidor, el único código necesario para que todo el proceso funcione es solo la función Azure y el código Arduino.
Paso 1:Reúna los componentes
Estamos construyendo un producto simple usando
- Arduino UNO
- Escudo base SEEED Grove
- Átomo de helio + Elemento de helio con placa de ruptura de helio Arduino
- Una bomba
- Sensor de temperatura / humedad, sensor de humedad, sensor de luz ultravioleta
- Pantalla OLED Grove
Paso 2:configura Arduino con helio y sensores
En este artículo nos centraremos en usar Arduino como nuestra aplicación, lo primero es que enviaremos datos de Helium Atom a Helium Hub. Primero tenemos que registrar nuestro Atom en Helium Network Dashboard.
Después de configurar el Atom, también tendríamos que registrar Element, ya que son el punto de acceso (para aquellos que tienen una versión celular, sería suficiente encenderlo).
Después de activar el elemento, deberíamos verlo en el punto de acceso.
A continuación, debemos conectar todo el sensor y el átomo de helio, cuando todo esté listo, debería verse algo así, un poco desordenado, pero podemos limpiarlo más tarde.
Podemos ejecutar el siguiente código para saber que el programa se está ejecutando.
#include "Arduino.h" #include "Board.h" #include "Helium.h" #include "HeliumUtil.h" #include #include "Arduino.h" #include "Wire.h" #include #include #define CHANNEL_NAME "Azure IoT App" Helio helio (&atom_serial); Canal canal (&helium); int relay =5; void setDisplayToOriginalState () {SeeedGrayOled.init (SSD1327);} void setup () {// ponga su código de configuración aquí, para que se ejecute una vez:Serial.begin (9600); pinMode (relé, SALIDA); retraso (150); / * Restablecer HP20x_dev * / TH02.begin (); retraso (100); Serial.println ("TH02_dev está disponible. \ N"); DBG_PRINTLN (F ("Inicio")); // Comience la comunicación con Helium Atom // La velocidad en baudios difiere según la placa admitida // y está configurada en Board.h helium.begin (HELIUM_BAUD_RATE); // Conecte el átomo a la red de helio helium_connect (&helium); // Comienza a comunicarte con el canal. Esto solo debería tener que // hacerse una vez. Las funciones de HeliumUtil agregan una lógica de reintento simple // para volver a crear un canal si se desconecta. channel_create (&canal, CHANNEL_NAME); Wire.begin ();} void loop () {// Contaminación acústica int humedad =0; para (int i =0; i <32; i ++) {humedad + =analogRead (A0); } int uvlight =0; para (int i =0; i <32; i ++) {uvlight + =analogRead (A1); } temperamento flotante =TH02.ReadTemperature (); humedad de flotación =TH02.ReadHumidity (); String dataString ="Humedad =" + String (humedad) + "&UVLight =" + String (luz ultravioleta) + "&Temperature =" + String (temperamento) + "&Humedad =" + String (humedad); char data [dataString.length ()]; dataString.toCharArray (datos, dataString.length ()); channel_send (&canal, CHANNEL_NAME, datos, strlen (datos)); Serial.println (datos); setDisplayToOriginalState (); SeeedGrayOled.clearDisplay (); // Pantalla clara. SeeedGrayOled.setNormalDisplay (); // Establecer el modo de visualización normal SeeedGrayOled.setVerticalMode (); // Establecer en modo vertical para mostrar texto SeeedGrayOled.setTextXY (0, 0); // Coloca el cursor en la línea 0, columna 0 String weturestring ="Humedad:" + String (humedad); char moibuffer [wettring.length ()]; Weturestring.toCharArray (moibuffer, wetString.length ()); SeeedGrayOled.putString (moibuffer); SeeedGrayOled.setTextXY (2, 0); String uvstring ="UVLight:" + String (uvlight); char uvbuffer [uvstring.length ()]; uvstring.toCharArray (uvbuffer, uvstring.length ()); SeeedGrayOled.putString (uvbuffer); SeeedGrayOled.setTextXY (4, 0); Cadena de temperatura cadena =Cadena (temperamento) + "C"; char tempbuffer [TemperatureString.length ()]; TemperatureString.toCharArray (tempbuffer, TemperatureString.length ()); SeeedGrayOled.putString (tempbuffer); SeeedGrayOled.setTextXY (6, 0); String humidstring ="Húmedo:" + String (humedad); char humidbuffer [temperaturetring.length ()]; humidstring.toCharArray (humidbuffer, humidstring.length ()); SeeedGrayOled.putString (búfer de humedad); si (humedad <100) {digitalWrite (relé, ALTA); retraso (5000); digitalWrite (relé, BAJO); } retraso (60000);}
La bomba de agua requiere 12 V, mientras que el Arduino normal solo produciría 5 V como máximo, por lo que para que la cerradura funcione, podemos acceder a la fuente de alimentación soldando dos cables en la fuente de alimentación como se muestra en la imagen de abajo. Usaremos cable rojo como 12V y cable negro como tierra.
El relé actuará como un control de cuándo se bombeará el agua.
Paso 3:configurar Helium Hub y Azure IoT Hub
Primero creamos IoT Hub en todos los servicios, sería prudente mover IoT Hub a favorito para que sea mucho más fácil acceder a él. Podemos usar el nivel estándar ya que el crédito de prueba de prueba gratuita de $ 200 puede cubrirlo. También puede optar por utilizar la capa gratuita.
Después de seleccionar el nombre, puede pasar a Tamaño y escala.
Una vez creado, debemos ir a Políticas de acceso compartido-> Entrada RegistryReadWrite-> Cadena de conexión - Clave principal , también asegúrese de que la lectura del registro y la escritura del registro estén marcadas, aunque deberían ser las predeterminadas
Podemos crear nuestro primer dispositivo de prototipo para probar la conexión
Después de obtener esa cadena de conexión principal, vaya a Helium Dashboard y cree una conexión de helio, después de pegar la cadena de conexión en el campo de conexión, todo lo demás debería completarse automáticamente.
Después de configurar esto, podríamos hacer que todas las cadenas MQTT se generen automáticamente en Helium Hub. Se puede acceder fácilmente a esto a través del canal.
Dado que Azure requiere que el dispositivo publique y se suscriba a un tema fijo de MQTT, esto permitirá que Helium Atom lo haga, además de permitir que IoT Hub envíe mensajes a Helium Atom. Podemos hacer lo siguiente para probar el envío a Azure.
clon de git https://github.com/helium/helium-cli.gitcd helium-climake./helium -p / dev /
Eso comprobará si Helium está instalado correctamente
./helium -p / dev / serial0 channel crear "Azure IoT App" ./ helium -p / dev / serial0 channel enviar 1 "Hello Azure"
Esto enviará información desde Atom a Azure directamente, deberíamos verificarlo tanto en Helium Dashboard como en Azure IoT Hub Overview
Y en Azure IoT Hub a continuación deberíamos ver el mismo resultado
El dispositivo se autentica a través de X509 y la plataforma Helium lo maneja todo. Haciéndolo simple y limpio.
Paso 5:configurar la base de datos SQL de Azure
A continuación, debemos poder almacenar los datos que provienen del dispositivo IoT. Hay una gran guía sobre esto escrita en detalle en https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/01/23/working-with-azure-iot-data-in-azure-sql-database/ En En este artículo nos centraremos en la integración rápida de cómo sucede eso. Primero vamos a las bases de datos SQL para crear una base de datos como la imagen a continuación, podemos seleccionar el Nivel Básico ya que solo estamos iniciando la aplicación, el crédito de prueba gratuito debería poder cubrirlo. Esta es la opción más barata . para la creación de prototipos, a medida que escala, es posible que desee cambiarse a Azure Cosmos en el futuro, ya que el mínimo en Cosmos es de $ 25.
Luego, podemos usar el editor de consultas para crear la siguiente tabla; para empezar, solo vamos a usar la estructura de datos simple de Smart Plant IoT para comenzar
CREATE TABLE SmartPlant (id bigint IDENTITY (1,1) NOT NULL, Temperature int NOT NULL, Humidity int NOT NULL, Moisture int NOT NULL, UVLight int NOT NULL, DateCreated datetime default CURRENT_TIMESTAMP)
Ahora que tenemos una tabla para almacenar los datos, necesitamos conectar esto a un eventhub para que los datos se puedan almacenar. Vaya a Connection Strings y tome la cadena de conexión para el siguiente paso.
Paso 4:Cree la aplicación de función de Azure
Para conectarnos a la función usaremos Event Hub. Primero necesitamos crear una aplicación de función de Azure, que permita una estructura sin servidor, lo cual es excelente para las aplicaciones de IoT, ya que ya no tenemos que mantener. Para comenzar, primero debemos crear una aplicación de función en compute.
Podemos crear una función en esta configuración
Solo tómate un par de minutos y lo tendremos debajo de nuestras notificaciones.
Aplicación de función implementada
Ahora que tenemos funciones, a continuación, crearemos una función en el disparador de IoT Hub (Event Hub) para que podamos ejecutar el centro de eventos. Vaya a función-> características de la plataforma-> Configuración de la aplicación
Aquí vamos a agregar la cadena de conexión que hemos creado en el paso anterior. Guárdelo después de creado
El siguiente paso es crear una función de Event Hub, para este ejemplo usaremos C #. Después de hacer clic en la nueva conexión, las cosas deberían completarse automáticamente.
Cambie la función a la siguiente, esto es para insertar datos directamente en Azure SQL Database.
usando System.Configuration; usando System.Data.SqlClient; usando System.Threading.Tasks; ejecución de tarea asíncrona estática pública (string myIoTHubMessage, TraceWriter log) {var map =myIoTHubMessage.Split ('&'). Seleccione (x => x.Split ('=')). ToDictionary (x => x [0], x => x [1]); Cadena de temperatura =mapa ["Temperatura"]; Cadena H Cadena Humedad =mapa ["Humedad"]; String UVLight =map ["UVLight"]; var str =ConfigurationManager.ConnectionStrings ["sqldb_connection"]. ConnectionString; usando (SqlConnection conn =new SqlConnection (str)) {conn.Open (); var text ="INSERT INTO dbo. SmartPlant (Temperature, using (SqlCommand cmd =new SqlCommand (text, conn)) {// Ejecuta el comando y registra las # filas afectadas.var filas =aguardar cmd.ExecuteNonQueryAsync (); log.Info ($ "{filas} filas fueron actualizados ");}} log.Info ($" La función de activación de C # IoT Hub procesó un mensaje:{myIoTHubMessage} ");}
Cuando tenga éxito, debería poder ver
En este punto, tenemos todo el envío de datos de un extremo a otro desde Helium a Azure SQL a través de Azure IoT Hub. A continuación, necesitamos recuperar los datos, que necesitamos para crear un disparador HTTP a través de la API de funciones de Azure.
Cambiaremos un par de valores, el enrutamiento para que sea / data para que podamos acceder a / api / smartplant, y el nivel de autorización sea anónimo, y el método HTTP solo para GET
En cuanto al código, podemos probarlo accediendo a la dirección
http://
Esto probaría el resultado y devolvería "hola foobar". Cuando esto termine, podemos usar el siguiente código para devolver los datos reales. A continuación, podemos usar el siguiente código para probar toda la aplicación. Esta es la consulta más simple, cuya información adicional se puede recopilar escribiendo consultas más complejas, pero para el prototipo solo nos enfocaremos en obtener un registro.
#r "System.Configuration" #r "System.Data" #r "Newtonsoft.Json" usando System; usando System.Net; usando System.Configuration; usando System.Data.SqlClient; usando System. Threading.Tasks; using System.Text; using Newtonsoft.Json; public static async Task Run (HttpRequestMessage req, TraceWriter log) {log.Info ("La función de activación HTTP C # procesó una solicitud."); Var str =ConfigurationManager .ConnectionStrings ["sqldb_connection"]. ConnectionString; using (SqlConnection conn =new SqlConnection (str)) {conn.Open (); var text ="SELECT Top 100 Temperature, Moisture, UVLight SmartPlant ret =new SmartPlant (); usando ( SqlCommand cmd =new SqlCommand (text, conn)) {SqlDataReader reader =await cmd.ExecuteReaderAsync (); try {while (reader.Read ()) {ret.Temperature =(int) reader [0]; ret.Moisture =( int) reader [1]; ret.UVLight =(int) reader [2]; ret.Humidity =(int) reader [3];}} finalmente {// Llamar siempre a Close cuando termine de leer. reader.Close (); } var json =JsonConvert.SerializeObject (ret, Form atting.Indented); return new HttpResponseMessage (HttpStatusCode.OK) {Content =new StringContent (json, Encoding.UTF8, "application / json")}; }}} public class SmartPlant {Public Float Temperature {get; colocar; } humedad pública flotante {get; colocar; } luz UVLight flotante pública {get; colocar; } público flotante Humedad {get; colocar; }}
Cuando todo esté hecho, debería producir el resultado del último registro.
Paso 5:interfaz de usuario para la salida
Ahora que todo está conectado de un extremo a otro, podemos crear una aplicación de Android simple que puede verificar el estado general de la planta. En este caso, estamos usando una aplicación de Android muy simple para monitorear los 4 sensores que hay alrededor de la planta, así como activar la bomba peristáltica para regar la planta si es necesario. Debería mostrar y actualizar información como la siguiente. Los datos deben pasar cada 60 segundos (o como quieras configurarlo)
Por otro lado, el gabinete de Arduino se puede cerrar para tener una vista mucho mejor al lado de la planta.
Podemos simular fácilmente su propio bombeo.
Extra:Integración de Alexa
Código
- Solicitud GET de la función de Azure
- Inserción de datos de funciones de Azure desde IoT Hub
- Acceso directo a la función de Azure
- código Arduino
Solicitud GET de función de Azure C #
Llamada tranquila desde la llamada / api / smartplant#r "System.Configuration" #r "System.Data" #r "Newtonsoft.Json" usando System; usando System.Net; usando System.Configuration; usando System.Data. SqlClient; using System.Threading.Tasks; using System.Text; using Newtonsoft.Json; Public static async TaskRun (HttpRequestMessage req, TraceWriter log) {log.Info ("La función de activación HTTP C # procesó una solicitud").; var str =ConfigurationManager.ConnectionStrings ["sqldb_connection"]. ConnectionString; using (SqlConnection conn =new SqlConnection (str)) {conn.Open (); var text ="SELECT Top 100 Temperature, Moisture, UVLight from dbo.IoTData Order por DateCreated DESC "; EventData ret =new EventData (); using (SqlCommand cmd =new SqlCommand (text, conn)) {SqlDataReader reader =await cmd.ExecuteReaderAsync (); try {while (reader.Read ()) {ret.Temperature =(int) lector [0]; ret.Moisture =(int) lector [1]; ret.UVLight =(int) lector [1]; }} finalmente {// Llamar siempre a Cerrar cuando termine de leer. reader.Close (); } var json =JsonConvert.SerializeObject (ret, Formatting.Indented); return new HttpResponseMessage (HttpStatusCode.OK) {Content =new StringContent (json, Encoding.UTF8, "application / json")}; }}} public class SmartPlant {Public Float Temperature {get; colocar; } humedad pública flotante {get; colocar; } luz UVLight flotante pública {get; colocar; }}
Inserción de datos de funciones de Azure desde IoT Hub C #
Insertar datos a través de la función de Azureusando System.Configuration; usando System.Data.SqlClient; usando System.Threading.Tasks; ejecución de tarea asíncrona estática pública (string myIoTHubMessage, TraceWriter log) {var map =myIoTHubMessage.Split ('&' ) .Seleccione (x => x.Split ('=')). ToDictionary (x => x [0], x => x [1]); Tipo de cadena =mapa ["Tipo"]; Cadena de confianza =mapa ["Confianza"]; log.Info (Tipo); log.Info (Confianza); var str =ConfigurationManager.ConnectionStrings ["sqldb_connection"]. ConnectionString; using (SqlConnection conn =new SqlConnection (str)) {conn.Open (); var text ="INSERT INTO dbo.IoTData (Tipo, Confianza) VALORES ('" + Tipo + "'," + Confianza + ");"; using (SqlCommand cmd =new SqlCommand (text, conn)) {// Ejecute el comando y registre las # filas afectadas. var filas =esperar cmd.ExecuteNonQueryAsync (); log.Info ($ "{filas} filas se actualizaron"); }} log.Info ($ "La función de activación de C # IoT Hub procesó un mensaje:{myIoTHubMessage}");}
Acceso directo a la función de Azure C #
insertando directamente en AzureSQL#r "System.Configuration" #r "System.Data" usando System; usando System.Configuration; usando System.Data.SqlClient; usando System.Threading.Tasks; usando System.Net; public static Async TaskEjecutar (HttpRequestMessage req, TraceWriter log) {string Temperature =req.GetQueryNameValuePairs () .FirstOrDefault (q => string.Compare (q.Key, "Temperature", true) ==0) .Value; string Moisture =req.GetQueryNameValuePairs () .FirstOrDefault (q => string.Compare (q.Key, "Humedad", verdadero) ==0) .Value; string UVLight =req.GetQueryNameValuePairs () .FirstOrDefault (q => string.Compare (q.Key, "UVLight", true) ==0) .Value; if (Temperature ==null || Moisture ==null || UVLight ==null) {// Obtener el cuerpo de la solicitud return req.CreateResponse (HttpStatusCode.BadRequest, "Por favor, pase un nombre en la cadena de consulta o en el cuerpo de la solicitud"); } var str =ConfigurationManager.ConnectionStrings ["sqldb_connection"]. ConnectionString; using (SqlConnection conn =new SqlConnection (str)) {conn.Open (); var text ="INSERT INTO dbo.SmartPlant (Temperatura, Humedad, Luz UV) VALORES (" + Temperatura + "," + Humedad + "," + Luz UV + ");"; using (SqlCommand cmd =new SqlCommand (text, conn)) {// Ejecute el comando y registre las # filas afectadas. var filas =esperar cmd.ExecuteNonQueryAsync (); log.Info ($ "{filas} filas se actualizaron"); }} return req.CreateResponse (HttpStatusCode.OK, "Success");}
Código Arduino Arduino
Código Arduino para cargar los datos y regar automáticamente la planta#include "Arduino.h" #include "Board.h" #include "Helium.h" #include "HeliumUtil.h" #include#include "Arduino.h" #include "Wire.h" #include #include #define CHANNEL_NAME "Azure IoT App" Helio helio (&atom_serial); Canal de canal (&helio); int relay =5; void setDisplayToOriginalState () {SeeedGrayOled.init (SSD1327);} void setup () {// ponga su código de configuración aquí, para que se ejecute una vez:Serial.begin (9600); pinMode (relé, SALIDA); retraso (150); / * Restablecer HP20x_dev * / TH02.begin (); retraso (100); Serial.println ("TH02_dev está disponible. \ N"); DBG_PRINTLN (F ("Inicio")); // Comience la comunicación con Helium Atom // La velocidad en baudios difiere según la placa admitida // y está configurada en Board.h helium.begin (HELIUM_BAUD_RATE); // Conecte el átomo a la red de helio helium_connect (&helium); // Comienza a comunicarte con el canal. Esto solo debería tener que // hacerse una vez. Las funciones de HeliumUtil agregan una lógica de reintento simple // para volver a crear un canal si se desconecta. channel_create (&canal, CHANNEL_NAME); Wire.begin ();} void loop () {// Contaminación acústica int humedad =0; para (int i =0; i <32; i ++) {humedad + =analogRead (A0); } int uvlight =0; para (int i =0; i <32; i ++) {uvlight + =analogRead (A1); } temperamento flotante =TH02.ReadTemperature (); humedad de flotación =TH02.ReadHumidity (); String dataString ="Humedad =" + String (humedad) + "&UVLight =" + String (luz ultravioleta) + "&Temperature =" + String (temperamento) + "&Humedad =" + String (humedad); char data [dataString.length ()]; dataString.toCharArray (datos, dataString.length ()); channel_send (&canal, CHANNEL_NAME, datos, strlen (datos)); Serial.println (datos); setDisplayToOriginalState (); SeeedGrayOled.clearDisplay (); // Pantalla clara. SeeedGrayOled.setNormalDisplay (); // Establecer el modo de visualización normal SeeedGrayOled.setVerticalMode (); // Establecer en modo vertical para mostrar texto SeeedGrayOled.setTextXY (0, 0); // Coloca el cursor en la línea 0, columna 0 String weturestring ="Humedad:" + String (humedad); char moibuffer [wettring.length ()]; Weturestring.toCharArray (moibuffer, wetString.length ()); SeeedGrayOled.putString (moibuffer); SeeedGrayOled.setTextXY (2, 0); String uvstring ="UVLight:" + String (uvlight); char uvbuffer [uvstring.length ()]; uvstring.toCharArray (uvbuffer, uvstring.length ()); SeeedGrayOled.putString (uvbuffer); SeeedGrayOled.setTextXY (4, 0); Cadena de temperatura cadena =Cadena (temperamento) + "C"; char tempbuffer [TemperatureString.length ()]; TemperatureString.toCharArray (tempbuffer, TemperatureString.length ()); SeeedGrayOled.putString (tempbuffer); SeeedGrayOled.setTextXY (6, 0); String humidstring ="Húmedo:" + String (humedad); char humidbuffer [temperaturetring.length ()]; humidstring.toCharArray (humidbuffer, humidstring.length ()); SeeedGrayOled.putString (búfer de humedad); si (humedad <100) {digitalWrite (relé, ALTA); retraso (5000); digitalWrite (relé, BAJO); } retraso (60000);}
Repo del proyecto
Proyecto de repositorio para netduino smart planthttps://github.com/Nyceane/smart-plant-iotEsquemas
La arquitectura de helio conecta el dispositivo IoT directamente a Azure IoT HubProceso de manufactura
- Una mirada en profundidad a IoT en la agricultura y las soluciones de agricultura inteligente
- Datos inteligentes:la próxima frontera en IoT
- IoT celular:cubo de basura inteligente
- Smart Bartender
- GE abre una planta inteligente en Alabama
- Los hospitales inteligentes del mañana necesitan un software más inteligente
- Los secretos de una infraestructura de IoT con una ciudad inteligente
- Sea inteligente con su dólar de IoT
- El ecosistema de IoT crea un almacén inteligente optimizado
- Mantenerse seguro con dispositivos inteligentes e IoT
- Últimos avances y aplicaciones en la tecnología de IoT