⚡ Descuentos en cursos en video - Lleva tu aprendizaje técnico al siguiente nivel y aprovecha precios especiales antes de que termine la oferta. 🔥 Aprovechar oferta ahora 🔥
Computadoras

comportamiento no deseado

Meta
Meta
39
hace 3 años
hace 3 años
hola:

en este código de arduino, lo que quiero hacer es menú con submenús. cuando quiero ir al menú nombre relÉs, pulso el botón ok / enter, como que entra a dicho menú y vuelve a salir automáticamente. no se queda dentro.
lo he dividido el programa en tres archivos.

archivo inicial.ino:
// include el código de la librería.#include <liquidcrystal.h>
// inicializa la librería con sus pines indicados.// rs, rw, enable, d4, d5, d6, d7.//liquidcrystal lcd(8, null, 9, 4, 5, 6, 7);liquidcrystal lcd(8, 9, 4, 5, 6, 7);
// declarar a partir de aquí el lcd.#include "menuprincipal.h"
// pin 10 para saber que es luz de fondo.//const byte luzfondo = 10;
// variables.// declarado pulsadores.const progmem byte arriba = a1;const progmem byte abajo = a2;const progmem byte izquierda = a3;const progmem byte derecha = a4;const progmem byte enter = a5;
byte estadobotonarriba = 0;byte estadobotonabajo = 0;byte estadobotonizquierda = 0;byte estadobotonderecha = 0;byte estadobotonenter = 0;
void setup(){  serial.begin(115200); // 115200
  // la pantalla es de 20 caracteres y 4 filas.  lcd.begin(20, 4);
  // indicar luz de fondo como salida.  // pinmode(luzfondo, output);
  // configuración de pines como salidas digitales.  pinmode(13, output);
  // configuración de pines como entradas digitales.  pinmode(arriba, input); // arriba. a1.  pinmode(abajo, input); // abajo. a2.  pinmode(izquierda, input); // izquierda. a3.  pinmode(derecha, input); // derecha. a4.  pinmode(enter, input); // ok / enter. a5.
  lcd.clear();                          // borra la pantalla y su posición superior izquierda.  lcd.setcursor(0, 1);                  // línea 2 del lcd.  lcd.print(f(" pantalla principal ")); // muestra título en la lcd.}
void loop(){  estadobotonenter = digitalread(enter);  if (estadobotonenter == high)  {    lcd.nocursor(); // oculat cursor.    lcd.noblink();  // cursor no parpadeando.    menu_principal();    serial.println(estadobotonenter);  }  delay(50); // para mayor estabilidad entre lecturas.}
menuprincipal.h:
// el menú principal que muestra nada más ejecutar el programa.

// ** menÚ principal **
// > estado principal
//   nombres relÉs
//   nombres sensores

// -------------------

// ** menÚ principal **
//   entrada analÓgica
//   configuraciÓn
//   acerca de...


// -------------------

// ** menÚ principal **
//   ayuda
//   extra
//   inicio

#include "nombrereles.h"

static void menu_principal()
{
  // contador de teclas y navegador.
  byte opcion = 0;
  bool salir = false;
  const progmem byte seleccionmenu = 8;

  // oculat cursor.
  lcd.nocursor();
 
  // cursor no parpadeando.
  lcd.noblink();
 
  // limpiar pantalla.
  lcd.clear();


  do
  {
    //******************************************************************
    // dibujo el menú principal.
    const progmem string mensajes[] =
    {
      "** menu principal **", // posición 0.
      "  estado principal  ", // 1
      "  nombre reles      ", // 2
      "  nombre sensores   ", // 3
      "  entrada analogica ", // 4
      "  configuracion     ", // 5
      "  acerca de...      ", // 6
      "  ayuda             ", // 7
      "  extra             ", // 8
      "  inicio            ", // 9
      "                    ", // 10
      ">"                     // 11
    };

    switch (opcion)
    {
      case 0:
        lcd.setcursor(0, 0);     // línea 1 del lcd.
        lcd.print(mensajes[0]);  // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[1]);  // > estado principal
        lcd.setcursor(0, 1);
        lcd.print(mensajes[11]); // >
        lcd.setcursor(0, 2);
        lcd.print(mensajes[2]);  //   nombre relÉs
        lcd.setcursor(0, 3);
        lcd.print(mensajes[3]);  //   nombre sensores
        break;

      case 1:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[1]);         //   estado principal
        lcd.setcursor(0, 2);
        lcd.print(mensajes[2]);         // > nombre relÉs
        lcd.setcursor(0, 2);
        lcd.print(mensajes[11]);        // >
        lcd.setcursor(0, 3);
        lcd.print(mensajes[3]);         //   nombre sensores
        break;

      case 2:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[1]);         //   estado principal
        lcd.setcursor(0, 2);
        lcd.print(mensajes[2]);         //   nombre relÉs
        lcd.setcursor(0, 3);
        lcd.print(mensajes[3]);         // > nombre sensores
        lcd.setcursor(0, 3);
        lcd.print(mensajes[11]);        // >
        break;

      case 3:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[4]);         // > entrada analÓgica
        lcd.setcursor(0, 1);
        lcd.print(mensajes[11]);        // >
        lcd.setcursor(0, 2);
        lcd.print(mensajes[5]);         //   configuraciÓn
        lcd.setcursor(0, 3);
        lcd.print(mensajes[6]);         //   acerca de...
        break;

      case 4:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[4]);         //   entrada analÓgica
        lcd.setcursor(0, 2);
        lcd.print(mensajes[5]);         // > configuraciÓn
        lcd.setcursor(0, 2);
        lcd.print(mensajes[11]);        // >
        lcd.setcursor(0, 3);
        lcd.print(mensajes[6]);         //   acerca de...
        break;

      case 5:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[4]);         //   entrada analÓgica
        lcd.setcursor(0, 2);
        lcd.print(mensajes[5]);         //   configuraciÓn
        lcd.setcursor(0, 3);
        lcd.print(mensajes[6]);         // > acerca de...
        lcd.setcursor(0, 3);
        lcd.print(mensajes[11]);        // >
        break;

      case 6:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[7]);         // > ayuda
        lcd.setcursor(0, 1);
        lcd.print(mensajes[11]);        // >
        lcd.setcursor(0, 2);
        lcd.print(mensajes[8]);         //   extra
        lcd.setcursor(0, 3);
        lcd.print(mensajes[9]);         //   inicio
        break;

      case 7:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[7]);         //   ayuda
        lcd.setcursor(0, 2);
        lcd.print(mensajes[8]);         // > extra
        lcd.setcursor(0, 2);
        lcd.print(mensajes[11]);        // >
        lcd.setcursor(0, 3);
        lcd.print(mensajes[9]);         //   inicio
        break;

      case 8:
        lcd.setcursor(0, 0);
        lcd.print(mensajes[0]);         // ** menÚ principal **
        lcd.setcursor(0, 1);
        lcd.print(mensajes[7]);         //   ayuda
        lcd.setcursor(0, 2);
        lcd.print(mensajes[8]);         //   extra
        lcd.setcursor(0, 3);
        lcd.print(mensajes[9]);         // > inicio
        lcd.setcursor(0, 3);
        lcd.print(mensajes[11]);        // >
        break;

      default:
        serial.print(f("fuera de rango"));
        break;
    }
    // fin de pintar el menú principal.
    //******************************************************************

    // leer pulsador ingresada por el usuario.

    // validar el tipo de pulsador.
    if (digitalread(a5) == high)
    {
      switch (opcion)
      {
        case 0:
          //
          break;
        case 1:
          nombrereles_principal();
          break;
        case 2:
          //opcionc();
          break;
        case 3:
          //
          break;
        case 4:
          //
          break;
        case 5:
          //
          break;
        case 6:
          //
          break;
        case 7:
          //
          break;
        case 8:
          return;
          salir = true;
          break;
        default:
          lcd.print(f("fuera de rango.     "));
          break;
      }
    }
    delay(50);

    // entonces si pulsas pulsador abajo.
    if (digitalread(a2) == high)
    {
      opcion++;
    }
    delay(50);

    // entonces si pulsas pulsador arriba.
    if (digitalread(a1) == high)
    {
      opcion--;
    }
    delay(50);

    // si está en la última opción, salta a la primera.
    if (opcion > seleccionmenu)
    {
      opcion = 0;
    }

    // si está en la primera posición, salta a la última.
    if (opcion < 0)
    {
      opcion = seleccionmenu;
    }

    // uso la tecla escape como salida.
  } while (salir == false);
}
nombrereles.h:
// variables.
static byte coordenadax = 0; // coordenada x del textbox del nombre del relé.
static byte index = 0; // Índice de atras y guardar.
static byte textbox = 0; // 0 para el número de relé (de 1 al 8) y 1 para el texto del relé (16 char).
static string nombresdelosreles[8]; // líneas que al final se van a guardar en archivo.txt.
static bool cargado = false; // vale false si todavía no se cargaron los nombres del archivo, si no true, para no repetir.

// caracteres alfanuméricos en el array. no se usa la Ñ.
const static progmem char alfanumerico[] =
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'ñ', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ',', '-', '_', ':', ';', '¿',
'?', '(', ')', '[', ']', '{', '}', '<', '>', '=', '$', '&', '@', '\\', '/', '\"', ' '
};

// Índices de los caracteres de los 8 relés para el array alfanumérico.
// hay un total de 85 caracteres. se cuenta desde el 0 al 84.
static byte indicearray[][16] =
{
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 },
{ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84 }
};

const static progmem char numerico[] = { '1', '2', '3', '4', '5', '6', '7', '8' };
static byte indicenumerico = 0;

static void mostrarlineanombre()
{
lcd.setcursor(4, 1);
for (byte a = 0; a < 16; a++)
{
lcd.print(alfanumerico[indicearray[indicenumerico][a]]);
}
}

static void inicio()
{
lcd.clear(); // limpiar ventana.
lcd.setcursor(2, 0); // posición del cursor.
lcd.print(f("nombre de reles: "));
lcd.setcursor(0, 3);
lcd.print(f(" atras guardar "));

//#########################################################################################
// este código es de c#, ya lo pasaré a arduino con su eeprom interna o una tarjeta sd
// que también se puede leer archivo de texto tipo *.txt.

/*
if (cargado == false)
{
// ¿existe el archivo de texto?
if (file.exists("nombresreles.txt"))
{
// supone un archivo con 8 lineas de 16 char completas aunque sea con espacios.
nombresdelosreles = file.readalllines("nombresreles.txt");
int a, b, c;
for (a = 0; a < 8; a++)
{
for (b = 0; b < 16; b++)
{
for (c = 0; nombresdelosreles[a][b] != alfanumerico[c]; c++)
{
;
}
indicearray[a][b] = c;
}
}
}
cargado = true;
}
*/

if (cargado == false)
{
// supone un archivo con 8 lineas de 16 char completas aunque sea con espacios.
// nombresdelosreles = file.readalllines("nombresreles.txt");
byte a, b, c;
for (a = 0; a < 8; a++)
{
for (b = 0; b < 16; b++)
{
for (c = 0; nombresdelosreles[a][b] != alfanumerico[c]; c++)
{
;
}
indicearray[a][b] = c;
}
}
cargado = true;
}
//#########################################################################################

mostrarlineanombre();
lcd.setcursor(2, 1);
lcd.print(numerico[indicenumerico]);
if (textbox == 0)
{
lcd.setcursor(2, 1);
}
else
{
lcd.setcursor(4 + coordenadax, 1);
}
}

static void nombrereles_principal()
{
// consolekey tecla, tecla2;
byte indice = 0;

inicio();

while (true)
{
lcd.cursor(); // mostrar cursor.
lcd.blink(); // cursosr parpadeando.
//tecla = console.readkey(true).key;

// ¿has pulsado tecla flecha arriba?
if (high == digitalread(a1)) // sí.
{
if (textbox == 0)
{
lcd.setcursor(4, 1);
textbox = 1;
}
else // textbox == 1
{
if (coordenadax < 15)
{
coordenadax++;
lcd.setcursor(4 + coordenadax, 1);
}
}
}
// entonces. ¿haz pulsado flecha izquierda?
else if (high == digitalread(a3)) // sí.
{
if (textbox == 1)
{
if (coordenadax > 0)
{
coordenadax--;
lcd.setcursor(4 + coordenadax, 1);
}
else
{
lcd.setcursor(2, 1);
textbox = 0;
}
}
}
// entonces. ¿haz pulsado flecha abajo?
else if (high == digitalread(a2)) // sí.
{
if (textbox == 0)
{
indicenumerico--;
if (indicenumerico < 0)
{
indicenumerico = 7;
}
lcd.setcursor(2, 1);
lcd.print(numerico[indicenumerico]);
mostrarlineanombre();
lcd.setcursor(2, 1);
}
else // textbox == 1
{
indicearray[indicenumerico][coordenadax]--;
if (indicearray[indicenumerico][coordenadax] < 0)
{
indicearray[indicenumerico][coordenadax] = 84;
}
lcd.print(alfanumerico[indicearray[indicenumerico][coordenadax]]);
lcd.setcursor(4 + coordenadax, 1);
}
}
// entonces. ¿haz pulsado flecha arriba?
else if (high == digitalread(a1)) // sí.
{
if (textbox == 0)
{
indicenumerico++;
if (indicenumerico >= 8)
{
indicenumerico = 0;
}
lcd.setcursor(2, 1);
lcd.print(numerico[indicenumerico]);
mostrarlineanombre();
lcd.setcursor(2, 1);
}
else // textbox == 1
{
indicearray[indicenumerico][coordenadax]++;
if (indicearray[indicenumerico][coordenadax] > 84) // aquí es > 84 (o >= 85) porque 85 es la cantidad.
{ // total y al alcanzarla ahí paso al comienzo (0).
indicearray[indicenumerico][coordenadax] = 0;
}
lcd.print(alfanumerico[indicearray[indicenumerico][coordenadax]]);
lcd.setcursor(4 + coordenadax, 1);
}
}
// entonces. ¿haz pulsado la tecla enter?
else if (high == digitalread(a5)) // sí.
{
lcd.cursor(); // ocultar cursor.
lcd.noblink(); // sin parpadeos el cursor.
lcd.setcursor(0, 3);
lcd.print("> atras guardar ");
index = 0;
while (digitalread(a5))
{
if ((high == digitalread(a4)) || (high == digitalread(a3)))
{
index = 1 - index; // si vale 0 valdrá 1, si vale 1 valdrá 0.
lcd.setcursor(0, 3);
if (index == 0)
{
lcd.print(f("> atras guardar "));
}
else
{
lcd.print(f(" atras > guardar "));
}
}
}
if (index == 1) // se pulsó enter en guardar.
{
nombresdelosreles[8];
for (byte a = 0; a < 8; a++)
{
for (byte b = 0; b < 16; b++)
{
// nombresdelosreles[a] += alfanumerico[indicearray[a][b]];
}
}

// guardar archivo de texto con los nombres de los relés.
//file.writealllines("nombresreles.txt", nombresdelosreles);

// en esta parte, justo arriba se hace con el lenguaje de c#, aquí hay que usar la
// eeprom interna de arduino que haré más adelante.

// puede que los nombres contengan espacios al final, que no se verán pero no
// hay que borrarlos porque al principio leerá 16 char y si faltan, fallará.
lcd.clear();
lcd.setcursor(2, 1);
lcd.print(f("haz guardado:"));
lcd.setcursor(2, 3);
lcd.print((indice + 1));
lcd.setcursor(4, 3);
//lcd.print(nombresdelosreles[indice]);

// mientras no pulses la tecla enter, sigue las demás intrucciones.
while (high == digitalread(a5))
{
// ¿haz pulsado flecha arriba?
if (high == digitalread(a1)) // sí. ejecuta código dentro de ella.
{
indice--; // decrementa la variable indice.
// ¿indice es menor que 0?
if (indice < 0) // sí.
{
indice = 7;
}
}
// entonces. ¿haz pulsado flecha abajo?
else if (high == digitalread(a2)) // sí.
{
indice++; // incrementa la variable indice.
// ¿indice es mayor o igual que 8?
if (indice >= 8) // sí.
{
indice = 0;
}
}
lcd.setcursor(2, 3);
lcd.print((indice + 1));
lcd.setcursor(4, 3);
lcd.print(nombresdelosreles[indice]);
}
inicio();
}
else if (index == 0)
{
break;
}
}
}
}
¿alguna idea para resolver este problema?

un cordial saludos.
Arduino LCD.JPG
Reparaciones similares solucionadas

¿Conoces una solución?

¡Aprende a reparar con estos cursos YoReparo!

¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos?
Regístrate gratis