Go Down

Topic: Riego automatico (Read 160 times) previous topic - next topic

willydejoe

Jan 17, 2020, 01:41 pm Last Edit: Jan 18, 2020, 09:43 pm by surbyte Reason: Agregado de etiqueta para códigos/errores
Hola buenas tardes, tengo un sistema de riego con sensores de suelo capacitivos arduino y relés que manejan las microbombas, en total 6 canales con los relés configurados como ÑO ( normal open).
Mi código es simple pero después de muchos meses intentándolo no consigo que los reles corten a un tiempo que le programemos ejem. 10 seg.
Osea que solo riegue 10 seg. Descanse 15 seg. Y vuelva a la normalidad.
No tengo ni idea de programacion pero he conseguido que funcione aunque no como quisiera.
Soy mayor para esto (54) y nunca había tocado arduino

Code: [Select]
//Code//

int rainPin1 = A0;
int base1 = 5;
int rainPin2 = A1;
int base2 = 4;
int rainPin3 = A2;
int base3 = 3;
int rainPin4 = A3;
int base4 = 2;
int rainPin5 = A4;
int base5 = 6;
int rainPin6 = A5;
int base6 = 7;
int thresholdValue = 500;



void setup(){
Serial.begin(9600);  
pinMode(rainPin1, INPUT);
pinMode(base1, OUTPUT);
pinMode(rainPin2, INPUT);
pinMode(base2, OUTPUT);
pinMode(rainPin3, INPUT);
pinMode(base3, OUTPUT);
pinMode(rainPin4, INPUT);
pinMode(base4, OUTPUT);
pinMode(rainPin5, INPUT);
pinMode(base5, OUTPUT);
pinMode(rainPin6, INPUT);
pinMode(base6, OUTPUT);
digitalWrite(base1, LOW);
digitalWrite(base2, LOW);
digitalWrite(base3, LOW);
digitalWrite(base4, LOW);
digitalWrite(base5, LOW);
digitalWrite(base6, LOW);

}

void loop() {
int sensor1Value = analogRead(rainPin1);
Serial.print(sensor1Value);
if(sensor1Value < thresholdValue){
  Serial.println(" Plant 1 - No watering");
  digitalWrite(base1, HIGH);
}
else {
  Serial.println(" Plant 1 - Watering");
  digitalWrite(base1, LOW);
   
}

delay(500);
int sensor2Value = analogRead(rainPin2);
Serial.print(sensor2Value);
if(sensor2Value < thresholdValue){
  Serial.println(" Plant 2 - No watering");
  digitalWrite(base2, HIGH);
}
else {
  Serial.println(" Plant 2 - Watering");
  digitalWrite(base2, LOW);
}

delay(500);
int sensor3Value = analogRead(rainPin3);
Serial.print(sensor3Value);
if(sensor3Value < thresholdValue){
  Serial.println(" Plant 3 - No watering");
  digitalWrite(base3, HIGH);
}
else {
  Serial.println(" Plant 3 - Watering");
  digitalWrite(base3, LOW);
}

delay(500);
int sensor4Value = analogRead(rainPin4);
Serial.print(sensor4Value);
if(sensor4Value < thresholdValue){
  Serial.println(" Plant 4 - No watering");
  digitalWrite(base4, HIGH);
}
else {
  Serial.println(" Plant 2 - Watering");
  digitalWrite(base4, LOW);
}

delay(500);
int sensor5Value = analogRead(rainPin5);
Serial.print(sensor5Value);
if(sensor5Value < thresholdValue){
  Serial.println(" Plant 5 - No watering");
  digitalWrite(base5, HIGH);
}
else {
  Serial.println(" Plant 5 - Watering");
  digitalWrite(base5, LOW);
}

delay(500);
int sensor6Value = analogRead(rainPin6);
Serial.print(sensor6Value);
if(sensor6Value < thresholdValue){
  Serial.println(" Plant 6 - No watering");
  digitalWrite(base6, HIGH);
}
else {
  Serial.println(" Plant 6 - Watering");
  digitalWrite(base6, LOW);
}
delay(500);
}



Muchas gracias.

victorjam

Hola y bienvenido al foro.

Te invito a que te leas las NORMAS, a fin de que aprendas a postear correctamente tanto código, como imagenes, enlaces, errores, etc.

Además, indicarte que la sección de PROYECTOS es para enseñarnos tu proyecto acabado, o si no lo está, que sea al menos funcional.

Tu código presenta el típico problema de abuso del delay. En la sección de DOCUMENTACIÓN hay varios tutoriales para aprender a usar millis.

willydejoe

#2
Jan 17, 2020, 09:28 pm Last Edit: Jan 18, 2020, 02:37 am by willydejoe
Muchas gracias por las indicaciones.
Ya explique anteriormente que llevo mucho tiempo con esto
He leído mucho pero no consigo las combinaciones con millis y el valor del sensor.
Y como también explique qué soy mayor para esto,
Sólo busco una solución, la cual yo no sé darle.
De todas formas gracias.
Si alguien puede estaría agradecisimo.
Por favor si hay que cambiarlo de sitio en el foro, decidme cómo lo hago a si podeis vosotros mejor.

victorjam

No estoy de acuerdo. 54 años no es un impidimento para nada, solo hay que estar dispuesto a aprender y no desesperarse. No sé la edad de todos los miembros del foro, pero lo que si sé es que los "asiduos" estamos por encima de la cuarentena, mas bien cerca de la cincuentena y en algunos casos más.

Y aquí entra un problema: No hacemos código a nadie ¿por qué?

Primero por que el foro se llenaría de estudiantes que vendrían tan solo a que le hagamos el ejercicio que le ha puesto el profesor y lo tiene que entregar mañana. Y todos con prisas, muchas veces irrespetuosos, y cuando tienen el ejercicio hecho, ni colaboran, ni vuelven (mucho menos dar las gracias).

Segundo. Si hacemos código no aprendes. Y si no aprendes, cualquier código que te pasemos será inutil si no hace lo que tu deseas. Y lo que tu deseas algunas veces no lo sabes explicar.

Por ejemplo:

Code: [Select]

/*
 * Riego automático.
 *
 * (*)Asumo que estamos usando un "shield Relay" con lo para encender el relé
 * tendremos que poner un valor LOW. Igualmente, para apagar el relé hay que
 * llevarlo a estado HIGH.
 *
 * Vamos a necesitar un valor por cada zona de riego: pin del relé, pin del
 * ADC, valor del ADC, una variable de estado (regando o no) y un temporizador.
 *
 * Como tenemos varios sensores y el código es el mismo para cada uno, creo
 * todas las variables como un array o lista de elementos. Así solo hay que
 * recorrer la lista y solo escribir el código una vez.
 *
 * La idéa es la siguiente: regar significa encender el relé durante un tiempo (para
 * que eche agua), apagarlo y esperar un tiempo. Así que cuando estemos "regando"
 * significa que encenderemos el relé durante un tiempo de riego, una vez transcurrido
 * ese tiempo, seguimos regando, pero ahora comparamos con un tiempo de espera, que
 * al transcurrir dejaremos de "regar".
 *
 */
 
const int threshold = 500;                 // Variable que índica el valor del ADC para regar.
const int reles[6]={5,4,3,2,6,7};          // Pins de relé.
const int sensores[6]={A0,A1,A2,A3,A4,A5}; // Donde esta cada sensor
int valorSensor[6];                        // Valor del sensor.
unsigned long t[6];                        // Una variable de tiempo.
bool regando[6]={false, false, false, false, false, false}; // Para indicar si estamos regando.
const unsigned long tiempoRiego = 10000;   // Tiempo de riego.
const unsigned long tiempoPausa = 15000;   // Tiempo de pausa.

void setup() {
  Serial.begin(9600);
  // Inicializamos las salidas de los relés y los apagamos (*)
  for (int i=0; i<6; i++) {
    pinMode(reles[i],OUTPUT);
    digitalWrite(reles[i], HIGH);
  }
  Serial.print("riego");
}
void loop() {
  for (int i=0; i<6; i++) {
    // Leemos el valor de cada sensor. Si no está regando y el valor del ADC
    // es inferior, signfica que tenemos regar.
    valorSensor[i]=analogRead(sensores[i]);
    if ( valorSensor[i] < threshold && regando[i]==false ) {
      regando[i]=true;            // Decimos que vamos a regar.
      digitalWrite(reles[i],LOW); // Encedemos los relés.
      t[i]=millis();              // Guardamos el momento en el que lo hemos hecho.
      Serial.print(F("Regando: ")); Serial.println(i);
    }
  }
  for (int i=0; i<6; i++) {
    // Si estamos regando.
    if ( regando[i]==true ) {
      // Leemos el estado de la salida del relé.
      // Si el relé es LOW significa que está encendido y como estamos regando
      // hemos de comparar con el tiempo de riego.
      if ( digitalRead(reles[i])==LOW ) {
        if ( millis()-t[i] > tiempoRiego ) { // Comprobamos el tiempo de riego.
          digitalWrite(reles[i], HIGH); // Si ha pasado debemos apagar el relé.
          t[i]=millis(); // y guardamos el tiempo para hacer una "espera.
        }
      }
      else {
        // El relé no está encendido, así que seguimos "regando" pero ahora
        // estamos en el tiempo de espera.
        if ( millis()-t[i] > tiempoPausa ) {
          regando[i]=false; // Ya ha pasado el tiempo, así que dejamos de regar.
          Serial.print(F("No regando: ")); Serial.println(i);
        }
      }
    }
  }
}


Es el código que tu necesitas. Hace lo que querias. Compilado OK y simulación en proteus OK.

Ahora tu lo coges, copias y pegas, y por lo que sea no compila, o no es exactamente lo que querias, o si hace lo que quieres, pero te gustaria que hiciera otra cosa.

Sé que te va a sentar mal, lo que tu llevas meses pensando, lo he hecho en media hora tomando el café antes de irme a trabajar (pero no te enfades, llevo programando mas de 22 años). Pero si ahora no lo entediendes, ni sabes modificarlo, vendrás a que te ayudemos otra vez, y esa media hora se convierte en una hora. Multiplica por cuantos usuarios vienen con el mismo problema...

Con la tonteria de la parrafada te he dado una solución apróximada a tu programa. He intentado explicarlo como buenamente he podido y espero, al menos, que lo entiendas y comprendas el problema de hacer los programas de todos los que vienen al foro.


willydejoe

Victorjam
muchas gracias por la ayuda, no puedo explicar aquí los motivos de mi situación pero si deciros que he puesto todo mi empeño en yo mismo hacer mi código.
Mi trabajo a sido cocinero siempre, nunca tube tiempo para mis hobbies pero ahora toda mi dedicación por motivos de salud, es ha investigar este tipo de tecnologías y mis plantas.
Para mí esto significa más de lo que podáis imaginar.

Muchas gracias.

surbyte

#5
Jan 18, 2020, 09:56 pm Last Edit: Jan 18, 2020, 10:07 pm by surbyte
Que tal esta leve modificación de tu código

Code: [Select]
void loop() {
    
    leoSensor(1, rainPin1, base1);
    leoSensor(2, rainPin2, base2);
    leoSensor(3, rainPin3, base3);
    leoSensor(4, rainPin4, base4);
    leoSensor(5, rainPin5, base5);
    leoSensor(6, rainPin6, base6);
    delay(500);
}

void leoSensor(byte tmp, const byte pin, const byte pinout) {

    int tmpValue = analogRead(pin);
    Serial.print("Sensor " + String(tmp) + ":");
    Serial.println(tmpValue);
    Serial.println(" Plant " + String(tmp));
    if(tmpValue < thresholdValue){
      Serial.println("- No watering");
      digitalWrite(pinout, HIGH);
    }
    else {
      Serial.println("- watering");
      digitalWrite(pinout, LOW);
    }
}


Esta es otra versión que hace lo mismo un poco mas compacta

Code: [Select]
const byte rainPin[] = {A0, A1, A2, A3, A4, A5};
const byte base[] = {5, 4, 3, 2, 6, 7};
int thresholdValue = 500;
unsigned long startTime;


void setup(){
  Serial.begin(9600); 
  for (byte i= 0; i<6; i++)  {
      pinMode(rainPin[i], INPUT);
      pinMode(base[i], OUTPUT);
      digitalWrite(base[i], LOW);
  }
}

void loop() {

  for (byte i= 0; i<6; i++)  {
      leoSensor(i, rainPin[i], base[i]);
  }
  delay(500);
}

void leoSensor(byte tmp, const byte pin, const byte pinout) {

    int tmpValue = analogRead(pin);
    Serial.print("Sensor " + String(tmp) + ":");
    Serial.println(tmpValue);
    Serial.println(" Plant " + String(tmp));
    if(tmpValue < thresholdValue){
      Serial.println("- No watering");
      digitalWrite(pinout, HIGH);
    }
    else {
      Serial.println("- watering");
      digitalWrite(pinout, LOW);
    }
}

willydejoe

@victorjam
Muchas gracias, por el código, lo he  puesto en funcionamiento esta mañana pero solo obtenía un bucle de 10 seg ON Y 15 OFF , igual no me explique bien.
Necesito que funcione así pero solo si el sensor detecta que falta agua, si no, no ha de regar.
Tal y como lo escribió lo cargue en arduino y ya le digo que solo obtengo un bucle, todos se enciende 10 seg. luego se para 15 y vuelve a activarlos indefinidamente, los sensores estén en seco o en húmedo no influyen en ese bucle.
Aún así, de verdad que agradezco toda la ayuda que me dais,

@surbite
Esta tarde noche probaré lo que me has cedido,
Estoy un poco agotado,
No descanso apenas y aprovechar cuando el cuerpo me deja.
No tenéis idea de lo bueno que está siendo para mi el poder entretenerme con esto.

@ todos en general gracias por compartir.
Algunos de verdad que lo agradecemos.
Hace dos meses que estoy obsesionado con hacer esto funcionar y creo que con vuestra ayuda lo conseguiré.
Y si no, me queda el hecho que el que publique lo hice funcionar sin tener idea solo leer y leer hasta empezar a comprender código, pero aún no lo consigo hacer fino.
Seguro lo conseguiré.

victorjam

En esta parte del código se especifica que ha de regar si el valor es inferior al "threshold".

Code: [Select]

if ( valorSensor[i] < threshold && regando[i]==false ) {


A esto me referia con lo de hacer código. No se tu sensor, así que viendo tu código "deduje" que cuando el valor threshold bajaba de 500 era tierra seca. Quizás este funcione al reves: mayor sequedad, mayor valor; con lo que hay que cambiar el código por "valorSensor>threshold".  

Haciendo un poco de memoria vi que los sensores fc-28 funcionan al revés: a mayor sequedad mayor valor del ADC, por que hay que cambiar el signo de menor (<) a mayor (>)

willydejoe

#8
Jan 19, 2020, 08:03 pm Last Edit: Jan 20, 2020, 02:29 am by surbyte
Los sensores son
Soil Moisture capacitivos v 1.2 con valores entre 230 (húmedo) a 550 (seco).
En mis pruebas baje el valor máximo a 450 y así no esperaba al valor seco hasta 550 porque se quedaban muy secas las plantas.
La placa es una Arduino UNO R3
Los relés son una placa de 4 más una de dos con configuración Normal open
No sé si lo voy a postear bien los enlaces.

Sensor:

https://rover.ebay.com/rover/0/0/0?mpre=https%3A%2F%2Fwww.ebay.es%2Fulk%2Fitm%2F233440008171

Relés:

https://www.amazon.es/dp/B06Y3VR1P1/ref=cm_sw_r_other_apa_i_1AkjEb1QBY99S
Más una idéntica de 2.

Micro bombas de agua:

https://www.amazon.com/-/es/SUKRAGRAHA-Mini-Bomba-Microsumergible-Motor/dp/B07F8JV7CT/ref=mp_s_a_1_22?keywords=micro+water+pump&qid=1579462355&sr=8-22

Arduino ya sabemos todos original UNO R3.
Espero lo haya hecho bien.

victorjam

Entonces está claro. Hay que cambiar ese signo de menor a mayor < >.

Traducido al castellano esa parte de código: si el valor del sensor es menor que 500 y regando es falso entonces riega.

Pero como el sensor va al revés riega por qué menos de 500 es húmedo. Si cambias el menor por el mayor solo regara cuando el valor este por encima de 500, es decir, seco.

willydejoe

#10
Jan 20, 2020, 03:50 pm Last Edit: Jan 20, 2020, 05:19 pm by willydejoe
Victorjam

muchas gracias, acabo de probar el cambio de símbolo <> para el valor del sensor y todo ha funcionado perfectamente.
comprobé mil veces tu código y era muy lógico todo el desarrollo pero para mi utilizar esas combinaciones  no está a mí alcance, imagínate si no soy capaz de limitar el tiempo de un relé esto ahora mismo es impensable para mí.
pero me ha picado el gusanillo de arduino y creo que haré mas de un artilugio para casa.
La informática me gusta y hago cosillas pero siempre con ayuda de programas de terceros, desatendidos, autoinstalables etc, pero claro si no sabes programar te limitas a utilizar ayudas.
Gracias a todos y sin dudar que probare los otros solo por aprender.

Go Up