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:arduino:lcd [2016/08/07 22:42] – lc | electronica:arduino:lcd [2023/01/18 14:36] (actual) – editor externo 127.0.0.1 | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| + | {{tag> | ||
| ===== 3 . Añadir LCD ===== | ===== 3 . Añadir LCD ===== | ||
| Continuamos con nuestro proyecto y ahora vamos a añadirle un LCD del tipo [[http:// | Continuamos con nuestro proyecto y ahora vamos a añadirle un LCD del tipo [[http:// | ||
| + | {{ : | ||
| 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 | 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: | tenemos que hacer las conexiones siguientes: | ||
| Línea 9: | Línea 10: | ||
| El esquema de conexión sería: | El esquema de conexión sería: | ||
| - | ^LCD ^ Arduino Nano^ | + | ^ LCD ^ Arduino Nano ^ | 
| - | |A0 |A0 | | + | | A0 | 
| - | |D4 |D4 | | + | | D4 | 
| - | |D5 |D5 | | + | | D5 | 
| - | |D6 |D6 | | + | | D6 | 
| - | |D7 |D7 | | + | | D7 | 
| - | |D8 |D8 | | + | | D8 | 
| - | |D9 |D9 | | + | | D9 | 
| El código: | El código: | ||
| <sxh javascript> | <sxh javascript> | ||
| + | //// wiki.intrusos.info | ||
| + | // modificación del código de http:// | ||
| - | // wiki.intrusos.info | ||
| - | // modificacion del Sketch de prueba para sensores DHT humedad / temperatura de www.internetdelascosas.cl | ||
| - | // Escrito por @joniuz basado en el sketch de Ladyada | ||
| - | // v1.3 añadimos lcd | ||
| - | |||
| - | // Libreria para Sensores DHT | ||
| - | #include " | ||
| - | |||
| - | //libreia LCD | ||
| - | #include < | ||
| - | LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // ( RS, EN, d4, d5, d6, d7) | ||
| + | // | ||
| + | #include " | ||
| #define DHTPIN 2 // Pin del Arduino al cual esta conectado el pin 2 del sensor | #define DHTPIN 2 // Pin del Arduino al cual esta conectado el pin 2 del sensor | ||
| - | |||
| // Descomentar segun el tipo de sensor DHT usado | // Descomentar segun el tipo de sensor DHT usado | ||
| #define DHTTYPE DHT11 // DHT 11 | #define DHTTYPE DHT11 // DHT 11 | ||
| + | DHT dht(DHTPIN, DHTTYPE);// Inicializa el sensor | ||
| - | // Inicializa el sensor | + | //---------------LCD --------------------------------------------------------------------- | 
| - | DHT dht(DHTPIN, DHTTYPE); | + | #include < | 
| - | //Definimos a que patilla esta conectado | + | // Inicializa | 
| - | const int sensorPin = A1; | + | LiquidCrystal lcd(8, 9, 4, 5, 6, 7); | 
| - | // Configura Arduino | + | // Pines digitales | 
| - | void setup() { | + | byte pinLedVerde = 10; | 
| - |  | + | byte pinLedRojo = 11; | 
| - |  | + | byte pinMotor = 12; | 
| + | |||
| + | // Pines analógicos | ||
| + | byte pinSensorHumedad = 1; | ||
| + | |||
| + | // definición teclado | ||
| + | int lcd_key | ||
| + | int adc_key_in | ||
| + | #define btnRIGHT | ||
| + | #define btnUP 1 | ||
| + | #define btnDOWN | ||
| + | #define btnLEFT | ||
| + | #define btnSELECT 4 | ||
| + | #define btnNONE | ||
| + | |||
| + | // 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; | ||
| + | String linea2; | ||
| + | |||
| + | int humedadMinima = 0;		// Lectura mínima por defecto para el sensor de humedad | ||
| + | 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 | ||
| + | |||
| + | int read_LCD_buttons(); | ||
| + | |||
| + | int read_LCD_buttons() | ||
| + | { adc_key_in = analogRead(0); | ||
| + |  | ||
| + |  | ||
| + | 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; | ||
| + | } | ||
| + | |||
| + | |||
| + | // | ||
| + | void setup() | ||
| + | { | ||
| + | |||
| + | // Inicializa el número de columnas y filas del LCD | ||
| lcd.begin(16, | lcd.begin(16, | ||
| - | dht.begin(); | + | |
| + | // Establece a modo salida los pines para controlar la bomba y los led de señalización | ||
| + | pinMode(pinMotor, | ||
| + | pinMode(pinLedRojo, | ||
| + | pinMode(pinLedVerde, | ||
| + | |||
| + | // Activa el led rojo y muestra la pregunta sobre el modo en el que va a funcionar | ||
| + | digitalWrite(pinLedRojo, | ||
| + | mostrarPregunta(modoElegido); | ||
| + | |||
| + | // Pregunta por el modo de funcionamiento: | ||
| + | boolean respuesta = false; | ||
| + | while (!respuesta) | ||
| + | { | ||
| + | lcd_key = read_LCD_buttons(); | ||
| + | delay(200); | ||
| + | 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(" | ||
| + | horasTemporizacion = preguntarValor(" | ||
| + | minutosTemporizacion = preguntarValor(" | ||
| + | } | ||
| + | |||
| + | // Muestra un resumen del tiempo elegido | ||
| + | linea1 = " | ||
| + | linea2 = " | ||
| + | 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(" | ||
| + | } | ||
| + | |||
| + | // Pregunta cuantos segundos deberá durar el riego cuando se active | ||
| + | duracionRiego = preguntarValor(" | ||
| + | |||
| + | // Finalizada la programación desactiva el led rojo y activa el verde | ||
| + | digitalWrite(pinLedRojo, | ||
| + | digitalWrite(pinLedVerde, | ||
| } | } | ||
| - | void loop() { | ||
| - | // Espera dos segundos para realizar la primera medición. | ||
| - | delay(2000); | ||
| - |  | + | void loop() | 
| - |  | + | { | 
| + |  | ||
| + |  | ||
| + | int horasPendientes = horasTemporizacion; | ||
| + | int minutosPendientes = minutosTemporizacion; | ||
| + | int segundosPendientes = 0; | ||
| - | // Obtiene la Humedad | + |  | 
| - | float h = dht.readHumidity(); | + | { | 
| - | // Obtiene la Temperatura en Celsius | + |  | 
| - | float t = dht.readTemperature(); | + | while ((diasPendientes + horasPendientes + minutosPendientes + segundosPendientes) > 0) | 
| - | // | + | { | 
| - | int humedadtierra | + |  | 
| + | delay(987); | ||
| + |  | ||
| + | if (segundosPendientes | ||
| + | { | ||
| + | segundosPendientes = 59; | ||
| + | minutosPendientes--; | ||
| + | } | ||
| + | if (minutosPendientes == -1) | ||
| + | { | ||
| + | minutosPendientes = 59; | ||
| + | horasPendientes--; | ||
| + | } | ||
| + | if (horasPendientes == -1) | ||
| + | { | ||
| + | horasPendientes = 23; | ||
| + | diasPendientes--; | ||
| + | } | ||
| - | lcd.setCursor(0, | + | // Actualiza la variable con la humedad actual | 
| - | lcd.print(" | + |  | 
| - | lcd.print(h); | + | |
| - |  | + | |
| + | // Actualiza el display con el tiempo hasta el siguiente riego y la humedad actual | ||
| + | linea1 = str(diasPendientes) + ":" | ||
| + | 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; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // 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 = " | ||
| + | linea2 = str(diasPendientes) + ":" | ||
| + | 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 = " | ||
| + | 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; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // Pregunta el modo de funcionamiento con la última opción elegida | ||
| + | void mostrarPregunta(byte modo) | ||
| + | { | ||
| + | lcd.clear(); | ||
| + | lcd.print(" | ||
| lcd.setCursor(0, | lcd.setCursor(0, | ||
| - | lcd.print(" | + |  | 
| - | lcd.print(humedadtierra); | + |  | 
| - | lcd.print(" | + |  | 
| + | } | ||
| + | |||
| + | // Muestra el texto configurado en el display | ||
| + | void mostrarTexto() | ||
| + | { | ||
| + | lcd.clear(); | ||
| + | lcd.print(linea1); | ||
| + | lcd.setCursor(0, | ||
| + | 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(); | ||
| + | } | ||
| - | //Segun la tecla pulsada mostramos temperatura o humedad | + | else if ( lcd_key == btnSELECT) | 
| - | int boton; | + |  | 
| - | boton= analogRead (0); | + |  | 
| - |  | + |  | 
| - |  | + | |
| - |  | + | |
| - |  | + | |
| - | lcd.print(" | + | |
| } | } | ||
| - |  | + |  | 
| - |  | + | } | 
| - |  | + | |
| - |  | + | // Devuelve una cadena numérica de al menos 2 caractes, rellenando con un cero por la izquierda si hace falta | 
| - |  | + | String str(int valor) | 
| + | { | ||
| + |  | ||
| + | else return (String(valor)); | ||
| + | } | ||
| + | |||
| + | |||
| + | // Actualiza la variable con la media de humedad de las últimas 10 lecturas | ||
| + | void leerHumedad() | ||
| + | { | ||
| + |  | ||
| + | lecturasHumedad[indiceLecturasHumedad] = map (lecturasHumedad[indiceLecturasHumedad], | ||
| + |  | ||
| + |  | ||
| + | { | ||
| + | indiceLecturasHumedad = 0; | ||
| + |  | ||
| } | } | ||
| + | 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; | ||
| - |  | + |  | 
| + | if (mediaHumedad == 100) mediaHumedad = 99; | ||
| } | } | ||
| + | |||
| + | |||
| + | // Activa lo bomba de riego durante el tiempo configurado | ||
| + | void regar() | ||
| + | { | ||
| + | if (riegos == limiteRiegos) | ||
| + | { | ||
| + | linea1 = " - BLOQUEADO - "; | ||
| + | linea2 = " | ||
| + | mostrarTexto(); | ||
| + | while (true) { | ||
| + | delay(999999); | ||
| + | } | ||
| + | } | ||
| + | int riegoPendiente = duracionRiego; | ||
| + | digitalWrite(pinMotor, | ||
| + | while (riegoPendiente > 0) | ||
| + | { | ||
| + | linea1 = " -- REGANDO -- "; | ||
| + | linea2 = " | ||
| + | mostrarTexto(); | ||
| + | delay(990); | ||
| + | riegoPendiente--; | ||
| + | } | ||
| + | digitalWrite(pinMotor, | ||
| + | riegos++; | ||
| + | } | ||
| + | |||
| </ | </ | ||
| Línea 102: | Línea 405: | ||
| ==== Referencias ==== | ==== Referencias ==== | ||
| * http:// | * http:// | ||
| + | * http:// | ||
 
