No consigo programarlo como deseo. Compila bien y se queda ahí

Foro dedicado a la programación en todo tipo de sistemas clásicos.
REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

No consigo programarlo como deseo. Compila bien y se queda ahí

Mensajepor REHome » 28 May 2022, 16:00

Imagen

Buenas:

He adaptado el código a Arduino y compila.

Tratando con el lenguaje Arduino. Ejecuta bien. Tiene comportamientos no deseado. Si pulsas el Botón Enter, todo bien. Luego al seleccionar un menú e incluso antes, la flecha indicadora parpadea, como que hay un bucle y se refresca una y otra vez.

Si entras al submenú llamado > NOMBRE RELES, directamente se pone en > ATRÁS y sale del submenú y vuelve al menú principal.

Quiero averiguar o corregir este motivo.

Códigos en Arduino.

LCD_Menu_y_Submenu.ino:

Código: Seleccionar todo

    // 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 byte ARRIBA PROGMEM = A1;
    const byte ABAJO PROGMEM = A2;
    const byte IZQUIERDA PROGMEM = A3;
    const byte DERECHA PROGMEM = A4;
    const byte ENTER PROGMEM = 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
:


Código: Seleccionar todo

    #include "NombreReles.h"
     
    void Menu_Principal()
    {
      // Contador de teclas y navegador.
      byte opcion = 0;
      bool salir = false;
      const byte seleccionMenu PROGMEM = 8;
     
      // Oculat cursor.
      lcd.noCursor();
     
      // Cursor no parpadeando.
      lcd.noBlink();
     
      // Limpiar pantalla.
      lcd.clear();
     
     
      do
      {
        //******************************************************************
        // Dibujo el menú principal.
        const String MENSAJES[] PROGMEM =
        {
          "** 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:

Código: Seleccionar todo

    // Variables.
    byte coordenadaX = 0;          // Coordenada X del textBox del nombre del Relé.
    byte index = 0;                // Índice de ATRAS y GUARDAR.
    byte textBox = 0;              // 0 para el número de Relé (de 1 al 8) y 1 para el texto del Relé (16 char).
    String nombresDeLosReles[8];  // Líneas que al final se van a guardar en Archivo.txt.
    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.
    const char ALFANUMERICO[] PROGMEM =
    {
      '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 86 caracteres. Se cuenta desde el 0 al 85.
    byte indiceArray[][16] =
    {
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
      { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 }
    };
     
    const char NUMERICO[] PROGMEM = { '1', '2', '3', '4', '5', '6', '7', '8' };
    byte indiceNumerico = 0;
     
    void MostrarLineaNombre()
    {
      lcd.setCursor(4, 1);
      for (byte a = 0; a < 16; a++)
      {
        lcd.print(ALFANUMERICO[indiceArray[indiceNumerico][a]]);
      }
    }
     
    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);
      }
    }
     
    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] = 85;
            }
            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] > 85)  // Aquí es > 85 (o >= 86) porque 86 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;
          }
        }
      }
    }


Compilar, compila bien.

¿Alguna idea?

Saludos.

Volver a “Programación”

¿Quién está conectado?

Usuarios navegando por este Foro: Bing [Bot] y 12 invitados