meta data de esta página
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| electronica:wemos:riego_autonomo [072017/06/ 23:02] – [Riego Idependiente] lc | electronica:wemos:riego_autonomo [182023/01/ 13:36] (actual) – editor externo 127.0.0.1 | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| + | {{tag> | ||
| + | ===== Riego Idependiente ===== | ||
| + | La idea de este proyecto es crear un sistema de riego automático que funcione independiente de una toma de agua. Para ello utilizaremos un motor sumergible que meteremos dentro de una garrafa y un wemos con display oled para controlar todo el sistema. | ||
| + | |||
| + | Materiales: | ||
| + | * Wemos D1 mini | ||
| + | * Display oled 0.96 | ||
| + | * Sensor | ||
| + | * circuito para cargar batería Lipo (TP 4506) | ||
| + | * batería Lipo | ||
| + | |||
| + | ==== Circuito ==== | ||
| + | Las equivalencias con los GPIOs lo pueden encontrar e http:// | ||
| + | Necesitaremos usar un transistor bipolar | ||
| + | < | ||
| + | |||
| + | Yo he utilizado un transistor BCP337 y un motor con una resistencia de unos 10 ohm . Utilizando la calculadora (https:// | ||
| + | |||
| + | Independiente de la resistencia de base necesitamos también poner un diodo en paralelo con el motor. | ||
| + | |||
| + | ** Pantalla Oled ** -> Vdd a +3V, GND al menos , el pin SCL al GPIO5 (D1) y SDA al GPIO4 (D2) del Wemos | ||
| + | **FC28 ** -> Vcc a +3V, GND, A0 a la patilla A0 del Wemos | ||
| + | |||
| + | < | ||
| + | El circuito queda de la siguiente forma: | ||
| + | {{ : | ||
| + | < | ||
| + | ==== Programa ==== | ||
| + | Lo primero debemos descargar e instalar las librerías para arduino del display Oled -> Adafruit_GFX y Adafruit_SSD1306 | ||
| + | |||
| + | |||
| + | |||
| + | <sxh C++> | ||
| + | / | ||
| + | // | ||
| + | // | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // | ||
| + | byte pinSensorHumedad = A0; | ||
| + | |||
| + | // | ||
| + | byte pinMotor = 15; //GPIO15 que es el D8 en el ESP8266 | ||
| + | |||
| + | // | ||
| + | // SCL GPIO5 | ||
| + | // SDA GPIO4 | ||
| + | #define OLED_RESET 0 // GPIO0 | ||
| + | Adafruit_SSD1306 display(OLED_RESET); | ||
| + | |||
| + | #define NUMFLAKES 10 | ||
| + | #define XPOS 0 | ||
| + | #define YPOS 1 | ||
| + | #define DELTAY 2 | ||
| + | |||
| + | #define LOGO16_GLCD_HEIGHT 16 | ||
| + | #define LOGO16_GLCD_WIDTH | ||
| + | |||
| + | |||
| + | // | ||
| + | byte MODO_SOLO_HUMEDAD = 0; | ||
| + | |||
| + | |||
| + | int modoElegido = 0; // Modo de funcionamiento | ||
| + | |||
| + | int umbralHumedad = 0; // Umbral de humedad seleccionado para empezar a regar | ||
| + | |||
| + | int duracionRiego = 0; // Duración del riego en segundos una vez alcanzado el evento de activación | ||
| + | |||
| + | String linea1; | ||
| + | String linea2; | ||
| + | |||
| + | int humedadMinima = 0; // Lectura mínima por defecto para el sensor de humedad (se ajusta dinámicamente) | ||
| + | int humedadMaxima = 100; // Lectura máxima por defecto para el sensor de humedad (se ajusta dinámicamente) | ||
| + | |||
| + | int lecturasHumedad[10]; | ||
| + | int indiceLecturasHumedad = 0; // Indice para saber que valor toca rellenar del array previo | ||
| + | boolean mediaLista = false; // Indicador de que ya están rellenos los 10 valores del array | ||
| + | int mediaHumedad = 0; // Media de las últimas 10 lecturas de humedad | ||
| + | int riegos = 0; // Numero de riegos realizados | ||
| + | int limiteRiegos = 10; // Limite de seguridad del número de riegos | ||
| + | const int dormir = 10; // | ||
| + | |||
| + | // | ||
| + | void setup() | ||
| + | Serial.begin(9600); | ||
| + | |||
| + | // Establece a modo salida el pin para controlar el motor | ||
| + | pinMode(pinMotor, | ||
| + | |||
| + | // | ||
| + | umbralHumedad = 70; | ||
| + | |||
| + | // | ||
| + | duracionRiego = 10; | ||
| + | |||
| + | // | ||
| + | display.begin(SSD1306_SWITCHCAPVCC, | ||
| + | // init done | ||
| + | |||
| + | display.display(); | ||
| + | delay(2000); | ||
| + | |||
| + | // ------------------------Limpiar el buffer. ------------------------- | ||
| + | display.clearDisplay(); | ||
| + | |||
| + | // ------------------------Muestra el tiempo entre riegos | ||
| + | linea1 = " | ||
| + | linea2 = " | ||
| + | mostrarTexto(); | ||
| + | delay(1000); | ||
| + | |||
| + | } | ||
| + | void loop() { | ||
| + | |||
| + | |||
| + | // ----------------------------------Continua el bucle hasta que el tiempo llegue a cero | ||
| + | while (true) | ||
| + | { | ||
| + | delay(1000); | ||
| + | |||
| + | // ----------------------------- Actualiza la variable con la humedad actual | ||
| + | leerHumedad(); | ||
| + | |||
| + | // ---------------------------------Actualiza el display con el tiempo hasta el siguiente riego y la humedad actual | ||
| + | linea1 = " | ||
| + | linea2 = " | ||
| + | mostrarTexto(); | ||
| + | |||
| + | // Si la media de humedad de las últimas 10 lecturas está lista y es inferior al umbral configurado, | ||
| + | | ||
| + | if ((mediaHumedad < umbralHumedad) && mediaLista) | ||
| + | { | ||
| + | regar(); | ||
| + | // Reinicia la media de humedad para que le tiempo a la tierra a empaparse | ||
| + | indiceLecturasHumedad = 0; | ||
| + | mediaLista = false; | ||
| + | } | ||
| + | // Si la media de humedad de las últimas 10 lecturas está lista y es superior al umbral configurado, | ||
| + | if ((mediaHumedad > umbralHumedad) && mediaLista) | ||
| + | { | ||
| + | reposo(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | // ------------------------------------- Muestra el texto configurado en el display --------------------- | ||
| + | void mostrarTexto() | ||
| + | { | ||
| + | display.clearDisplay(); | ||
| + | display.setTextSize(1); | ||
| + | display.setTextColor(WHITE); | ||
| + | display.setCursor(0, | ||
| + | display.println(linea1); | ||
| + | display.setCursor(0, | ||
| + | display.println(linea2); | ||
| + | display.display(); | ||
| + | delay(2000); | ||
| + | |||
| + | |||
| + | } | ||
| + | // ----------------------------Actualiza la variable con la media de humedad de las últimas 10 lecturas ------------------------- | ||
| + | void leerHumedad() | ||
| + | { | ||
| + | lecturasHumedad[indiceLecturasHumedad] = analogRead(pinSensorHumedad); | ||
| + | |||
| + | // Serial.println (lecturasHumedad[indiceLecturasHumedad]); | ||
| + | |||
| + | lecturasHumedad[indiceLecturasHumedad] = map (lecturasHumedad[indiceLecturasHumedad], | ||
| + | //los valores 140 y 395 son los que me daba mi sensor -> | ||
| + | indiceLecturasHumedad++; | ||
| + | if (indiceLecturasHumedad > 9) | ||
| + | { | ||
| + | indiceLecturasHumedad = 0; | ||
| + | mediaLista = true; | ||
| + | } | ||
| + | |||
| + | mediaHumedad = 0; | ||
| + | for (int i = 0; i < 10; i++) mediaHumedad += lecturasHumedad[i]; | ||
| + | mediaHumedad /= 10; | ||
| + | |||
| + | Serial.println (mediaHumedad); | ||
| + | |||
| + | if (mediaHumedad > humedadMaxima) humedadMaxima = mediaHumedad; | ||
| + | if (mediaHumedad < humedadMinima) humedadMinima = mediaHumedad; | ||
| + | mediaHumedad -= humedadMinima; | ||
| + | |||
| + | mediaHumedad = (double)((double)mediaHumedad / (double)(humedadMaxima - humedadMinima)) * 100; | ||
| + | |||
| + | } | ||
| + | |||
| + | // -----------------------------------------Devuelve una cadena numérica de al menos 2 caractes, rellenando con un cero por la izquierda si hace falta | ||
| + | |||
| + | String str(int valor) | ||
| + | { | ||
| + | if (valor < 10) return " | ||
| + | else return (String(valor)); | ||
| + | } | ||
| + | |||
| + | |||
| + | // ---------------------------Activa lo bomba de riego durante el tiempo configurado | ||
| + | void regar() | ||
| + | { | ||
| + | |||
| + | int riegoPendiente = duracionRiego; | ||
| + | digitalWrite(pinMotor, | ||
| + | while (riegoPendiente > 0) | ||
| + | { | ||
| + | linea1 = " -- REGANDO -- "; | ||
| + | linea2 = " | ||
| + | mostrarTexto(); | ||
| + | delay(990); | ||
| + | riegoPendiente--; | ||
| + | } | ||
| + | digitalWrite(pinMotor, | ||
| + | riegos++; | ||
| + | } | ||
| + | |||
| + | // ----------------- Entra en modo de ahorro energía ------------- | ||
| + | void reposo() | ||
| + | { | ||
| + | // a Dormir un rato (ojo se resetea y pierde el valor de las variables) | ||
| + | Serial.println(" | ||
| + | ESP.deepSleep(dormir * 1000000); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ==== Referencias ==== | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * http:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * http:// | ||
| + | |||