Sistema de riego con Arduino

Estoy intentando programar el siguiente codigo en arduino uno

El programa debería de comprobar el nivel de agua en el deposito de la bomba, si esta LOW, no debiera funcionar, estando en HIGH, debería empezar a funcionar la bomba durante 20 sg

Si el nivel de agua del deposito de distribución cambia a estado HIGH, tiene que para la Bomba y si los 20 segundos no llega a nivel HIGH , deberá seguir otros 20 sg hasta llegar a nivel HIGH .

Si durante el llenado del deposito de distribución el nivel de la bomba cambia a LOW, parara todo el proceso.

quisiera añadir un reloj tipo ds3231 pero no se como hacerlo para implantarlo en el codigo para poder activar el riego durante una 10 min al dia.

Código:
int levelPump=0     
int levelWater=0

int nivelPump;     // define variable nivel bomba
int nivelWater;    // define variable nivel agua distribuido

int relayPin=2;    // pin de salida activa relay
int nivelBomba=4;   // conectare nivel bomba pin 4
int nivelAgua=7;   // conectare nivel agua distribuidor pin 7

void setup() {
   Serial.begin(9600);
   pinMode(13,OUTPUT);        // led nivel de agua alto 
   pinMode(relayPin,OUTPUT);  // configuro pin 2 como salida relay
   pinMode(nivelBomba,INPUT); // configuro pin 4 como entrada nivel bomba
   pinMode(nivelAgua,INPUT);  // configuro pin 7 como entrada nivel agua 
}
void loop() {
 if (digitalRead(4)==1){ // comprobamos si hay nivel bomba
  levelPump=1;
   digitalWrite(13,HIGH);} // encendemos un led que nos indica nivel agua alto
   nivel();}
void nivel(){
  if(levelPump==1){  // comprueba estado de nivel
   Serial.println("nivel alto");  // muestra nivel y sige con riego
   levelPump=1; }
 else{
  digitalWrite(4,LOW);  // muestra nivel bajo y no continua 
  Serial.print("nivel bajo");}
 }
void riego(){
  if (digitalRead(7)==0){ /*comprueba el estado del nivel de 
                           depositro distribuidor*/
   levelWater=0;       // la variable nivel distribuidor nivel bajo 
   digitalWrite(2,HIGH);    // activa rele y comienza bomba
   Serial.println("BOMBA ON"); 
   delay(20000);            // iniciamos bomba  20 sg
   digitalWrite(2,LOW);    
   Serial.print("BOMBA OFF");
   delay(20000); // esperamos 20 sg
   riego(); }   //volvemos a iniciar riego  
   else{digitalWrite(9,LOW);
  levelWater=1; }}   // se detecta nivel distribuidor alto se apaga riego



Saludos
 
Última edición por un moderador:
Entierra bien hondo los delays y no los vuelvas a usar nunca para nada.
Usa los timers que están para eso.
Durante 20 segundos tu sistema está muerto y no hace caso de nada, pase lo que pase. Es nunca es admisible.

Busca los ejemplos del RTC y mira a ver como los mezclas, el RTC tiene unas alarmas tipo "despertador" para hacerlo
 
#define rele 2 //relé de encendido de la bomba al pin 2
#define tanqueBomba 4 //sensor de nivel del depósito de la bomba al pin 4
#define tanqueRiego 7 //sensor de nivel del deósito de riego al pin 7
#define led 13

void setup(){
pinMode(rele,OUTPUT);
pinMode(tanqueBomba,INPUT);
pinMode(tanqueRiego, INPUT);
pinMode(led, OUTPUT);
digitalWrite(rele, LOW);
digitalWrite(led, LOW);
}

void loop(){
if(digitalRead(tanqueBomba) && !digitalRead(tanqueRiego)){ //si: deposito de bomba lleno y depósito de riego vacío
digitalWrite(rele, HIGH); //enciende la bomba
}else{
digitalWrite(rele, LOW); //bajo cualquier otra circunstancia; apaga la bomba
}
}
Hola @overs; veo tu programa bastante enredado, quizá debas estudiar con mas detenimiento los conceptos de programación.
De todas maneras aquí te pongo un código con el que tendrás mas que suficiente para pasar el agua del depósito de la bomba al tanque de regadío; cumpliendo con las condiciones que se accione la bomba siempre que en su depósito exista el nivel de agua seguro y el tanque de regadío aun este vacío y se apague cuando éste último se llene o cuando el nivel en el de la bomba descienda del mínimo necesario.
No escribí nada para el led porque no entiendo si debe encenderse cuando hay suficiente agua en el depósito de la bomba o cuando se llena el depósito de regadío.
Tampoco hice nada para los diez minutos de “riego diarios” pues me gustaría que especifiques por ejemplo; si es necesario hacerlo en una hora en particular...
El uso del ds3231 me parece innecesario para una aplicación como esta. (como que es complicarse por gusto).
 
Gracias, por tu ayuda PILM.
En cuanto a los led es para saber en que momento de encuentra los estado de los sensores haciendo las pruebas.

Lo del tiempo en principio deseo que funcione una vez al día hasta cumplir el tiempo de llenado en este caso 20sg, ya que estoy probando con un deposito pequeño, pero según adquiera algo mas de conocimientos quisiera implementar un RTC para poder asignar el tiempo y duración de riego. Ya que proyecto es para implantarlo en una finca que hay cortes de luz constantes.

gracias por tu ayuda
 
A ver si comprendo @overs: tienes un depósito de agua donde instalarás una bomba. Esta bomba trasladará el agua a un depósito elevado (el de riego). De éste último se dará riego a la finca; por gravedad (o por medio de otra bomba???). Se regará la finca una vez al día por diez minutos, sin importar la hora del día.
¿Estoy bien hasta ahí…?
 
buenas Pilm:

Te explico el proyecto que deseo hacer:

Se disponen de 2 depósitos, uno es una balsa de que se llena a través de una red de agua de 10.000
litros y otro un deposito de 1000 litros.

El deposito de 1000 litros riega por gravedad

La bomba llena en unos 10 min. llena el deposito con 1000 litros aproximadamente.

El tiempo seria regar en horario nocturno o cuando empiece a oscurecer. 22:00 y dure 10 min.

Los sensores de nivel están puestos, uno para proteger la bomba del primer deposito en el caso de que se quedara sin agua, y en el deposito elevado por si se llena demasiado no se desborde.

Lo de implantar el RTC como comenta Scooter, seria buena idea por que como comentaba en este lugar donde se ubica la finca hay constantes corte de luz y el arduino perdería el tiempo de riego.
 
Saludos @overs. La verdad no tengo experiencia con un RTC, pero no le veo complicado: cuestión de buscar en la red la librería correspondiente, instalarla en el IDE de arduino, comprender y utilizar los métodos que disponga.

Pero, si bien solucionarías lo de la perdida de hora (con un RTC provisto de su propia batería), pensemos en el caso extremo; un corte de energía durante el tiempo que debería haberse dado el riego (22H00 como lo propones). Si la energía se restituye digamos a las 23H00, ¿cómo sabría tu arduino que aún tiene pendiente el riego de ese día?

A mí se me ocurre una forma mas sencilla: implementar un sensor de luz ambiente con foto-resistencia en uno de los pines análogos del arduino, de esa manera tendrías una indicación del momento que el día oscurece. Esta sería la señal para sincronizar la hora de riego. En la memoria EEPROM se guardaría una condición que indique si el riego ya se dio o si aún está pendiente. De esta manera, luego de un corte de energía al atardecer o en la noche, el programa que ejecute el arduino comprobaría tal condición y decidiría la acción que corresponda.
 
buenas Pilm , me parece buena idea lo del sensor de luz, voy a intentar comprar una lo antes posible para poder probar, ¿¿en la opción que comentas también haría falta colocar el RTC o no? o lo hace con la foto-resistencia.
 
Los sistemas de alumbrado público suelen ir con sos detectores, el reloj y una fotocelula.
Lo malo es que por ejemplo un día de tormenta lo mismo se activan las farolas a las dos de la tarde, eso está bien, porque si está oscuro es lo propio, pero si hay tormenta y se pone a regar...
 
Gracias por tu opinión Scooter, veo que cada vez se complica mas este proyecto, estoy pensando que se podría colocar un sensor de lluvia, para este caso, lo que pasa que como comente anteriormente llevo poco en esto y se me hace bastante complicado, pero bueno intentare realizar haber como sale.

gracias por colaborar .
 
Se disponen de 2 depósitos, uno es una balsa de que se llena a través de una red de agua de 10.000 litros y otro un deposito de 1000 litros.

El deposito de 1000 litros riega por gravedad. La bomba llena en unos 10 min. llena el deposito con 1000 litros aproximadamente. El tiempo seria regar en horario nocturno o cuando empiece a oscurecer. 22:00 y dure 10 min.

Podrías subir imágenes del tanque? o de lo que tengas hasta ahora? Algún esquema?
 
Última edición:
buenas Ruben, ahora mismo lo que tengo es una bomba que riega toda la parcela de 1000m2 con arboles, pero quiero realizar una linea independiente para regar hortalizas por goteo, te envió una imagen de lo que deseo realizar.
 

Adjuntos

  • riego.jpg
    riego.jpg
    16.7 KB · Visitas: 14
Ok, comentas que quieres implementar un DS3231 para activar el riego 10 min. al día. Tienes alguna hora en especifico? Te cometan sobre utilizar una foto resistencia, pero se me hace muy impreciso :unsure:. Sobre la programación con arduino no puedo ayudarte porque nunca lo eh utilizado, soy fiel a los PIC :LOL:.

Sobre el DS3231 es simplemente aplicar el protocolo I2C para leer y escribir los registros del CI, y para esto necesitas saber lo básico antes de meterle mano (desafortunadamente :cry:).

Puedo darte información bibliográfica donde hay ejemplos sobre esto y lo aplicas para Arduino,

Microcontrolador PIC16F84: Desarrollo de proyectos, Enrique Palacios Municio. Aquí utilizan el DS1307 que igual es un reloj de precisión muy parecido al DS3231. Explican paso a paso la programación.

Diseño y simulación de sistemas microcontrolados en lenguaje C, Juan Ricardo Mendoza. Aquí igual hay ejemplos de programación del DS1307 en lenguaje C, muy parecido al lenguaje utilizado en Arduino.

En tu código veo que utilizas Delays o retardos de 20 seg, esto no es buena idea. Para Delays mayores de 10_ms son mejores los Timers, como ya te indicaron.
 
Última edición:
Que tal @overs. Solo con la foto-resistencia seria más que suficiente para sincronizar la hora de riego.
Por cierto cuando digo foto-resistencia me refiero al elemento que muestro en la siguiente imagen:
ldr.jpg

Puedes usar cualquiera de las siguientes configuraciones para conectar a un pin análogo del arduino:
ldr_circuito.jpg

Utilizando la instrucción “ analogRead(pinAnalogo); ” lees el pin involucrado, obteniendo una lectura entre 0 y 1023. Cuando esta lectura supere o disminuya (según la configuración que escojas) de cierto valor de referencia determinas el momento que ha anochecido. El riego podrá iniciarse inmediatamente o disparar un temporizador para efectuarlo tiempo mas tarde. Este temporizador así como los diez minutos de riego que planteas puede implementarse en el propio arduino con la función “ milis() “

Se me acaba de ocurrir que tomando lecturas periódicas a lo largo del día y sacando un promedio podrías determinar que tan soleado ha estado el día y con ello ajustar el tiempo de riego… No sé, es tan solo una idea…

Un saludo @ruben90; Yo también prefiero usar PICs, se logran soluciones mas “profesionales”. Sin embargo a nivel didáctico Arduino es insuperable, su entorno de programación es demasiado sencillo, pues es una simplificación de Processing el cual de por sí ya es sencillo por ser a su vez una simplificación de Java. Está pensado para personas con mínimos o muy básicos conocimientos en electrónica y para aquellos que se inician en programación.
Para utilizar por ejemplo el DS3231 que mencionas, el programador ni siquiera necesita tener idea del protocolo I2C. Es cuestión de descargar e instalar la librería correspondiente y durante la escritura del código simplemente invocar sus métodos, según lo que desee hacer…
Échale una mirada, te va a gustar…
 
Última edición:
Hola Overs.

Te pongo un enlace a mi web donde tienes el código de mi sistema de riego. Ahi tienes un .ino donde puedes ver el uso de un RTC, y como está diseñado el riego. Espero que te sirva.

http://www.naparlinex.com/r_soft_code1.php

No uso un sensor de luz, por el asunto de las tormentas (parece que se pone de noche, ANTES de que llueva) y hay un detector de lluvia (hay muchos en el mercado, fáciles de poner).



Además, este sistema de riego está pensado para una huerta, de manera que se puede programar frecuencia de riego diaria y tiempo por día. Por ejemplo, si pones que riegue cada dos días y llueve, el siguiente inicio del riego se desplaza hasta dos dias más tarde.
Bueno y tiene más cosas, pero para lo que tú quieres igual te ilustra un poco.
Y está todo hecho con arduino.
 
Última edición:
Buenas ayer recibí el reloj DS3231, he estado probando un código que encontré que hace algo de lo que quiero pero hay que añadir los sensores de nivel y algo mas, el problema que cuando lo cargo en arduino no me muestra la fecha y hora, en el monitor aparece : 45:165:85 165/165, este es el codigo:

Código:
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  //DS3231 seconds, minutes, hours, day, date, month, year
  setDS3231time(00,00,9,05,04,8,16);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
void displayTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute<10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch(dayOfWeek){
  case 1:
    Serial.println("Sunday");
    break;
  case 2:
    Serial.println("Monday");
    break;
  case 3:
    Serial.println("Tuesday");
    break;
  case 4:
    Serial.println("Wednesday");
    break;
  case 5:
    Serial.println("Thursday");
    break;
  case 6:
    Serial.println("Friday");
    break;
  case 7:
    Serial.println("Saturday");
    break;
  }
}
void loop()
{
  displayTime(); // display the real-time clock data on the Serial Monitor,
  delay(1000); // every second
}
 
Hola, buenas noches.
Estoy realizando un proyecto de sistema de riego con arduino y soy muy nueva en esto de la programación en Arduino.
En estos momentos estoy presentando inconvenientes con el teclado, ya que quiero que el usuario programe la temperatura y humedad ingresando el rango desde un teclado y así mismo que tenga la opción de borrar los datos por si se desea colocar otros valores como Set-Point.
Si alguien me puede ayudar se lo agradecería mucho. Saludos

Este es el código que tengo hasta ahora.
Si me pueden corregir o dar su opinión, sería de gran ayuda para mí. Gracias
C++:
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd (0x20, 16, 2);

const byte fil = 4;
const byte col = 3;

char teclas[fil][col] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte pinfil[fil] = {9, 8, 7, 6};
byte pincol[col] = {5, 4, 3};

Keypad teclado = Keypad( makeKeymap(teclas), pinfil, pincol, fil, col); // dar formato a la matriz teclado

char presionada; // para guardar tecla presionada
int temperatura1 = 0;
int temperatura2 = 0;
int humedad1 = 0;
int humedad2 = 0;
int i=0; //contador

void setup() {
Wire.begin(9600);
lcd.begin(16, 2);
lcd.backlight();
//lcd.noBacklight();
lcd.setCursor(0,0);
lcd.print("Sistema de");
lcd.setCursor(0,1);
lcd.print("Control de Riego");
delay (2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Rango T: ");
}

void loop(){
  while(i<=1){
    presionada=teclado.getKey();
    borrador();

    if(presionada!= NO_KEY){ //Si la tecla presionada es diferente a cero
       switch(i){ // evaluando valor de i
          case 0: // si i=0, guarda valor en variable temperatura2
           temperatura1 = presionada-48;
     lcd.print(temperatura1);
          break;
          case 1: // si i=1, guarda valor en variable temperatura2
           temperatura2 = presionada-48;
     lcd.print(temperatura2);
          break;
    }
  i++;
  }
}

  int temperatura = (temperatura1*10)+temperatura2;

  lcd.setCursor(0,0);
  lcd.print("Rango T: ");
  lcd.setCursor(8,0);
  lcd.print(temperatura);
  lcd.setCursor(10,0);
  lcd.write('C');
  delay (1000);

  lcd.setCursor(0,1);
  lcd.print("Rango H: ");

   while(i==2 || i==3){
    presionada = teclado.getKey();
    borrador();

     if(presionada!= NO_KEY){
        switch(i){
          case 2:
           humedad1 = presionada-48;
     lcd.print(humedad1);
          break;
          case 3:
           humedad2 = presionada-48;
     lcd.print(humedad2);
          break;
    }
  i++;
  }
}

  int humedad = (humedad1*10)+humedad2;

  lcd.setCursor(0,1);
  lcd.print("Rango H: ");
  lcd.setCursor(8,1);
  lcd.print(humedad);
  lcd.setCursor(10,1);
  lcd.write('%');
  delay (2000);
}

//Subrutina para Borrar;
void borrador(){
  presionada=teclado.getKey();
  if(presionada == '*'){
  switch(presionada){
    case 0:
    temperatura1 = " ";
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Rango T");
    break;
    case 1:
    temperatura2 = " ";
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Rango T");
    break;
    case 2:
    humedad1 = " ";
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("Rango H");
    break;
    case 3:
    humedad2 = " ";
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("Rango H");
    break;
  }
}
}
 
Atrás
Arriba