Go Down

Topic: Problema con lcd.clear() parpadeo pantalla LCD [SOLUCIONADO] (Read 143 times) previous topic - next topic

cotarejo

Buenas... en un proyecto que tengo entre manos, estoy intentando hacer un menú para agregar, modificar y eliminar los alarm.alarmrepeat. Esto quiero hacerlo a través de un teclado 4x4 y un LCD, pero para entrar al menú tengo un interruptor, cuando pulso el interruptor "palanca hacia arriba del interruptor" entro al menú, cuando bajo la palanca, salgo del menú. Aún no tengo las funciones para modificar los alarm.repeat, pero he conseguido hacer un menú y cuando pulso el interruptor "subo la palanca" me cambia de pantalla y me va a la función menu() el problema que tengo es que me mantiene en la pantalla los caracteres que no se han cubierto en la función menu(), por lo que si uso un lcd.clear() los limpia, ya no se ven esos caracteres "residuales" pero no para de refrescarse... He buscado por internet y he visto varios ejemplos pero no doy con la solución.. el código es este:

Code: [Select]


#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
#include <Keypad.h>

// Creamos un array bidimensional para el control del teclado 4x4

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {26, 24, 22, 28}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {27, 25, 23, 29}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Fin de declaración del pad

// Creamos un objeto lcd con los pines a los que está conectado
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

// Definimos el pin del interruptor del menú
const int botonmenu = 3;     // Pin del interruptor del menú

void setup() {

  Serial.begin(9600);

  // Pin del pulsador para el menú
  pinMode(botonmenu, INPUT_PULLUP);  

  //cargamos un objeto lcd e iniciamos la pantalla con 20 caracteres por línea y 4 líneas
  lcd.begin(20, 4);

  // Crear las alarmas y configurar las funciones correspondientes a cada una
  Alarm.alarmRepeat(8, 30, 0, aperturaelectrovalvula);
  Alarm.alarmRepeat(20, 30, 0, aperturaelectrovalvula);

  ///// Fin del sistema de riego /////

}

void loop(){

 // Creamos el objeto key, para el keypad
 
     char key = keypad.getKey();
   //  String caracterpresionado(key);

 if (digitalRead(botonmenu) == LOW) {
    Serial.println("LOW");
    menu();
  }else{
    lcd.clear();
    //Resto del código.....
  }
}

void menu(){

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.write("1 - Ver Alarmas");
  lcd.setCursor(0,1);
  lcd.write("2 - cambiar Alarmas");
  lcd.setCursor(0,2);
  lcd.write("3 - Añadir alarmas");
  lcd.setCursor(0,3);
  lcd.write("4 - Borrar alarmas");
}



Con el lcd.clear() parpadea la pantalla LCD pero no hay datos residuales de la anterior pantalla... cuando quito el lcd.clear() la pantalla no parpadea pero quedan datos residuales de la anterior pantalla...


¿¿Alguna ayuda???


Gracias.

surbyte

Posible solucion todos los carteles del mismo tamaño, supongo que el mas largo cabe en tu LCD sino no lo hace lo siento porque tu lo posteaste asi.

Code: [Select]

  lcd.setCursor(0,0);
  lcd.write("1 - Ver Alarmas    ");
  lcd.setCursor(0,1);
  lcd.write("2 - cambiar Alarmas");
  lcd.setCursor(0,2);
  lcd.write("3 - Añadir alarmas ");
  lcd.setCursor(0,3);
  lcd.write("4 - Borrar alarmas ");


Aunque creo que luego tendremos que usar otra porque esto solo parece ser el comienzo.
Veremos como evoluciona tu programa, x ahora esta simple modificación no requiere de ningun lcd.clear()
Todos de igual longitud


cotarejo

Buenas!! Lo de tapar los caracteres con espacios ya lo pensé, aunque me parece una solución poco elegante... Había pensado sino en hacer un contador y si suma más de uno, que no hiciese lcd.clear() o algo similar... Aunque no he dado con esa solución aún

noter

Pues en mi opinión es la solución más práctica, aunque no sea "elegante". Evitas esos milisegundos de vacío que hay entre el borrado de pantalla y el repintado.
Si no quieres "derrochar" tanta memoria, puedes crear una función que mida e imprima la cadena, y rellene el resto de la línea con espacios.
Para terminar de afinar la sensación visual, es conveniente diferenciar sí la pantalla ha cambiado y solo redibujar en ese caso.
Y siempre se puede intentar utilizar una buena librería, en lugar de reinventar la rueda.


cotarejo

Si... voy a intentarlo con espacios... no sé si será lo más elegante, pero va ser lo más sencillo de realizar ;)

Gracias!

surbyte

#5
Apr 20, 2018, 09:44 pm Last Edit: Apr 20, 2018, 10:10 pm by surbyte
Que tal esta forma, y creo que es elegante no?

Code: [Select]
#include <Wire.h> // <= esto lo necesito yo con mi librería puedes comantarla o eliminarla en tu caso
#include <LiquidCrystal.h>


const char *dmenu[] = {"1 - Ver Alarmas",
   "2 - cambiar Alarmas",
   "3 - Anadir alarmas",   // no me acuerdo como poner ñ
       "4 - Borrar alarmas"};

// Creamos un objeto lcd con los pines a los que está conectado
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

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

  //cargamos un objeto lcd e iniciamos la pantalla con 20 caracteres por línea y 4 líneas
  lcd.begin(20, 4);
  lcd.clear();
}

void loop(){
menu();
delay(5000);
}

void menu(){
  char buffer[25];

  for (int i=0; i<4; i++) {
     lcd.setCursor(0,i);
     sprintf(buffer, "%s",dmenu[i]);
           lcd.print(buffer);
     Serial.println(buffer);
   }
}

cotarejo

surbyte perfecto como siempre!! muchas gracias!!

Go Up