Mi primer proyecto riego

Buenas tardes chic@s, que tal?

Hace tiempo que postee por aquí mi idea para realizar un proyecto con Arduino, pero por cuestiones familiares no he podido remontar el tema hasta esta misma semana. Partiendo de un código que he encontrado por ahí, os pido que le echeis un vistazo para darme vuestra opinión. Aquí está el codigo:
+++++++++++++++++++++++++++++++++++++++++

/*Disposición de los pines en la LCD
GND: A tierra(GND)
Vcc: A 5 voltios
SDA: A la entrada analógica 4
SCL: A la entrada analógica 5
*/
//Primero incluimos las librerías:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
int humedad;//Valor de la humedad actual de la planta
int humedadcorte;//Humedad que fija el usuario girando el potenciómetro.
int control=8;//Pin que activa o no el relé
void setup()
{
lcd.init();//Inicia la LCD
lcd.backlight();//Activa la luz de la LCD.
pinMode(control,OUTPUT);//Declara el control del relé como salida 4
}
void loop()
{
//Para que el sistema convierta la lectura analógica en % hay que establecer una relación:
humedad=0.12*analogRead(0);//Convierte la lectura del sensor a %.
humedadcorte=0.07*analogRead(1)+15;//Convierte la lectura del potenciómetro a %. La humedad se ajusta entre un 15 y 90 por ciento.
/*El siguiente bloque imprime en la pantalla
el valor de la humedad que lee el sensor, y el
de la humedad de corte leída por el potenciómetro*/
lcd.setCursor(0,0);
lcd.print("HUM. PLANTA:");
lcd.setCursor(12,0);
lcd.print(humedad);
lcd.setCursor(15,0);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("HUM. CORTE:");
lcd.setCursor(12,1);
lcd.print(humedadcorte);
lcd.setCursor(15,1);
lcd.print("%");
if(humedad<10)
{
digitalWrite(control,HIGH);
}
else if(humedad>humedadcorte)
{
digitalWrite(control,LOW);
}
delay(1000);
lcd.clear();
}

++++++++++++++++++++++++++++++++++++++++++++++++++++

Que os parece?

+Por otro lado, me surgen dudas porque tuve problemas para implementar la libreria nueva del display ya que me daba error al compilar. El problema que tengo con el display es que a la hora de poder adquirirlo por internet, me surgen dudas para saber cual es, ya que tengo entendido que el protocolo o conexionado es diferente a otros y tengo miedo por comprar el equivocado.
+Tengo dudas para realizar el conexionado porque sería el primero que haría fisicamente como proyecto. Hay alguna forma o algún simulador antes de realizar las conexiones?
+Alguna tienda fiable (fiscamente en MADRID) o en internet para realizar la compra de los elementos??

Muchas gracias y prometo subir un video para vosotros.

Porque no lees en el foro Proyectos el Hilo Cultivo Autónomo y te nutres de lo que hiddenNotebook ha hecho hasta ahora similar al tuyo en algunos aspectos.
Tienes que leer el foro antes de preguntar.
Todo lo que preguntas esta respondido en muchos hilos similares.

Gracias¡¡¡ Lo miraré entonces....

:slight_smile: :slight_smile:

Bueno.... Pues como me comenta Surbyte, expongo el código de mi primer proyecto. Que os parece?? Es coherente??
Muchas gracias a todos!!

/*Disposición de los pines en la LCD
GND: A tierra(GND)
Vcc: A 5 voltios
SDA: A la entrada analógica 4
SCL: A la entrada analógica 5
*/
//Primero incluimos las librerías:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
int sensorPin = 8;
int relePin = 9;
int botonManualPin = 11;
int sensor = 0;
int manual = 0;
int a = 0;
int humedad;//Valor de la humedad actual de la planta
int humedadcorte;//Humedad que fija el usuario girando el potenciómetro.
int control=9;//Pin que activa o no el relé

void setup()
{
Serial.begin(9600);
pinMode(sensorPin, INPUT);
pinMode(relePin, OUTPUT);
pinMode(botonManualPin, INPUT);
lcd.init();//Inicia la LCD
lcd.backlight();//Activa la luz de la LCD.
pinMode(control,OUTPUT);//Declara el control del relé como salida 4
}
void loop()
{
sensor = digitalRead(sensorPin);
manual = digitalRead(botonManualPin);
//Serial.println(digitalRead(8)); //lectura digital
//delay(500);
if(sensor == HIGH || manual == HIGH){
  digitalWrite(relePin, HIGH);
  for(a=1;a<=120;a++){ //Regamos durante dos minutos      
  }
}
//Para que el sistema convierta la lectura analógica en % hay que establecer una relación:
humedad=0.12*analogRead(0);//Convierte la lectura del sensor a %.
humedadcorte=0.07*analogRead(1)+15;//Convierte la lectura del potenciómetro a %. La humedad se ajusta entre un 15 y 90 por ciento.
/*El siguiente bloque imprime en la pantalla
el valor de la humedad que lee el sensor, y el
de la humedad de corte leída por el potenciómetro*/
lcd.setCursor(0,0);
lcd.print("HUM. PLANTA:");
lcd.setCursor(12,0);
lcd.print(humedad);
lcd.setCursor(15,0);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("HUM. CORTE:");
lcd.setCursor(12,1);
lcd.print(humedadcorte);
lcd.setCursor(15,1);
lcd.print("%");
if(humedad<10)
{
digitalWrite(control,HIGH);
}
else if(humedad>humedadcorte)
{
digitalWrite(control,LOW);
}
delay(1000);
lcd.clear();

Te presento el programa con cambios sutiles que introducen elementos que hacen mas fácil ubicar las cosas dentro del lcd, como es la función sprintf. Buscala como Arduino sprintf en google.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

const byte sensorPin = 8;
const byte relePin = 9;
const byte control = 9;				//Pin que activa o no el relé
const byte botonManualPin = 11;
bool sensor = 0;
bool manual = 0;
int a = 0;
float humedad;				//Valor de la humedad actual de la planta
float humedadcorte;			//Humedad que fija el usuario girando el potenciómetro.


void setup() {
	Serial.begin(9600);

	pinMode(sensorPin, INPUT);
	pinMode(relePin, OUTPUT);
	pinMode(botonManualPin, INPUT);
	lcd.init();				//Inicia la LCD
	lcd.backlight();		//Activa la luz de la LCD.
	pinMode(control,OUTPUT);//Declara el control del relé como salida 4
}

void loop() {
    char buffer[20];
	sensor = digitalRead(sensorPin);
	manual = digitalRead(botonManualPin);
	//Serial.println(digitalRead(8)); //lectura digital
	//delay(500);
	if (sensor == HIGH || manual == HIGH){
	   digitalWrite(relePin, HIGH);
	   for(a=1;a<=120;a++){ //Regamos durante dos minutos   ????   
	   	// DUDO que esto sea cierto
	   }
	}

	//Para que el sistema convierta la lectura analógica en % hay que establecer una relación:
	
	humedad = 0.12*analogRead(A0);					//Convierte la lectura del sensor a %.
	humedadcorte =0.07*analogRead(A1)+15;			//Convierte la lectura del potenciómetro a %. La humedad se ajusta entre un 15 y 90 por ciento.

	/*El siguiente bloque imprime en la pantalla
	el valor de la humedad que lee el sensor, y el
	de la humedad de corte leída por el potenciómetro*/
	
	lcd.setCursor(0,0);
	sprintf(buffer, "HUM. PLANTA:%3d%", humedad)
	lcd.print(buffer);
	lcd.setCursor(0,1);
	sprintf(buffer, "HUM. CORTE :%3d%", humedadcorte)
	lcd.print(buffer);
	
	if (humedad < 10) {
		digitalWrite(control,HIGH);
	}
	if (humedad>humedadcorte) {
       	digitalWrite(control,LOW);
	}
	delay(1000);
}

Yo no definiría como tu humedad yhumedadcorte como enteros ya que luego haces multiplicaciones x decimales.
Creo que esas cuentas no se realizarán correctamente.
Lo que haría es definir humedad y humedadcorte como float y luego hay que trabajar un poco para presentarlos.

Sencillamente genial!!

Muchas gracias por el aporte.

Dudas: Como puedo hacer entonces para que riegue durante 2 minutos accionando el mando manual? Porque donde expresas que dudas de que funcione esa expresión..... :slight_smile: :slight_smile:

Estoy muy verde... Lo sé!!

Por otro lado me viene el problema del ensamble físico!! En eso sí que estoy perdido la verdad!! Hay algún simulador por soft y tal que me permita hacer comprobaciones?? O tiene que ser si o si a través de una placa de conexiones?? Lo digo para no cagarla. Jejejeje

Gracias una vez más por la ayuda prestada!! :slight_smile: :slight_smile:

Bueno, para el tema de los dos minutos lee el ejemplo BlinkWithoutDelay.ino que usa millis();
millis() es un cronómetro en milisegundos que lleva la cuenta del tiempo de encendido del arduino hasta los 49.7 dias.
Entonces si tu tomas un parcial con el valor en un instante t1 y luego lo restas del valor de millis() en otro instante tienes un tiempo X por ejemplo 2 minutos = 2000 milisegundos.
Eso complica las cosas pero tiene grandes ventajes.
Como las complica?
Que tu debes establecer que evento quieres usar como inicio de tu control de tiempo.
En tu caso, cuando el boton pase a Manual? o pase a automático? Te los pongo con signo de interrogación porque Manual esta claro, pero automático no.

Veamos manual.
si tu haces que el evento se inicio con manual == HIGH y luego cuentas 2000 milegundos que pasará cuando transcurran 2001 milisegundos? Pues de nuevo se va a activar todo.
Entonces con manual==HIGH no alcanza.
Lo que se suele hacer es ver el cambio de 0 a 1 de ese boton o pulsador. De LOW a HIGH
y por esa razón se declara otra variable con el valor anterior del pulsador.
Entonces cuando la variable anterior este en 0 y la variable manual este en 1, tendras tu condición.

millis() requiere variables del tipo unsigned long asi que
tendras que definir estas variables globales antes del setup()

unsigned long start;
bool manual = false;
bool manualAnterior = false;
bool Riego = false;

esto detecta la situación incial

if (manual == HIGH && manualAnterior ==LOW) {
    start = millis();                                   // Tomo el instante inicial del cronómetro
    Riego = true;                                     // habilito la función Riego
  digitalWrite(relePin, HIGH);  // incio el riego
}
manualAnterior = manual;

if (Riego && (millis()-start)> 2000) ) {
   digitalWrite(relePin, LOW);  // apago el riego
 Riego = false; // con esto detengo que pueda entrar en este if
}

Genial!! :slight_smile:

Aver si me aclaro ahora....

Entiendo el razonamiento que me das de usar este sistema pero me surge alguna duda:
Si no entiendo mal y corrígeme si me equivoco.... Si pasan esos 49,7 días sin que yo accione dicho botón... Que ocurriría?? Entiendo que si yo acciono dicho botón, ese contador lo reseteo, no??

Por otro lado, este ejemplo solo afecta al modo manual, no? No intervendria con el modo automático, no?

Perdona por las preguntas, porque a lo mejor no tienen mucho sentido... Entiendo el razonamiento pero esta noche cuando llegue de currar lo estudiaré más a fondo.

Por otro lado y ya se que es abusar, en referencia al ensamblado físico, hay algún simulador por software? O hay que hacerlo siempre desde el principio desde una placa de conexiones?? Lo digo para no cargarme nada. Je je je je.

Muchas gracias Surbyte.... Eres un crack!!

Saludos a todos!

Si no entiendo mal y corrígeme si me equivoco.... Si pasan esos 49,7 días sin que yo accione dicho botón... Que ocurriría?? Entiendo que si yo acciono dicho botón, ese contador lo reseteo, no??

No pasa nada.

El módo automático no se como quieres que funcione.
Regar 2 minutos según que criterio, porque 2 minutos... y si no alcanza el umbral de corte?
Tienes un error de criterio creo yo.

Por cierto.. no soy ningún crack. Se algo mas por aprender con y de Uds. y tener alguna mejor formación. Solo eso. Nada que no puedan alcanzar Uds en un tiempo.

Simulador hay varios y estan documentados en Documentación.

Mi criterio es el siguiente,

Mi idea es con el potenciómetro regular voluntariamente el umbral de corte en modo automático.... Es decir... Ajustarlo a cuando yo quiera.... Unas veces al 85% o al 60% por poner un ejemplo. Me explico?? Cuando llegue a dicho valor... Pues que corte la bomba.

Por otro lado, los dos minutos son orientativos, es decir, si por algún casual quiero activar voluntariamente el riego, pues hacerlo durante un determinado tiempo independientemente del modo automático. Es decir, si en modo automático no riega porque esta dentro de valores la humedad, si yo quiero regar voluntariamente, pues acción el pulsador y que riegue durante 2 minutos o 5 por poner un ejemplo...

Espero que me haya explicado.

Respecto a lo otro del simulador.... Ahora mismo lo miro.

Muchas gracias por la ayuda y paciencia!!

Bien, en automático entonces deberia regar siempre que este por encima de 10 y por debajo del umbral
y en manual por 2 o X minutos.
Estoy de acuerdo.
Trabaja el código. Vamos a jugar y divertirse.
Seria bueno que lo vayas armando... y viendo como se porta.
En lugar de bomba conectas un led.
Conectas los pulsadores de Manual Automático y dos potenciometro para simular el de humedad de suelo y el de corte (bueno ese no lo simulas).
Haszlo asi que ganarás en tiempo mas que con el simulador.

surbyte:
Bien, en automático entonces deberia regar siempre que este por encima de 10 y por debajo del umbral
y en manual por 2 o X minutos.
Estoy de acuerdo.
Trabaja el código. Vamos a jugar y divertirse.
Seria bueno que lo vayas armando... y viendo como se porta.
En lugar de bomba conectas un led.
Conectas los pulsadores de Manual Automático y dos potenciometro para simular el de humedad de suelo y el de corte (bueno ese no lo simulas).
Haszlo asi que ganarás en tiempo mas que con el simulador.

El valor de 10 lo puse a boleo....
A lo mejor no me he explicado bien... O no lo he plasmado bien... Debe de regar en automático si la humedad es inferior al 25% (x ejemplo) hasta llegar a la que yo seleccione con el potenciómetro (dicese por ejemplo 90... Y en manual debe de regar independientemente de la humedad que haya por el tiempo que le ponga...

No se si me explico...

Por otro lado... Haré lo que me dices entonces.... Te mantendré informado :-):-).

Mil gracias

Eso lo decides tu.
Espero que con la guia intentes hacer tu proyecto y en el proceso aprendas

Bueno.... Después de solucionar mi problema con la lcd, tema tratado en otro hilo, al disponerme a compilar el código (gracias Surbyte), me surge un problema.

Al conectar la lcd y conectar debidamente el sensor de humedad de suelo, para ver si se refleja bien la lectura en el lcd y se imprime bien los caracteres... La lcd se enciende y se apaga continuamente... Es como si entrara en bucle continuo y solo se enciende la iluminación y se apaga :-(.
Porque puede pasar? De hecho es que no aparece ningún dígito en la lcd...

PD. La pantalla esta probada con una prueba con unos textos que le mandé y funcionaba perfectamente.

Mil gracias

Tienes muchos lcd.clear() que borran pantalla. Verifica usarlos cuando corresponda.

Muchos??? Si tenía uno y lo he borrado, pero sigue igual..... Algo se me está escapando.... Pero revisando el codigo, no veo ninguno mas.

Gracias.

Me perdí con tu código y mis correcciones. No se cual es el que corresponde ahora.

Aqui te lo dejo compi

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27);

const byte sensorPin = 8;
const byte relePin = 9;
const byte control = 9;        //Pin que activa o no el relé
const byte botonManualPin = 11;
bool sensor = 0;
bool manual = 0;
int a = 0;
float humedad;        //Valor de la humedad actual de la planta
float humedadcorte;     //Humedad que fija el usuario girando el potenciómetro.


void setup() {
  
  Serial.begin(9600);

  pinMode(sensorPin, INPUT);
  pinMode(relePin, OUTPUT);
  pinMode(botonManualPin, INPUT);
  lcd.begin(20,4);       //Inicia la LCD
  
  //lcd.backlight();    //Activa la luz de la LCD.
  pinMode(control,OUTPUT);//Declara el control del relé como salida 4
  Serial.println("Arrancando LCD I2C.");
}

void loop() {
  char buffer[20];
  
  sensor = digitalRead(sensorPin);
  manual = digitalRead(botonManualPin);
  //Serial.println(digitalRead(8)); //lectura digital
  //delay(500);
  if (sensor == HIGH || manual == HIGH){
     digitalWrite(relePin, HIGH);
     for(a=1;a<=120;a++){ //Regamos durante dos minutos   ????   
      // DUDO que esto sea cierto
     }
  }

  //Para que el sistema convierta la lectura analógica en % hay que establecer una relación:
  
  humedad = 0.12*(float) analogRead(A0);          //Convierte la lectura del sensor a %.
  humedadcorte =0.07*(float)analogRead(A1)+15.0;     //Convierte la lectura del potenciómetro a %. La humedad se ajusta entre un 15 y 90 por ciento.

  /*El siguiente bloque imprime en la pantalla
  el valor de la humedad que lee el sensor, y el
  de la humedad de corte leída por el potenciómetro*/
  
  lcd.setCursor(0,0);
  sprintf(buffer, "HUM. PLANTA:%3d%", humedad);
  lcd.print(buffer);
  lcd.setCursor(0,1);
  sprintf(buffer, "HUM. CORTE :%3d%", humedadcorte);
  lcd.print(buffer);
  
  if (humedad < 10.0) {
    digitalWrite(control,HIGH);
  }
  if (humedad > humedadcorte) {
        digitalWrite(control,LOW);
  }
  delay(1000);
}

en tu código veo que inicializas con

  lcd.begin(16,2);       //Inicia la LCD

en el mio

  lcd.begin(20,4);       //Inicia la LCD

tu díras cual corresponde.

Ya tengo el codigo funcionando. He realizado el montaje primero con un led, y a posteriori con un relé simulando la activación de la bomba sumergible. Todo funciona ok¡¡¡ Por fin¡¡¡ :slight_smile: :slight_smile: :slight_smile:

/*Disposición de los pines en la LCD
GND: A tierra(GND)
Vcc: A 5 voltios
SDA: A la entrada analógica 4
SCL: A la entrada analógica 5
*/
//Primero incluimos las librerías:
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR       0x27
LiquidCrystal_I2C           lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);

float humedad;//Valor de la humedad actual de la planta
float humedadcorte;//Humedad que fija el usuario girando el potenciómetro.
float temperatura;
int control=8;//Pin que activa o no el relé
int sensorPin = 2;
int sensorValue = 2;

void setup()

{
lcd.begin(20,4);//Inicia la LCD
lcd.setBacklightPin(3,POSITIVE);//Activa la luz de la LCD.
lcd.setBacklight(HIGH);
pinMode(control,OUTPUT);//Declara el control del relé como salida
}

void loop()

{
   lcd.setCursor(0,1);
   lcd.print("Temperatura:");
   sensorValue = analogRead(sensorPin); //conversor analògic-digital. 0=0v; 1024=5V
   //T=0,48*ADC-112,36 (veure wiki per saber com he arribat a aquest resultat)
   temperatura=0.48*sensorValue-385.5;
   lcd.setCursor(14,1);
   lcd.print(temperatura);
   lcd.print((char)223);
   delay(100);

//Para que el sistema convierta la lectura analógica en % hay que establecer una relación:
humedad=0.14*(float)analogRead(A0);//Convierte la lectura del sensor a %.
humedadcorte=0.07*(float)analogRead(A1)+25.0;//Convierte la lectura del potenciómetro a %. La
//humedad se ajusta entre un 15 y 90 por ciento.
/*El siguiente bloque imprime en la pantalla
el valor de la humedad que lee el sensor, y el
de la humedad de corte leída por el potenciómetro*/

lcd.setCursor(1,0);
lcd.print("RIEGO AUTOMATIZADO");
lcd.setCursor(0,2);
lcd.print("Hum.Planta:");
lcd.setCursor(15,2);
lcd.print(humedad);
lcd.setCursor(19,2);
lcd.print("%");
lcd.setCursor(0,4);
lcd.print("Hum.Corte:");
lcd.setCursor(15,4);
lcd.print(humedadcorte);
lcd.setCursor(19,4);
lcd.print("%");
if(humedad<30)
{
digitalWrite(control,HIGH);
}
else if(humedad>humedadcorte)
{
digitalWrite(control,LOW);
}

delay(1000);
}

Pero me surgen unas dudas.
Registro la temperatura con un sensor LM335, pero creo que no me mide bien la temperatura. Que puede ser??
Y por ultimo, cuando se realiza la activación del relé, la pantalla baja de brillo, como si bajara un tono la intensidad. Y cuando vuelve a descativarse, todo vuelve a la normalidad.Es como si hubiese un consumo excesivo, o no se...

Que puede suceder??

Muchas gracias por la ayuda prestada