meta data de esta página
  •  

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Próxima revisión
Revisión previa
electronica:arduino:lcd [2016/07/31 22:24] – creado lcelectronica:arduino:lcd [2023/01/18 14:36] (actual) – editor externo 127.0.0.1
Línea 1: Línea 1:
-===== Añadir LCD =====+{{tag>arduino lcd}} 
 +===== 3 . Añadir LCD ===== 
 +Continuamos con nuestro proyecto y ahora vamos a añadirle un LCD del tipo [[http://www.prometec.net/producto/lcd-keypad/|LCD KEY PAD SHIELD]] de 16x2 líneas 
 +{{ :electronica:arduino:lcd16x2.png?300 |}} 
 +Este tipo de LCD ya viene preparada para conectar directamente encima del arduino Uno o del Mega, pero en nuestro caso al utilizar el nano  
 +tenemos que hacer las conexiones siguientes: 
 +<note>Se ha cambiado la lectura del sensor DHT al A1 para dejar el A0 para los botones del LCD</note> 
 +{{ :electronica:arduino:sensor_lcd_bb.png?600 |}} 
 + 
 +El esquema de conexión sería: 
 + 
 +^ LCD  ^ Arduino Nano  ^ 
 +| A0   | A0            | 
 +| D4   | D4            | 
 +| D5   | D5            | 
 +| D6   | D6            | 
 +| D7   | D7            | 
 +| D8   | D8            | 
 +| D9   | D9            | 
 + 
 +El código: 
 +<sxh javascript> 
 +//// wiki.intrusos.info 
 +// modificación del código de http://webdelcire.com/wordpress/archives/2471 
 + 
 + 
 + 
 +//---------------------------Sensor DHT ------------------------------------------------ 
 +#include "DHT.h" // Libreria para Sensores DHT 
 +#define DHTPIN 2     // Pin del Arduino al cual esta conectado el pin 2 del sensor 
 +// Descomentar segun el tipo de sensor DHT usado 
 +#define DHTTYPE DHT11   // DHT 11  
 +DHT dht(DHTPIN, DHTTYPE);// Inicializa el sensor 
 + 
 +//---------------LCD --------------------------------------------------------------------- 
 +#include <LiquidCrystal.h>  //Libreria LCD 
 +// Inicializa el objeto LCD con los pines de la interfaz 
 +LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 
 + 
 +// Pines digitales 
 +byte pinLedVerde = 10; 
 +byte pinLedRojo = 11; 
 +byte pinMotor = 12; 
 + 
 +// Pines analógicos 
 +byte pinSensorHumedad = 1; 
 + 
 +// definición teclado 
 +int lcd_key     = 0; 
 +int adc_key_in  = 0; 
 +#define btnRIGHT 
 +#define btnUP     1 
 +#define btnDOWN   2 
 +#define btnLEFT   3 
 +#define btnSELECT 4 
 +#define btnNONE   5 
 + 
 +// Constantes para los posibles modos de funcionamiento 
 +byte MODO_TIEMPO_HUMEDAD = 0; 
 +byte MODO_SOLO_TIEMPO = 1; 
 +byte MODO_SOLO_HUMEDAD = 2; 
 + 
 + 
 +int modoElegido = 0; // Modo de funcionamiento 
 + 
 +int umbralHumedad = 0; // Umbral de humedad seleccionado para empezar a regar 
 + 
 +int diasTemporizacion = 0; 
 +int horasTemporizacion = 0; 
 +int minutosTemporizacion = 0; 
 + 
 +int duracionRiego = 0; // Duración del riego en segundos una vez alcanzado el evento de activación 
 + 
 +String linea1; // Contenido para la línea superior del display 
 +String linea2; // Contenido para la línea inferior del display 
 + 
 +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]; // Ultimas 10 lecturas del sensor para hacer la media 
 +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 
 + 
 +int read_LCD_buttons();  // para leer los botones 
 + 
 +int read_LCD_buttons() 
 +{ adc_key_in = analogRead(0);      // Leemos A0 
 +  if (adc_key_in > 900)  return btnNONE;     // Ningun boton pulsado 
 +  if (adc_key_in < 50)   return btnRIGHT; 
 +  if (adc_key_in < 200)  return btnUP; 
 +  if (adc_key_in < 400)  return btnDOWN; 
 +  if (adc_key_in < 600)  return btnLEFT; 
 +  if (adc_key_in < 800)  return btnSELECT; 
 +  return btnNONE;  // Por si todo falla 
 +
 + 
 + 
 +//----------------------------------inicio setup ---------------------------------- 
 +void setup() 
 +
 +   
 +  // Inicializa el número de columnas y filas del LCD 
 +  lcd.begin(16, 2); 
 + 
 +  // Establece a modo salida los pines para controlar la bomba y los led de señalización 
 +  pinMode(pinMotor,OUTPUT); 
 +  pinMode(pinLedRojo,OUTPUT); 
 +  pinMode(pinLedVerde,OUTPUT); 
 + 
 +  // Activa el led rojo y muestra la pregunta sobre el modo en el que va a funcionar 
 +  digitalWrite(pinLedRojo, HIGH); 
 +  mostrarPregunta(modoElegido); 
 + 
 +  // Pregunta por el modo de funcionamiento: tiempo + humedad, sólo tiempo o sólo humedad 
 +  boolean respuesta = false; 
 +  while (!respuesta) 
 +  { 
 +    lcd_key = read_LCD_buttons(); 
 +    delay(200);  //para evitar lecturas seguidas 
 +    if ( lcd_key == btnDOWN) 
 +    { 
 +      modoElegido--; 
 +      if (modoElegido == -1) modoElegido = 2; 
 +      mostrarPregunta(modoElegido); 
 +    } 
 +    else if ( lcd_key == btnUP) 
 +    { 
 +      modoElegido++; 
 +      if (modoElegido == 3) modoElegido = 0; 
 +      mostrarPregunta(modoElegido); 
 +    } 
 +    else if ( lcd_key == btnSELECT) 
 +    { 
 +      respuesta = true; 
 +    } 
 +  } 
 + 
 + 
 +  // Si el modo elegido incluye riego por tiempo, pregunta cada cuantos días, horas y minutos 
 +  if (modoElegido == MODO_TIEMPO_HUMEDAD || modoElegido == MODO_SOLO_TIEMPO) 
 +  { 
 +    // No permite elegir un tiempo cero 
 +    while (diasTemporizacion + horasTemporizacion + minutosTemporizacion == 0) 
 +    { 
 +      diasTemporizacion = preguntarValor("Numero de dias:", 0, 30); 
 +      horasTemporizacion = preguntarValor("Numero de horas:", 0, 23); 
 +      minutosTemporizacion = preguntarValor("Numero minutos:", 0, 59); 
 +    } 
 + 
 +    // Muestra un resumen del tiempo elegido 
 +    linea1 = "  DD : HH : MM"; 
 +    linea2 = "  " + str(diasTemporizacion) + " : " + str(horasTemporizacion) + " : " + str(minutosTemporizacion); 
 +    mostrarTexto(); 
 +    delay(1000); 
 +  } 
 + 
 +  // Si el modo elegido incluye riego por sensor de humedad, pregunta cual es el umbral de humedad para regar 
 +  if (modoElegido == MODO_TIEMPO_HUMEDAD || modoElegido == MODO_SOLO_HUMEDAD) 
 +  { 
 +    umbralHumedad = preguntarValor("Umbral humedad:", 40, 99); 
 +  } 
 + 
 +  // Pregunta cuantos segundos deberá durar el riego cuando se active 
 +  duracionRiego = preguntarValor("Duracion riego:", 15, 300); 
 + 
 +  // Finalizada la programación desactiva el led rojo y activa el verde 
 +  digitalWrite(pinLedRojo, LOW); 
 +  digitalWrite(pinLedVerde, HIGH); 
 +
 + 
 + 
 +void loop() 
 +
 +  // inicializa las variables de tiempo para el riego por temporización 
 +  int diasPendientes = diasTemporizacion; 
 +  int horasPendientes = horasTemporizacion; 
 +  int minutosPendientes = minutosTemporizacion; 
 +  int segundosPendientes = 0; 
 + 
 +  if (modoElegido == MODO_TIEMPO_HUMEDAD) 
 +  { 
 +    // Continua el bucle hasta que el tiempo llegue a cero 
 +    while ((diasPendientes + horasPendientes + minutosPendientes + segundosPendientes) > 0) 
 +    { 
 +      // Espera un segundo y decrementa las variables el equivalente a un segundo 
 +      delay(987); 
 +      segundosPendientes--; 
 +      if (segundosPendientes == -1) 
 +      { 
 +        segundosPendientes = 59; 
 +        minutosPendientes--; 
 +      } 
 +      if (minutosPendientes == -1) 
 +      { 
 +        minutosPendientes = 59; 
 +        horasPendientes--; 
 +      } 
 +      if (horasPendientes == -1) 
 +      { 
 +        horasPendientes = 23; 
 +        diasPendientes--; 
 +      } 
 + 
 +      // Actualiza la variable con la humedad actual 
 +      leerHumedad(); 
 + 
 +      // Actualiza el display con el tiempo hasta el siguiente riego y la humedad actual 
 +      linea1 = str(diasPendientes) + ":" + str(horasPendientes) + ":" + str(minutosPendientes) + ":" + str(segundosPendientes); 
 +      linea2 = "Humedad:" + str(mediaHumedad) + "\x25" + " [" + str(umbralHumedad) + "]"; 
 +      mostrarTexto(); 
 + 
 +      // Si la media de humedad de las últimas 10 lecturas está lista y es inferior al umbral configurado, activa el riego 
 +      if ((mediaHumedad < umbralHumedad) && mediaLista) 
 +      { 
 +        regar(); 
 +        // Reinicia la media de humedad para que le tiempo a la tierra a empaparse 
 +        indiceLecturasHumedad = 0; 
 +        mediaLista = false; 
 +      } 
 +    } 
 + 
 +    // Activa lo bomba de riego durante el tiempo configurado 
 +    regar(); 
 +  } 
 +  else if (modoElegido == MODO_SOLO_TIEMPO) 
 +  { 
 +    // Continua el bucle hasta que el tiempo llegue a cero 
 +    while ((diasPendientes + horasPendientes + minutosPendientes + segundosPendientes) > 0) 
 +    { 
 +      delay(990); 
 +      segundosPendientes--; 
 +      if (segundosPendientes == -1) 
 +      { 
 +        segundosPendientes = 59; 
 +        minutosPendientes--; 
 +      } 
 +      if (minutosPendientes == -1) 
 +      { 
 +        minutosPendientes = 59; 
 +        horasPendientes--; 
 +      } 
 +      if (horasPendientes == -1) 
 +      { 
 +        horasPendientes = 23; 
 +        diasPendientes--; 
 +      } 
 + 
 +      // Actualiza el display con el tiempo hasta el siguiente riego 
 +      linea1 = "Proximo riego:"; 
 +      linea2 = str(diasPendientes) + ":" + str(horasPendientes) + ":" + str(minutosPendientes) + ":" + str(segundosPendientes); 
 +      mostrarTexto(); 
 +    } 
 + 
 +    // Activa lo bomba de riego durante el tiempo configurado 
 +    regar(); 
 +  } 
 +  else if (modoElegido == MODO_SOLO_HUMEDAD) 
 +  { 
 +    while (true) 
 +    { 
 +      delay(1000); 
 + 
 +      // Actualiza la variable con la humedad actual 
 +      leerHumedad(); 
 + 
 +      // Actualiza el display con la humedad actual y el número de riegos efectuados hasta el momento 
 +      linea1 = "Humedad: " + str(mediaHumedad) + "\x25" + " [" + str(umbralHumedad) + "]";  // \x25 es el símbolo ascii de % 
 +      linea2 = "Riegos: " + str(riegos); 
 +      mostrarTexto(); 
 + 
 +      // Si la media de humedad de las últimas 10 lecturas está lista y es inferior al umbral configurado, activa el riego 
 +      if ((mediaHumedad < umbralHumedad) && mediaLista) 
 +      { 
 +        regar(); 
 +        // Reinicia la media de humedad para que le tiempo a la tierra a empaparse 
 +        indiceLecturasHumedad = 0; 
 +        mediaLista = false; 
 +      } 
 +    } 
 +  } 
 +
 + 
 + 
 +// Pregunta el modo de funcionamiento con la última opción elegida 
 +void mostrarPregunta(byte modo) 
 +
 +  lcd.clear(); 
 +  lcd.print("Modo de riego?"); 
 +  lcd.setCursor(0, 1); 
 +  if (modo == MODO_TIEMPO_HUMEDAD) lcd.print("Tiempo + Humedad"); 
 +  else if (modo == MODO_SOLO_TIEMPO) lcd.print("Solo Tiempo"); 
 +  else if (modo == MODO_SOLO_HUMEDAD) lcd.print("Solo Humedad"); 
 +
 + 
 +// Muestra el texto configurado en el display 
 +void mostrarTexto() 
 +
 +  lcd.clear(); 
 +  lcd.print(linea1); 
 +  lcd.setCursor(0, 1); 
 +  lcd.print(linea2); 
 +
 + 
 + 
 +// Muestra una pregunta y recoge un valor numérico 
 +int preguntarValor(String texto, int inicial, int maximo) 
 +
 +  linea1 = texto; 
 +  linea2 = str(inicial); 
 +  mostrarTexto(); 
 +  boolean respuesta = false; 
 +  int valor = inicial; 
 +  while (!respuesta) 
 +  { 
 +    lcd_key = read_LCD_buttons(); 
 +    delay(200); //para evitar lecturas seguidas 
 +    if ( lcd_key == btnDOWN) 
 +    { valor--; 
 +      if (valor == -1) valor = maximo; 
 +      linea2 = str(valor); 
 +      mostrarTexto(); 
 +    } 
 + 
 +    else if ( lcd_key == btnUP) 
 +    { 
 +      valor++; 
 +      if (valor > maximo) valor = 0; 
 +      linea2 = str(valor); 
 +      mostrarTexto(); 
 +    } 
 + 
 +    else if ( lcd_key == btnSELECT) 
 +    { 
 +      respuesta = true; 
 +    } 
 +  } 
 +  return valor; 
 +
 + 
 +// 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 "0" + String(valor); 
 +  else return (String(valor)); 
 +
 + 
 + 
 +// Actualiza la variable con la media de humedad de las últimas 10 lecturas 
 +void leerHumedad() 
 +
 +  lecturasHumedad[indiceLecturasHumedad] = analogRead(pinSensorHumedad); 
 +  lecturasHumedad[indiceLecturasHumedad] = map (lecturasHumedad[indiceLecturasHumedad], 0, 1023, 100, 0); // Mapeamos el valor del sensor de 0 a 100 
 +  indiceLecturasHumedad++; 
 +  if (indiceLecturasHumedad > 9) 
 +  { 
 +    indiceLecturasHumedad = 0; 
 +    mediaLista = true; 
 +  } 
 + 
 +  mediaHumedad = 0; 
 +  for (int i = 0; i < 10; i++) mediaHumedad += lecturasHumedad[i]; 
 +  mediaHumedad /= 10; 
 +  if (mediaHumedad > humedadMaxima) humedadMaxima = mediaHumedad; 
 +  if (mediaHumedad < humedadMinima) humedadMinima = mediaHumedad; 
 +  mediaHumedad -= humedadMinima; 
 + 
 +  mediaHumedad = (double)((double)mediaHumedad / (double)(humedadMaxima - humedadMinima)) * 100; 
 +  if (mediaHumedad == 100) mediaHumedad = 99; 
 +
 + 
 + 
 +// Activa lo bomba de riego durante el tiempo configurado 
 +void regar() 
 +
 +  if (riegos == limiteRiegos) 
 +  { 
 +    linea1 = " - BLOQUEADO - "; 
 +    linea2 = "Limite de riegos"; 
 +    mostrarTexto(); 
 +    while (true) { 
 +      delay(999999); 
 +    } 
 +  } 
 +  int riegoPendiente = duracionRiego; 
 +  digitalWrite(pinMotor, HIGH); 
 +  while (riegoPendiente > 0) 
 +  { 
 +    linea1 = " -- REGANDO -- "; 
 +    linea2 = "Restante: " + str(riegoPendiente); 
 +    mostrarTexto(); 
 +    delay(990); 
 +    riegoPendiente--; 
 +  } 
 +  digitalWrite(pinMotor, LOW); 
 +  riegos++; 
 +
 + 
 +</sxh> 
 + 
 + 
 + 
 +==== Referencias ==== 
 +  * http://www.prometec.net/lcd-keypad-shield/ 
 +  * http://forum.arduino.cc/index.php?topic=303135.105