Ejecutar una función una SOLA vez en el void LOOP??

Hola!:slight_smile: Necesito ayuda

Estoy trabajando en un proyecto similar a una pda con una tft. La pantalla principal es un menu, este te redirige a diferentes pantallas que muestran resultados de sensores,o modulos como un RTC ( muestra la hora).
Entre estas funciones, tenía pensado poner una calculadora. Ésta la tendría que "pintar" en el void setup, (solo sería pintada una vez al inicio). Pero en el void setup ya "pinto" la estructura del menú. Si pruebo de imprimir la calculadora en el void loop, parpadea. Esto se deve a que constantemente está imprimiendo los diferentes botones, y no una sola vez.
En resumen, que podría hacer para que una instrucción solo sea ejecutada una vez en el void LOOP?

1 Like

Hola,
Tu problema es que no planteas bien como tiene que ser el programa, en el loop no tienes que pintar nada solo preocuparte de que opción se elige, según la opción elegida deberías llamar a un método que se encargue de borrar la pantalla y dibujar la siguiente, una vez dibujada la nueva pantalla entoces el mismo método o otro diferente deberá de ser el encargado de mantenerlo ahí, con un while hasta la orden de volver, por ejemplo con un botón volver, dentro de ese while se gestiona la calculadora.
Es mi opinión no tiene que ser compartida o ser la solución, pero espero haberte dado ideas.

Usa un flag o variable booleana.
La configuras como true y global.

Al iniciar el loop preguntas si esta en true y entonces haces lo qu quieres y al final cambias el flag o variable a false y listo!! Resuelto el problema.

Eso lo haces con cuantas cosas quieras activar una sola vez.

Que rapidez! Gracias por las ideas, chicos. Voy a informarme y probarlo:)

Me imagino que tendras prisa, yo estoy haciendo un proyecto similar con botones tipo windows, pero en estas fechas no creo que pueda avanzar mucho, cuando tenga algo te lo pongo aquí para que veas mi planteamiento.

Un saludo.

rodripelto:
Me imagino que tendras prisa, yo estoy haciendo un proyecto similar con botones tipo windows, pero en estas fechas no creo que pueda avanzar mucho, cuando tenga algo te lo pongo aquí para que veas mi planteamiento.

Un saludo.

Pues si... estoy aprovechando estas fiestas para avanzar. Parece interesante, cuando lo tengas me iria bien:)

rodripelto:
Hola,
Tu problema es que no planteas bien como tiene que ser el programa, en el loop no tienes que pintar nada solo preocuparte de que opción se elige, según la opción elegida deberías llamar a un método que se encargue de borrar la pantalla y dibujar la siguiente, una vez dibujada la nueva pantalla entoces el mismo método o otro diferente deberá de ser el encargado de mantenerlo ahí, con un while hasta la orden de volver, por ejemplo con un botón volver, dentro de ese while se gestiona la calculadora.
Es mi opinión no tiene que ser compartida o ser la solución, pero espero haberte dado ideas.

He provado con el while. Primeramente he declarado el menu antes de entrar en el void loop. Algo así:

void menu0 () {
  
  // create buttons
  for (uint8_t row=0; row<3; row++) {
    for (uint8_t col=0; col<3; col++) { 
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X), 
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE); 
      buttons[col + row*3].drawButton();
    }
  }

y después, ya en el void loop he llamado el menu con un while que lo imprime, y seguidamente mira que botton seleccionas mediante "if" (no lo he puesto, porque creo que no influye en el problema). Funciona bien, pero en la pantalla hay un leve parpadeo en los botones. Donde puede estar el error?

while (pantalla==0 ){
    
  menu0();

}

Claro, es que estas redibujando el botón constantemente, esa no es la idea que te planteo exactamente, sería algo así.

void menu0 () {
 
  // create buttons
  for (uint8_t row=0; row<3; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
while (condicion para salir ){
   
  // Código de gestión del menu 0

}
 MenuPrincipal(); // Cuando sale vuelve a dibujar el menú principal.
  }

A groso modo el programa seria algo así, ten en cuenta que esto que pongo ahora no funciona es solo para darte la idea.

void setup()
{
 MenuPrincipal(); // Esto sería un método que se encargara de dibujar el menú principal.
}

void loop()
{
// Gestión del menú principal

if (botón menu0 pulsado)
{
 Menu0(); // Llamo al menú 0
}
// Mas if que se encargan de otros botones
// También en lugar de if podría ser un switch case
}

Más o menos ese sería el planteamiento.

FUNCIONA! Muchas gracias rodripelto. He hecho el mismo codigo y va perfecto, no parpadea. Ahora pondré un "button" para volver al menú inicial así será más práctico.

Saludos

Me alegro,
Una pregunta ¿buttons es de alguna libreria o lo has creado tu?¿si es libreria me puedes decir cual?.

De momento yo me los he creado, luego pango la clase que he creado, es por compara.

Un saludo.

jajajaj no! els buttons del programa/ libreria són bastante difíciles de entender. Yo he aprovechado un ejemplo de la TFT (que era similar a un teclado con numeros) y lo he modificado para hacer el menu. Cuando dije "button" me refería a uno de externo, de los de toda la vida. Práctico y más rápido. Eso si, no queda tan estético...

Bueno yo he puesto lo que tengo hasta ahora en este hilo he aprovechado para hacer una consulta ya que quiero sacarlo en una librería a parte.