Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Una solución de riego de plantas urbanas

Componentes y suministros

Sensor de humedad del suelo
Se puede utilizar cualquier sensor de humedad del suelo con salida analógica. También se pueden usar dos electrodos y un divisor de voltaje. ESTOS SON OPCIONALES.
× 2
Sensor de lluvia
× 1
Jarra de leche
Cualquier recipiente que pueda contener agua, cortarse y asegurarse a una superficie servirá. montarse en una superficie elevada.
× 1
Tubo hueco flexible de plástico blando
Cualquier tipo de tubería servirá. Usé una cuerda para saltar con los extremos cortados, ya que es muy flexible y el centro es hueco.
× 1
Cables de puente (genéricos)
Más o menos.
× 37
SparkFun Inventor's Kit para Arduino 101
Usé Arduino 101, servo, tablero, potenciómetro y LCD.
× 1
Arcilla para modelar
× 1
Varilla de plástico corta
O cualquier varilla no flexible. Se utiliza para soportar la tubería de salida del tanque de agua.
× 1
Resistencia de 330 ohmios
× 1

Herramientas y máquinas necesarias

Tijeras
Destornillador Phillips
Cinta aislante
y también cinta normal.

Aplicaciones y servicios en línea

Nordic Semiconductor nRF Connect SDK
Arduino IDE

Acerca de este proyecto

Este dispositivo mejora el riego de las plantas en entornos urbanos. Alimentado por un Arduino 101, utiliza herramientas integradas junto con algunos sensores externos para calcular las condiciones óptimas para regar las plantas en su propio entorno, y luego riega la planta en el momento calculado.

Se basa en los siguientes conceptos:

Gravedad y presión

Este dispositivo extrae su fuente de agua de un depósito, que hice con una jarra de leche, un tubo de plástico, arcilla para sellar el tubo y un servo. Este contenedor está colocado de tal manera que, además de estar elevado, puede recoger el agua de lluvia por encima del dispositivo.

La jarra se llena principalmente con un suministro de agua doméstico (debido a que la lluvia no siempre está disponible), pero se complementa con agua de lluvia. Cuando hay agua en la jarra, la fuerza de atracción de la gravedad empuja el agua hacia la Tierra dentro de la jarra. Se hace un agujero en la base de la jarra para permitir la inserción de un tubo de salida. La fuerza de la gravedad arrastra el agua a través de esta tubería de salida. El servo regula cuándo se permite que el agua salga completamente de la tubería. En circunstancias normales, el brazo del servo está en posición vertical, lo que evita que el agua fluya por la tubería. Sin embargo, al regar la planta, el brazo desciende 135 grados, lo que permite que el agua salga de la tubería y riegue las plantas. El brazo se levanta una vez que se completa.

La presión del agua contra la jarra no solo ayuda a la estabilidad de la jarra, sino que también ayuda con la salida del agua, lo que permite un flujo continuo de agua durante el riego.

Sensor de temperatura TMP36 y motor de coincidencia de patrones Intel Curie

Esta combinación de conceptos ayuda a impulsar el cálculo que determina el momento óptimo para regar las plantas. El TMP36 es un sensor de temperatura que funciona como un termómetro, pero con una salida analógica electrónica. Un dispositivo, como un microcontrolador, puede leer esta salida y convertirla a temperatura. En este proyecto, el dispositivo intenta calcular el tiempo óptimo para regar las plantas, que está más cerca de los 25 grados centígrados. Realiza 30 registros por hora, a intervalos de dos minutos, y al final de cada período calcula el promedio de 29 de estos (excluyendo el primero, ya que suele ser inexacto). Aquí es donde entra en juego el motor de coincidencia de patrones.

Intel Curie PME, o motor de coincidencia de patrones, es una red neuronal artificial integrada en Arduino 101. Sus bibliotecas están disponibles en GitHub. Compuesto por 128 neuronas, es capaz de aprender y clasificar datos, guardados en vectores, basados ​​en datos existentes o vectores clasificados en categorías. Cuantas más categorías estén disponibles, más opciones de clasificación podrá perseguir el PME.

Para este proyecto, el PME registra datos de temperatura durante el transcurso de un día e intenta clasificar la condición óptima, 25 grados Celsius, entre estos datos. El resultado se convierte en el momento del día siguiente para regar la planta.

Los datos se registran cada hora desde las 8 am hasta las 9 pm. La primera vez que se hace esto, los datos se guardarán en la Flash serial incorporada . Esto permitirá que el dispositivo se inicie en un conjunto de datos incluso si se ha apagado. Después de obtener el conjunto de datos, intenta clasificar las condiciones óptimas. Si puede hacerlo, la categoría seleccionada se convierte en la hora utilizada para la siguiente ronda. De lo contrario, el dispositivo utilizará constantes mensuales o la hora del día en que cada mes las temperaturas son más altas. Cabe señalar que estas no siempre son las mejores temperaturas para regar las plantas , por eso utilicé el PME.

Después de la primera sesión de aprendizaje, los datos se borran y se vuelven a aprender al día siguiente, y la planta se riega a la hora elegida. Este ciclo se repite infinitamente, o hasta que el dispositivo se desconecta de la alimentación, momento en el que cuando se vuelve a encender utiliza los parámetros guardados como la hora seleccionada y continúa.

Reloj en tiempo real Intel Curie y Bluetooth de bajo consumo

El Intel Curie RTC, o reloj en tiempo real, es un componente crucial de este dispositivo. El RTC controla cuándo ocurre todo en el dispositivo. Para este proyecto, el RTC es especialmente esencial para realizar un seguimiento de la hora, que se usa para regar la planta y cuándo registrar los datos, y el mes, que se usa para determinar las constantes de temperatura pico de respaldo. Sin embargo, la fecha precisa para este RTC debe configurarse manualmente, ya sea en código o por entrada del usuario. Esto se resolvió con BLE.

Bluetooth Low Energy es una versión más reciente de Bluetooth diseñada para dispositivos de bajo consumo. Opera en un sistema central-periférico, donde una central, o entrada, escribe en periféricos o salidas. Esto actúa más como un sistema de tablero de anuncios, donde la central coloca los datos en un boletín para que todos los periféricos los lean. En este caso, utilicé nRF Connect de Nordic Semiconductor en mi dispositivo móvil como central y el Arduino 101 como periférico. El dispositivo móvil tiene la capacidad de conectarse al Arduino y enviarle datos. En este caso, el dispositivo móvil debe enviar datos cuatro veces, una para cada uno de los campos de entrada obligatorios.

La entrada de datos en el dispositivo móvil se escribe en hexadecimal. Esto es bastante fácil de convertir desde base 10, pero se puede usar un convertidor en línea.

Cómo construir

La construcción de esta solución de riego requiere un poco de conocimiento de circuitos, pero no demasiado. También requiere algunos componentes no eléctricos para terminar. Aquí está la lista de piezas completa:

Componentes eléctricos

  • Arduino 101
  • Tablero de pruebas de 400 corbatas, con rieles + -
  • Potenciómetro giratorio
  • LCD de 16x2
  • Resistencia de 330 ohmios
  • Sensor de temperatura TMP36
  • Servo de 180 grados, con bocina de servo
  • Sensor de lluvia y tablero de control
  • Sensor de humedad del suelo y tablero de control (opcional, hardware incluido como referencia)
  • Una cantidad considerable de cables de puente; ver el diagrama de Fritzing

Para funcionar con baterías (puede que no dure demasiado; la configuración que utilicé):

  • cajas de batería 2X 4xAA con interruptor de encendido / apagado y cables conductores
  • 8 pilas recargables AA de 1,2 V NiMH

Para funcionar con alimentación USB, ya sea desde una verruga de pared o una computadora portátil:

  • Cable USB macho A - macho B, cuya longitud depende de sus necesidades

Componentes de hardware no eléctricos

  • Jarra de leche
  • Tubo de plástico flexible, de unos 20-30 cm de largo
  • Plastilina, pegamento termofusible o cualquier cosa que pueda usarse como sellador
  • Varilla de plástico, para sostener el brazo del tubo
  • Canasta para manualidades, para sostener el dispositivo
  • Superficie elevada para sostener la jarra, es decir, un banco pequeño o una mesa
  • Una planta

Herramientas

  • Cinta, tanto normal como eléctrica
  • Tijeras
  • Destornillador Phillips, para conectar la bocina del servo al servo

Pasos

1. Construya el circuito de acuerdo con el diagrama de Fritzing a continuación. Tenga en cuenta que los sensores de humedad del suelo son opcionales y que el sensor de lluvia y el servo pueden necesitar cables más largos para llegar a las ubicaciones deseadas. Vea la segunda foto a continuación para ver la disposición final del circuito.

2. (Vaya al paso 5 si usa alimentación USB). Inserte las baterías en las dos cajas de baterías y ate el cable positivo de una caja y el cable negativo de la otra.

3. Pegue las cajas con cinta aislante. Asegure las cajas de modo que las cubiertas de ambos queden pegadas y las carcasas de ambos, y la cubierta sea removible como una sola pieza. Deje las ranuras abiertas para los interruptores de encendido.

4. Pega con cinta adhesiva la cubierta doble de la caja de la batería a la parte inferior del Arduino 101 y la placa de pruebas. Esto permitirá que las baterías se reemplacen fácilmente deslizándolas hacia afuera desde debajo de la placa.

5. Inserte el dispositivo en la canasta de manualidades y corte dos ranuras en un lado del dispositivo. La primera ranura será para programación (o alimentación USB si así lo desea), y la segunda será una salida para los sensores y actuadores que no se encuentran en el dispositivo. Siéntase libre de usar cinta aislante para asegurar los cables sueltos juntos en este tomacorriente.

6. Tome una jarra de leche y corte la parte superior para que la jarra tenga una abertura lo suficientemente grande para recolectar agua y una capacidad lo suficientemente grande para ser confiable. Recomiendo que el corte esté cerca de la base del mango.

7. Haga un pequeño agujero en la base de la jarra directamente debajo de la parte más grande de la abertura en la parte superior de la jarra. Inserte un extremo del tubo de plástico en este orificio. Asegúrese de que el orificio sea lo suficientemente pequeño para que la tubería permanezca en su posición, pero lo suficientemente grande para que no apriete la tubería.

8. Use la arcilla para sellar las áreas superior e inferior alrededor de la tubería en el agujero. Asegúrese de que la arcilla no entre en la tubería.

9. Usando arcilla y cinta aislante, asegure el servo lo más bajo posible a la base de la jarra de leche. Pega con cinta adhesiva la mitad del tubo y una varilla de plástico a la bocina del servo. Asegúrese de que la varilla de plástico también esté pegada con cinta al extremo superior del tubo. Utilice la imagen siguiente como referencia para los pasos 8 a 10.

10. Asegure la jarra en la superficie elevada. Use cinta si es necesario.

11. Coloque una planta justo debajo de la salida del tubo cuando esté en posición baja. Pegue los sensores de humedad en el suelo si los está usando y coloque el sensor de lluvia cerca de la planta a lo largo del piso. Conecte los sensores y el servo en el dispositivo, con el dispositivo colocado un poco más lejos de la jarra y la planta.

Programación

Programe el Arduino 101 con el código adjunto. Sube usando Arduino IDE y Curie Core 2.0.2 o superior (si está disponible). En el código se incluyen muchos comentarios útiles.

Funcionamiento del dispositivo

Cuando el dispositivo se enciende por primera vez, esperará a que se conecte un dispositivo móvil. Una vez que un dispositivo está conectado usando nRF Connect, esperará la entrada de tiempo. Para hacer esto, ingrese secuencialmente los códigos hexadecimales para la base de 10 horas, minutos, día y mes en orden en nRF Connect como se muestra en el diagrama a continuación.

Una entrada de ID, o cualquier número, debe escribirse y enviarse antes de ingresar las horas.

Después de escribir la hora, el 101 esperará a que el dispositivo móvil se desconecte. Después de hacerlo, esperará a las 8 am, ya sea el día actual o el siguiente.

Al llegar a las 8 am, la pizarra verificará si tiene algo guardado en la memoria flash. De lo contrario, pasará por el proceso de recopilación de 14 horas como se describió anteriormente, y luego clasificará los datos y determinará el momento óptimo, momento en el que se repetirá el ciclo de recopilación. Si se almacena algo, esos datos se utilizan como la constante horaria y los ciclos continúan con normalidad.

Durante los momentos en los que el tablero riega la planta, la presencia de lluvia o un exceso de humedad del suelo (opcional) impedirá que la planta sea regada. Luego se saltará el riego del día y esperará al siguiente.

Esta solución está diseñada para simplificar y optimizar el riego de las plantas urbanas empleando una configuración automática para solucionar este problema. También conserva el agua de lluvia junto con los suministros domésticos existentes mediante el uso de un depósito, que aprovecha la lluvia que no se dirige a las plantas.

¡Esperamos que este proyecto haga de nuestro mundo en constante cambio un lugar un poco mejor!

Código

  • Sistema de riego Arduino 101
Sistema de riego Arduino 101 Arduino
Código para operar el sistema de riego Arduino 101. Sube usando Curie core 2.0.2 y cualquier IDE 1.8.xo superior. CuriePME se puede encontrar en GitHub.
 / * Este es un boceto para una solución de riego urbano. Utiliza el CuriePME para aprender los datos de temperatura y clasificar la condición óptima de riego de la planta en comparación con ella. Luego riega la planta en ese momento y vuelve a aprender los datos, ciclando infinitamente. Tenga en cuenta que este boceto DEBE EJECUTARSE ANTES de las 8 am del día objetivo para iniciar el dispositivo. Fuentes de datos:"WeatherSpark.com". Clima promedio en Vancouver, Canadá, todo el año - Weather Spark. N.p., n.d. Web. 4 de julio de 2017. . "Just 4 Growers:Global Garden Community". Solo para cultivadores. N.p., n.d. Web. 10 de julio de 2017. . * /// Bibliotecas para usar con este código. Todos ellos excepto CuriePME se pueden encontrar en el ide. CuriePME se puede descargar desde el repositorio de GitHub. # Include "CuriePME.h" #include  #include  #include  #include  #include  #include  // Código pinout del servo Servo waterPipe; // Código pinout LCD.LiquidCrystal lcd (12, 11, 5, 4, 3, 2); // Constantes / variables globales. # definir termómetro A3 # definir rainSensor 1 # definir humedad1 A4 # definir humedad2 A1int tm1; int tm2; int tm3; int tm4; int tm5; int tm6; int tm7; int tm8; int tm9; int tm10; int tm11; int tm12; int tm13; int tm14; int tm15; int tm16; int tm17; int tm18; int tm19; int tm20; int tm21; int tm22; int tm23; int tm24; int tm25; int tm26; int tm27; int tm28; int tm29; int tm30; int average; int progav; float voltage; float temperatureC; int tm; int hourTime =-1; int minuteTime =-1; int dayTime =-1; int monthTime =-1; int confirmTime =-1; // servicio BLE data.BLEService plantService ("19B10000-E8F2-537E-4F6C-D104768A1214"); // Característica BLE, legible / escribible por central.BLEUnsignedCharCharacteristic timeCha racterístico ("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); void setup () {// Esto se ejecuta una vez. waterPipe.attach (9); waterPipe.write (0); pinMode (sensor de lluvia, ENTRADA); lcd. comienzo (16, 2); // Inicie y borre la pantalla LCD. lcd.clear (); if (! SerialFlash.begin (ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)); lcd.setCursor (0, 0); lcd.print ("Hora de entrada:BLE"); // Inicialice el servicio BLE con nombre, servicio, característica y valor de característica. BLE.begin (); BLE.setLocalName ("Arduino 101"); BLE.setAdvertisedService (plantService); plantService.addCharacteristic (timeCharacteristic); BLE.addService (plantService); timeCharacteristic.setValue (0); // 0 hasta que lo escriba central. BLE.advertise (); lcd.setCursor (0, 1); lcd.print ("Esperando"); // Listo para conectarse.x:BLEDevice central =BLE.central (); if (central) {// Si un dispositivo se enlaza con el tablero. lcd.setCursor (8, 1); lcd.print ("Listo"); retraso (3000); while (central.connected ()) {// Mientras el dispositivo aún está conectado. if (timeCharacteristic.written ()) {// Código que llena secuencialmente todas las ranuras de variables de tiempo después de que se envía cada byte desde el dispositivo. Los datos se envían cuatro veces, más una para la confirmación del enlace. if (confirmTime ==-1) {confirmTime =timeCharacteristic.value (); } else if (hourTime ==-1) {hourTime =timeCharacteristic.value (); } else if (minuteTime ==-1) {minuteTime =timeCharacteristic.value (); } else if (dayTime ==-1) {dayTime =timeCharacteristic.value (); } else if (monthTime ==-1) {monthTime =timeCharacteristic.value (); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Hora establecida"); lcd.setCursor (0, 1); lcd.print ("Desconectar dispositivo"); }}}} else {ir a x; // Vuelve atrás si un dispositivo aún no está conectado. } // Establece la hora con las variables recopiladas. Los segundos y el año no importan para este sistema. setTime (hourTime, minuteTime, 00, dayTime, monthTime, 2017); // Inicializa el PME. lcd.clear (); CuriePME.begin (); lcd.setCursor (0, 0); lcd.print ("Comprobando guardar."); retraso (3000); const char * nombre de archivo ="NeurData.dat"; if (check_if_exists (filename) ==true) {restoreNetworkKnowledge (); lcd.setCursor (0, 1); lcd.print ("¡Encontrado!"); retraso (3000); lcd.clear (); goto z; } else {lcd.setCursor (0, 1); lcd.print ("¡No encontrado!"); retraso (3000); lcd.clear (); } / * La parte restante de la configuración recopila datos de temperatura durante el transcurso del día. Hace 30 verificaciones por hora, espaciadas a intervalos de 2 minutos, y al final de la hora toma un promedio de los datos de la hora al encontrar la media aritmética de todos los datos excepto el primer escaneo. Luego, este medio se introduce en el PME y se aprende. Esto se repite de 8 am a 9 pm, momento en el que el conjunto de datos completo aprendido por el PME se guarda en la memoria CurieFlash de forma predeterminada para si el dispositivo pierde energía o es necesario reiniciarlo. * / lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizaje"); for (int i =8; i <22; i ++) // Repite esto 14 veces, cada una guardando en una categoría diferente. {// Recopila 30 datos de temperatura, guardados como un int mapeado entre 0 y 255. voltage =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm1 =restringir (tm, 0, 255); retraso (114000); // Compense la demora de verificación anterior. voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm2 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm3 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm4 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm5 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm6 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm7 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm8 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm9 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm10 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm11 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm12 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm13 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm14 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm15 =restringir (tm, 0, 255); // Durante el primer período de aprendizaje, el riego de las plantas se realizará en el pico de temperatura de ese mes. if ((mes () ==1 || mes () ==2 || mes () ==11 || mes () ==12) &&hora () ==12) {lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); // Riegue la planta si no llueve y la humedad del suelo es lo suficientemente baja. int readRain =digitalRead (rainSensor); if (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print ("Lloviendo ahora mismo"); goto a2; } // Descomenta el uso de sensores de humedad. // else if (analogRead (humedad1)> 400 || analogRead (humedad2)> 400) // Ajústelos para que coincidan con su suelo. // {//lcd.setCursor(0, 1); //lcd.print("Suelo demasiado húmedo. "); // ir a a2; //} else {waterPipe.write (135); retraso (7000); // Agua durante 7 segundos. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print ("Listo"); a2:retraso (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizaje"); } más si ((mes () ==3 || mes () ==4 || mes () ==10) &&hora () ==14) {lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); // Riegue la planta si no llueve y la humedad del suelo es lo suficientemente baja. int readRain =digitalRead (rainSensor); if (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print ("Lloviendo ahora mismo"); goto a31; } // Descomenta el uso de sensores de humedad. // else if (analogRead (humedad1)> 400 || analogRead (humedad2)> 400) // Ajústelos para que coincidan con su suelo. // {//lcd.setCursor(0, 1); //lcd.print("Suelo demasiado húmedo. "); // ir a a31; //} else {waterPipe.write (135); retraso (7000); // Agua durante 7 segundos. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print ("Listo"); a31:retraso (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizaje"); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizaje"); } más si ((mes () ==5 || mes () ==6 || mes () ==9) &&hora () ==15) {lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); // Riegue la planta si no llueve y la humedad del suelo es lo suficientemente baja. int readRain =digitalRead (rainSensor); if (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print ("Lloviendo ahora mismo"); goto a3; } // Descomenta el uso de sensores de humedad. // else if (analogRead (humedad1)> 400 || analogRead (humedad2)> 400) // Ajústelos para que coincidan con su suelo. // {//lcd.setCursor(0, 1); //lcd.print("Suelo demasiado húmedo. "); // ir a a3; //} else {waterPipe.write (135); retraso (7000); // Agua durante 7 segundos. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print ("Listo"); a3:retraso (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizaje"); } más si ((mes () ==7 || mes () ==8) &&hora () ==16) {lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Ejecutando ..."); // Riegue la planta si no llueve y la humedad del suelo es lo suficientemente baja. int readRain =digitalRead (rainSensor); if (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print ("Lloviendo ahora mismo"); goto a4; } // Descomenta el uso de sensores de humedad. // else if (analogRead (humedad1)> 400 || analogRead (humedad2)> 400) // Ajústelos para que coincidan con su suelo. // {//lcd.setCursor(0, 1); //lcd.print("Suelo demasiado húmedo. "); // ir a a4; //} else {waterPipe.write (135); retraso (7000); // Agua durante 7 segundos. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print ("Listo"); a4:retraso (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizaje"); } retraso (110000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm16 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm17 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm18 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm19 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm20 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm21 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm22 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm23 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm24 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm25 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm26 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm27 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm28 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm29 =restringir (tm, 0, 255); retraso (120000); voltaje =analogRead (termómetro) * 3.3; voltaje / =1024.0; temperaturaC =(voltaje - 0.5) * 100; tm =mapa (temperatura C, -40, 125, 0, 255); tm30 =restringir (tm, 0, 255); retraso (120000); // Reconvertir los datos a las especificaciones del sensor de temperatura. tm1 =mapa (tm1, 0, 255, -40, 125); tm1 =restringir (tm1, -40, 125); tm2 =mapa (tm2, 0, 255, -40, 125); tm2 =restringir (tm2, -40, 125); tm3 =mapa (tm3, 0, 255, -40, 125); tm3 =restringir (tm3, -40, 125); tm4 =mapa (tm4, 0, 255, -40, 125); tm4 =restringir (tm4, -40, 125); tm5 =mapa (tm5, 0, 255, -40, 125); tm5 =restringir (tm5, -40, 125); tm6 =mapa (tm6, 0, 255, -40, 125); tm6 =restringir (tm6, -40, 125); tm7 =mapa (tm7, 0, 255, -40, 125); tm7 =restringir (tm7, -40, 125); tm8 =mapa (tm8, 0, 255, -40, 125); tm8 =restringir (tm8, -40, 125); tm9 =mapa (tm9, 0, 255, -40, 125); tm9 =restringir (tm9, -40, 125); tm10 =mapa (tm10, 0, 255, -40, 125); tm10 =restringir (tm10, -40, 125); tm11 =mapa (tm11, 0, 255, -40, 125); tm11 =restringir (tm11, -40, 125); tm12 =mapa (tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); // Find the arithmetic mean and commit it to memory. average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; commitSample(i, average); } saveNetworkKnowledge(); // Save this new data to flash memory.z:delay(1);}void commitSample (int category, uint8_t s1){ // Commit to memory a single vector (the average), along with the category, which represents the hour of that data. uint8_t vector[1]; vector[0] =s1; CuriePME.learn(vector, 1, category);}void loop() { // Infinitely repeats. /* This code attempts to classify the optimum temperature for watering plants, 25 Celsius, among the data learned by the PME. If it can classify the data, the returned category becomes the hour at which the plant will be watered. The data is then erased and relearned, which infinitely repeats. IF IT CANNOT CLASSIFY THE DATA, it will take the monthly defaults from earlier in the sketch. */ uint8_t vector[1]; vector[0] =25; int answer =CuriePME.classify(vector, 1 ); if (answer ==CuriePME.noMatch) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("NO MATCHES!"); if (month() ==1 || month() ==2 || month() ==11 || month() ==12) { answer =12; } else if (month() ==3 || month() ==4 || month() ==10) { answer =14; } else if (month() ==5 || month() ==6 || month() ==9) { answer =15; } else if (month() ==7 || month() ==8) { answer =16; } } else { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Category:"); lcd.setCursor (0, 1); lcd.print(answer); } delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Optimization Done"); retraso (3000); CuriePME.forget(); // Erase and relearn. This does not erase the flash memory. lcd.clear (); lcd.setCursor (0, 0); lcd.print("Waiting"); while (hour() !=8); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); // Learn the data again. for (int i =8; i <22; i++) { voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm1 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm2 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm3 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm4 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm5 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm6 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm7 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm8 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm9 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm10 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm11 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm12 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm13 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm14 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm15 =constrain(tm, 0, 255); // The time in the day at which to water the plant, as determined by the PME. if (hour() ==answer) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a5; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ // lcd.setCursor(0, 1); // lcd.print("Soil too moist."); // goto a5; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor (0, 1); lcd.print("Done");a5:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } delay(110000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm16 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm17 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm18 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm19 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm20 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm21 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm22 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm23 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm24 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm25 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm26 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm27 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm28 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm29 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm30 =constrain(tm, 0, 255); delay(120000); tm1 =map(tm1, 0, 255, -40, 125); tm1 =constrain(tm1, -40, 125); tm2 =map(tm2, 0, 255, -40, 125); tm2 =constrain(tm2, -40, 125); tm3 =map(tm3, 0, 255, -40, 125); tm3 =constrain(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; progav =(tm30 - tm2) / 2; commitSample(i, average); }}/* A quick note on the flash memory data:The data will only ever be saved once; that is, it cannot be changed with this code. As a result, if the device loses power, IT WILL DEFAULT TO THE SETTINGS OF THE FIRST TIME IT WAS USED WHEN IT IS REACTIVATED, even if the monthly averages have changed. Keeping the device on an extra day will allow it to software obtain new averages, but the flash memory will stay the same. To erase flash completely, upload "EraseEverything" from "CurieSerialFlash" in the IDE. Then reupload this sketch to save new averages to the flash memory.*/void saveNetworkKnowledge() // Code for saving to flash memory....This file has been truncated, please download it to see its full contents.

Esquemas

Fritzing diagram for the circuit. Note that batteries would be attached on the left. The soil moisture sensors are optional. rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz

Proceso de manufactura

  1. Titanio
  2. Castañuelas
  3. Pegamento
  4. Hilo
  5. Acetileno
  6. Amianto
  7. Dados
  8. Contrachapado
  9. Estaño
  10. Riego automatizado de plantas Raspberry Pi con sitio web
  11. Siemens y Bentley lanzan una solución para acelerar la digitalización de plantas