No funciona flecha indicadora para elegir submenús en el LCD

Buenas:

Como muestra en la imagen, no se mueve la flecha indicadora para seleccionar menús y submenús y quiero saber el motivo.

¿Qué hago mal?

Es verdad que estoy desarrollando el menú con submenú completo, por ahora voy por partes.

Arduino LCD.JPG
Si pulsas el botón OK / Enter entra en una lista de submenús, solo funciona el "Nombre Relés". Debería moverse la flecha indicadora cuando pulsas el pulsador Arriba y Abajo. También es funcional introducir nombre de cada relés.


También dejo el código hecho en C# hasta donde he llegado, funciona introducir nombre de los relés y quede guardado en un archivo de texto tipo .txt.

LCD_Menu_y_submenu_03.ino

C++:
// 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.
// Pulsador Arriba.
byte estadoActualArriba1 = 0;
byte estadoActualArriba2 = 0;
byte estadoUltimoArriba = 0;
int contadorArriba = 0;

// Pulsador Abajo.
byte estadoActualAbajo1 = 0;
byte estadoActualAbajo2 = 0;
byte estadoUltimoAbajo = 0;
int contadorAbajo = 0;

// Pulsador Izquierda.
byte estadoActualIzquierda1 = 0;
byte estadoActualIzquierda2 = 0;
byte estadoUltimoIzquierda = 0;
int contadorIzquierda = 0;

// Pulsador Derecha.
byte estadoActualDerecha1 = 0;
byte estadoActualDerecha2 = 0;
byte estadoUltimoDerecha = 0;
int contadorDerecha = 0;

// Pulsador Ok / Enter.
byte estadoActualEnter1 = 0;
byte estadoActualEnter2 = 0;
byte estadoUltimoEnter = 0;
int contadorEnter = 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(A1, INPUT); // Arriba.
  pinMode(A2, INPUT); // Abajo.
  pinMode(A3, INPUT); // Izquierda.
  pinMode(A4, INPUT); // Derecha.
  pinMode(A5, INPUT); // Ok / Enter.

  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()
{
  // Pulsador Arriba.
  estadoActualArriba1 = digitalRead(A1);
  delay(10);
  estadoActualArriba2 = digitalRead(A1);
  // Si los estados no son iguales, el sketch no hace gran cosa.
  if (estadoActualArriba1 == estadoActualArriba2)
  {
    // El código que sigue es idéntico al del anteerior ejemplo.
    if (estadoActualArriba1 != estadoUltimoArriba)
    {
      if (estadoActualArriba1 == HIGH)
      {
        contadorArriba = contadorArriba + 1;
        Serial.print (F("Esta es la pulsación ARRIBA nº: "));
        Serial.println(contadorArriba);
        lcd.setCursor(0, 0); // Línea 1 del LCD.
        lcd.print("Pulsado: ");
        lcd.print(contadorArriba);
      }
    }
  }
  estadoUltimoArriba = estadoActualArriba1;

  if (contadorArriba % 2 == 0)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  // Pulsador Abajo.
  estadoActualAbajo1 = digitalRead(A2);
  delay(10);
  estadoActualAbajo2 = digitalRead(A2);
  // Si los estados no son iguales, el sketch no hace gran cosa.
  if (estadoActualAbajo1 == estadoActualAbajo2)
  {
    // El código que sigue es idéntico al del anteerior ejemplo.
    if (estadoActualAbajo1 != estadoUltimoAbajo)
    {
      if (estadoActualAbajo1 == HIGH)
      {
        contadorAbajo = contadorAbajo + 1;
        Serial.print (F("Esta es la pulsación ABAJO nº: "));
        Serial.println(contadorAbajo);
      }
    }
  }
  estadoUltimoAbajo = estadoActualAbajo1;

  if (contadorAbajo % 2 == 0)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  // Pulsador Izquierda.
  estadoActualIzquierda1 = digitalRead(A3);
  delay(10);
  estadoActualIzquierda2 = digitalRead(A3);
  // Si los estados no son iguales, el sketch no hace gran cosa.
  if (estadoActualIzquierda1 == estadoActualIzquierda2)
  {
    // El código que sigue es idéntico al del anteerior ejemplo.
    if (estadoActualIzquierda1 != estadoUltimoIzquierda)
    {
      if (estadoActualIzquierda1 == HIGH)
      {
        contadorIzquierda = contadorIzquierda + 1;
        Serial.print (F("Esta es la pulsación IZQUIERDA nº: "));
        Serial.println(contadorIzquierda);
      }
    }
  }
  estadoUltimoIzquierda = estadoActualIzquierda1;

  if (contadorIzquierda % 2 == 0)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  // Pulsador Derecha.
  estadoActualDerecha1 = digitalRead(A4);
  delay(10);
  estadoActualDerecha2 = digitalRead(A4);
  // Si los estados no son iguales, el sketch no hace gran cosa.
  if (estadoActualDerecha1 == estadoActualDerecha2)
  {
    // El código que sigue es idéntico al del anteerior ejemplo.
    if (estadoActualDerecha1 != estadoUltimoDerecha)
    {
      if (estadoActualDerecha1 == HIGH)
      {
        contadorDerecha = contadorDerecha + 1;
        Serial.print (F("Esta es la pulsación DERECHA nº: "));
        Serial.println(contadorDerecha);
      }
    }
  }
  estadoUltimoDerecha = estadoActualDerecha1;

  if (contadorDerecha % 2 == 0)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  // Pulsador OK / Enter.
  estadoActualEnter1 = digitalRead(A5);
  delay(10);
  estadoActualEnter2 = digitalRead(A5);
  // Si los estados no son iguales, el sketch no hace gran cosa.
  if (estadoActualEnter1 == estadoActualEnter2)
  {
    // El código que sigue es idéntico al del anteerior ejemplo.
    if (estadoActualEnter1 != estadoUltimoEnter)
    {
      if (estadoActualEnter1 == HIGH)
      {
        contadorEnter = contadorEnter + 1;
        Serial.print (F("Esta es la pulsación OK / ENTER nº: "));
        Serial.println(contadorEnter);
      }
    }
  }
  estadoUltimoEnter = estadoActualEnter1;

  if (contadorEnter % 2 == 0)
  {
    digitalWrite(13, LOW);
    //Menu_Principal();
  }
  else
  {
    digitalWrite(13, HIGH);
    Menu_Principal();
  }
}

MenuPrincipal.h
C++:
void Menu_Principal()
{
  // Contador de teclas y navegador.
  int opcion = 0;
  bool salir = false;
  const int seleccionMenu = 8;

  // Capturar tecla para luego validar.


  // Limpiar pantalla.
  lcd.clear();

  // Capturar pulsador para luego validar.
  byte tecla;
  byte teclaArriba = digitalRead(A1);
  byte teclaAbajo = digitalRead(A2);

  do
  {
    //******************************************************************
    // Dibujo el menú principal.
    String MENSAJES[] =
    {
      "** MENU PRINCIPAL **", // Posición 0.
      "  ESTADO PRINCIPAL  ", // 1
      "  NOMBRE RELES      ", // 2
      "  NOMBRE SENSORES   ", // 3
      "  ENTRADA ANALÓGICA ", // 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.
    tecla = digitalRead(A5);

    // Validar el tipo de tecla.
    if (tecla == digitalRead(A5))
    {
      switch (opcion)
      {
        case 0:
          //
          break;
        case 1:
          //
          break;
        case 2:
          //OpcionC();
          break;
        case 3:
          //
          break;
        case 4:
          //
          break;
        case 5:
          //
          break;
        case 6:
          //
          break;
        case 7:
          //
          break;
        case 8:
          salir = true;
          break;
        default:
          lcd.print(F("Fuera de rango.     "));
          break;
      }
    }

    // Entonces si pulsas pulsador Abajo.
    //tecla = digitalRead(A2);
    else if (tecla == digitalRead(A2))
    {
      opcion++;
    }

    // Entonces si pulsas pulsador Arriba.
    //tecla = digitalRead(A1);
    else if (tecla == digitalRead(A1))
    {
      opcion--;
    }

    // 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);
}

Gracias por todo.
 

Adjuntos

  • LCD Menu con submenus Consola 01.zip
    4.9 KB · Visitas: 1
Ahora me fijo bien, pero lo ideal es mantener todo el texto como está, y solo modificar la "flecha" cuando sea necesario, asi como lo estas haciendo vas a consumir toda la memoria...
 
Hola, en lo personal, el uso de la fecha le doy un valor dentro de un array.
Por ejem. Si estoy dentro del menú principal y hay cuatro opciones. Entonces la flecha puede valer de 0 a 3.
Ahora sí estoy en un submenú, el cursor puede valer de 4 a 7 si hay cuatro opciones dentro de ese submenú. Y así aplicado al resto.
 
Buenas:

Metí los textos en el array y en la memoria Flash o memoria programa para que no se quede en la RAM. El símbolo > o flecha está dentro del array y así me ahorro consumo.

C++:
String MENSAJES[] =
    {
      "** MENU PRINCIPAL **", // Posición 0.
      "  ESTADO PRINCIPAL  ", // 1
      "  NOMBRE RELES      ", // 2
      "  NOMBRE SENSORES   ", // 3
      "  ENTRADA ANALÓGICA ", // 4
      "  CONFIGURACION     ", // 5
      "  ACERCA DE...      ", // 6
      "  AYUDA             ", // 7
      "  EXTRA             ", // 8
      "  INICIO            ", // 9
      "                    ", // 10
      ">"                     // 11
    };

La flecha está en la opción 11 del aray. Un ejemplo abajo.

C++:
lcd.setCursor(0, 1);     // Indica la posición de de la flecha.
lcd.print(MENSAJES[11]);   // Mostrar flecha en el LCD.

Saludos.
 
Última edición:
Buenas:

C++:
// 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

En C# para PC que se programa muy similar si funciona y este es su código.

C#:
using System;

namespace LCD_Menu_con_submenus_Consola_01
{
    public class MenuPrincipal
    {
        public static void Menu_Principal()
        {
            // Contador de teclas y navegador.
            int opcion = 0;
            bool salir = false;
            const int seleccionMenu = 8;

            // Capturar tecla para luego validar.
            ConsoleKey tecla;

            // Limpiar pantalla.
            Console.Clear();

            do
            {
                //******************************************************************
                // Dibujo el menú principal.

                // Cursor invisible.
                Console.CursorVisible = false;

                string[] MENSAJES =
                {
                    "** MENÚ PRINCIPAL **", // Posición 0.
                    "  ESTADO PRINCIPAL  ", // 1
                    "  NOMBRE RELÉS      ", // 2
                    "  NOMBRE SENSORES   ", // 3
                    "  ENTRADA ANALÓGICA ", // 4
                    "  CONFIGURACIÓN     ", // 5
                    "  ACERCA DE...      ", // 6
                    "  AYUDA             ", // 7
                    "  EXTRA             ", // 8
                    "  INICIO            ", // 9
                    "                    ", // 10
                    ">"                     // 11
                };

                switch (opcion)
                {
                    case 0:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[1]);         // > ESTADO PRINCIPAL 
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[2]);         //   NOMBRE RELÉS     
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[3]);         //   NOMBRE SENSORES   
                        break;

                    case 1:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[1]);         //   ESTADO PRINCIPAL 
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[2]);         // > NOMBRE RELÉS     
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[3]);         //   NOMBRE SENSORES   
                        break;

                    case 2:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[1]);         //   ESTADO PRINCIPAL 
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[2]);         //   NOMBRE RELÉS     
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[3]);         // > NOMBRE SENSORES   
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[11]);        // >
                        break;

                    case 3:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[4]);         // > ENTRADA ANALÓGICA     
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[5]);         //   CONFIGURACIÓN     
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[6]);         //   ACERCA DE...             
                        break;

                    case 4:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[4]);         //   ENTRADA ANALÓGICA     
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[5]);         // > CONFIGURACIÓN
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[6]);         //   ACERCA DE...
                        break;

                    case 5:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[4]);         //   ENTRADA ANALÓGICA
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[5]);         //   CONFIGURACIÓN
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[6]);         // > ACERCA DE...             
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[11]);        // >
                        break;

                    case 6:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[7]);         // > AYUDA
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[8]);         //   EXTRA     
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[9]);         //   INICIO             
                        break;

                    case 7:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[7]);         //   AYUDA     
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[8]);         // > EXTRA   
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[9]);         //   INICIO     
                        break;

                    case 8:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[7]);         //   AYUDA
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[8]);         //   EXTRA     
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[9]);         // > INICIO
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[11]);        // >
                        break;

                    default:
                        Console.Write("Fuera de rango.     ");
                        break;
                }

                // Fin de pintar el menú principal.
                //******************************************************************

                // Leer tecla ingresada por el usuario.
                tecla = Console.ReadKey(true).Key;

                // Validar el tipo de tecla.
                if (tecla == ConsoleKey.Enter)
                {
                    switch (opcion)
                    {
                        case 0:
                            EstadoPrincipal.Estado_Principal();
                            break;
                        case 1:
                            NombresReles.NombreReles_Principal();
                            break;
                        case 2:
                            //OpcionC();
                            break;
                        case 3:
                            //
                            break;
                        case 4:
                            //
                            break;
                        case 5:
                            //
                            break;
                        case 6:
                            //
                            break;
                        case 7:
                            //
                            break;
                        case 8:
                            salir = true;
                            break;
                        default:
                            break;
                    }
                }

                else if (tecla == ConsoleKey.DownArrow)
                {
                    opcion++;
                }

                else if (tecla == ConsoleKey.UpArrow)
                {
                    opcion--;
                }

                // 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);
        }
    }
}

Es muy similar, solo cambian los nombres de las instrucciones como estas. Ejemplo.

Arduino C:
C++:
        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;

C#:
C#:
                    case 0:
                        Console.SetCursorPosition(0, 0);
                        Console.Write(MENSAJES[0]);         // ** MENÚ PRINCIPAL **
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[1]);         // > ESTADO PRINCIPAL 
                        Console.SetCursorPosition(0, 1);
                        Console.Write(MENSAJES[11]);        // >
                        Console.SetCursorPosition(0, 2);
                        Console.Write(MENSAJES[2]);         //   NOMBRE RELÉS     
                        Console.SetCursorPosition(0, 3);
                        Console.Write(MENSAJES[3]);         //   NOMBRE SENSORES   
                        break;

Por lo que veo, en ARduino estoy metido en un blucle, por eso no hace caso. Com dices, solo se tiene que mostrar una vez.
Lo que pasa que dibujas mil veces las opciones, y no hace falta.
Simplemente dibuja las opciones, y despues con el "setCursor" moves (redibuja) la flecha, ahi si ahorras memoria...
De eso se trata. Algo se me escapa en Arduino C.
 
Última edición:
Puedes usar el cursor visible del LCD en lugar del signo mayor.
En ese caso basta con mover el cursor, no hay que "pintar" nada, y además puedes ocupar todos la línea con el texto del menú
 
Buenas:

Parece ser que me funciona, por fin. Voy a seguir avanzando en la parte de los nombres de los relés, que puedan introducirlos ustedes mismos y que se guarde en la EEPROM interna de Arduino. En la versión de consola C# crea un archivo de texto Archivo.txt y se guardan los datos, en Arduino con la tarjeta SD también se peude guardar con el archivo .txt si lo desean, pero es más electrónica.

Dejo el código hasta ahora por si alguien lo quieren probar en Arduino.

ARchivo *.ino.
Código:
// 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 = A1;
const byte ABAJO = A2;
const byte IZQUIERDA = A3;
const byte DERECHA = A4;
const 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(A1, INPUT); // Arriba.
  pinMode(A2, INPUT); // Abajo.
  pinMode(A3, INPUT); // Izquierda.
  pinMode(A4, INPUT); // Derecha.
  pinMode(A5, INPUT); // Ok / Enter.

  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)
  {
    Menu_Principal();
    Serial.println(estadoBotonEnter);
  }
  delay(50); // Para mayor estabilidad entre lecturas.
}

Archivo MenuPrincipal.h.
C++:
void Menu_Principal()
{
  // Contador de teclas y navegador.
  int opcion = 0;
  bool salir = false;
  const int seleccionMenu = 8;

  // Limpiar pantalla.
  lcd.clear();

  do
  {
    //******************************************************************
    // Dibujo el menú principal.
    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:
          //
          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);
}
Hola de nuevo:

Ahora necesito adaptar el código de C# a Arduino.

Buena gente.

Tengo una función de consola C# y quiero adaptarlo a Arduino, lo tengo a medias pero me fallan cosas. Sobre todo la pulsaciones de teclas y botones.

Espero tener ualguna ayuda.

Código C#:
Código:
using System;
using System.IO;

namespace LCD_Menu_con_submenus_Consola_01
{
    public class NombresReles
    {
        // Variables.
        static int coordenadaX = 0;         // Coordenada X del textBox del nombre del Relé.
        static int index = 0;               // Índice de ATRÁS y GUARDAR.
        static int 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;  // 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.
        static readonly char[] roALFANUMERICO = new char[]
        {
            '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.
        static readonly int[][] roINDICE_ARRAY = new int[][]
        {
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 },
            new int[] { 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 }
        };

        static readonly char[] roNUMERICO = new char[] { '1', '2', '3', '4', '5', '6', '7', '8' };
        static int roINDICE_NUMERICO = 0;

        public static void NombreReles_Principal()
        {
            ConsoleKey tecla, tecla2;
            int indice = 0;

            Inicio();

            while (true)
            {
                Console.CursorVisible = true; // Mostrar cursor.
                tecla = Console.ReadKey(true).Key;

                // ¿Has pulsado tecla flecha arriba?
                if (tecla == ConsoleKey.RightArrow) // Sí.
                {
                    if (textBox == 0)
                    {
                        Console.SetCursorPosition(4, 1);
                        textBox = 1;
                    }
                    else // textBox == 1
                    {
                        if (coordenadaX < 15)
                        {
                            coordenadaX++;
                            Console.SetCursorPosition(4 + coordenadaX, 1);
                        }
                    }
                }
                // Entonces. ¿Haz pulsado flecha izquierda?
                else if (tecla == ConsoleKey.LeftArrow) // Sí.
                {
                    if (textBox == 1)
                    {
                        if (coordenadaX > 0)
                        {
                            coordenadaX--;
                            Console.SetCursorPosition(4 + coordenadaX, 1);
                        }
                        else
                        {
                            Console.SetCursorPosition(2, 1);
                            textBox = 0;
                        }
                    }
                }
                // Entonces. ¿Haz pulsado flecha abajo?
                else if (tecla == ConsoleKey.DownArrow) // Sí.
                {
                    if (textBox == 0)
                    {
                        roINDICE_NUMERICO--;
                        if (roINDICE_NUMERICO < 0)
                        {
                            roINDICE_NUMERICO = 7;
                        }
                        Console.SetCursorPosition(2, 1);
                        Console.Write(roNUMERICO[roINDICE_NUMERICO]);
                        MostrarLineaNombre();
                        Console.SetCursorPosition(2, 1);
                    }
                    else // textBox == 1
                    {
                        roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]--;
                        if (roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] < 0)
                        {
                            roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] = 85;
                        }
                        Console.Write(roALFANUMERICO[roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]].ToString());
                        Console.SetCursorPosition(4 + coordenadaX, 1);
                    }
                }
                // Entonces. ¿Haz pulsado flecha arriba?
                else if (tecla == ConsoleKey.UpArrow) // Sí.
                {
                    if (textBox == 0)
                    {
                        roINDICE_NUMERICO++;
                        if (roINDICE_NUMERICO >= 8)
                        {
                            roINDICE_NUMERICO = 0;
                        }
                        Console.SetCursorPosition(2, 1);
                        Console.Write(roNUMERICO[roINDICE_NUMERICO]);
                        MostrarLineaNombre();
                        Console.SetCursorPosition(2, 1);
                    }
                    else // textBox == 1
                    {
                        roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]++;
                        if (roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] > 85) // Acá es > 85 (o >= 86) porque 86 es la cantidad
                        {                                                        // total y al alcanzarla ahí paso al comienzo (0)
                            roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] = 0;
                        }
                        Console.Write(roALFANUMERICO[roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]].ToString());
                        Console.SetCursorPosition(4 + coordenadaX, 1);
                    }
                }
                // Entonces. ¿Haz pulsado la tecla Enter?
                else if (tecla == ConsoleKey.Enter) // Sí.
                {
                    Console.CursorVisible = false;
                    Console.SetCursorPosition(0, 3);
                    Console.Write("> ATRÁS     GUARDAR ");
                    index = 0;
                    while ((tecla2 = Console.ReadKey(true).Key) != ConsoleKey.Enter)
                    {
                        if ((tecla2 == ConsoleKey.RightArrow) || (tecla2 == ConsoleKey.LeftArrow))
                        {
                            index = 1 - index;  // Si vale 0 valdrá 1, si vale 1 valdrá 0.
                            Console.SetCursorPosition(0, 3);
                            if (index == 0)
                            {
                                Console.Write("> ATRÁS     GUARDAR ");
                            }
                            else
                            {
                                Console.Write("  ATRÁS   > GUARDAR ");
                            }
                        }
                    }
                    if (index == 1)  // Se pulsó Enter en Guardar.
                    {
                        nombresDeLosReles = new string[8];
                        for (int a = 0; a < 8; a++)
                        {
                            for (int b = 0; b < 16; b++)
                            {
                                nombresDeLosReles[a] += roALFANUMERICO[roINDICE_ARRAY[a][b]].ToString();
                            }
                        }

                        // Guardar archivo de texto con los nombres de los relés.
                        File.WriteAllLines("NombresReles.txt", nombresDeLosReles);

                        // 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á.
                        Console.Clear();
                        Console.SetCursorPosition(2, 1);
                        Console.Write("Haz guardado:");
                        Console.SetCursorPosition(2, 3);
                        Console.Write((indice + 1).ToString());
                        Console.SetCursorPosition(4, 3);
                        Console.Write(nombresDeLosReles[indice]);

                        // Mientras no pulses la tecla Enter, sigue las demás intrucciones.
                        while ((tecla2 = Console.ReadKey(true).Key) != ConsoleKey.Enter)
                        {
                            // ¿Haz pulsado flecha arriba?
                            if (tecla2 == ConsoleKey.UpArrow) // 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 (tecla2 == ConsoleKey.DownArrow) // Sí.
                            {
                                indice++; // Incrementa la variable indice.
                                // ¿indice es mayor o igual que 8?
                                if (indice >= 8) // Sí.
                                {
                                    indice = 0;
                                }
                            }
                            Console.SetCursorPosition(2, 3);
                            Console.Write((indice + 1).ToString());
                            Console.SetCursorPosition(4, 3);
                            Console.Write(nombresDeLosReles[indice]);
                        }
                        Inicio();
                    }
                    else if (index == 0)
                    {
                        break;
                    }
                }
            }
        }

        static void Inicio()
        {
            Console.SetWindowSize(20, 5);                   // Establece el ancho y alto de la ventana.
            Console.Clear();                                // Limpiar ventana.
            Console.SetCursorPosition(2, 0);                // Posición del cursor.
            Console.Write("Nombre de Relés:    ");
            Console.SetCursorPosition(0, 3);
            Console.Write("  ATRÁS     GUARDAR ");

            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] != roALFANUMERICO[c]; c++)
                            {
                                ;
                            }
                            roINDICE_ARRAY[a][b] = c;
                        }
                    }
                }
                cargado = true;
            }
            MostrarLineaNombre();
            Console.SetCursorPosition(2, 1);
            Console.Write(roNUMERICO[roINDICE_NUMERICO]);
            if (textBox == 0)
            {
                Console.SetCursorPosition(2, 1);
            }
            else
            {
                Console.SetCursorPosition(4 + coordenadaX, 1);
            }
        }

        static void MostrarLineaNombre()
        {
            Console.SetCursorPosition(4, 1);
            for (int a = 0; a < 16; a++)
            {
                Console.Write(roALFANUMERICO[roINDICE_ARRAY[roINDICE_NUMERICO][a]]);
            }
        }
    }
}

Código C de Arduino:
Código:
// Variables.
int coordenadaX = 0;          // Coordenada X del textBox del nombre del Relé.
int index = 0;                // Índice de ATRÁS y GUARDAR.
int textBox = 0;              // 0 para el número de Relé (de 1 al 8) y 1 para el texto del Relé (16 char).
//String[] nombresDeLosReles; // 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.
char roALFANUMERICO[] =
{
  '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.
int roINDICE_ARRAY[][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 }
};

char roNUMERICO[] = { '1', '2', '3', '4', '5', '6', '7', '8' };
int roINDICE_NUMERICO = 0;

void NombreReles_Principal()
{
  ConsoleKey tecla, tecla2;
  int indice = 0;

  Inicio();

  while (true)
  {
    lcd.cursor(); // Mostrar cursor.
    lcd.blink();  // Cursosr parpadeando.
    tecla = Console.ReadKey(true).Key;

    // ¿Has pulsado tecla flecha arriba?
    if (tecla == 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 (tecla == 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 (tecla == digitalRead(A2)) // Sí.
    {
      if (textBox == 0)
      {
        roINDICE_NUMERICO--;
        if (roINDICE_NUMERICO < 0)
        {
          roINDICE_NUMERICO = 7;
        }
        lcd.setCursor(2, 1);
        lcd.print(roNUMERICO[roINDICE_NUMERICO]);
        MostrarLineaNombre();
        lcd.setCursor(2, 1);
      }
      else // textBox == 1
      {
        roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]--;
        if (roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] < 0)
        {
          roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] = 85;
        }
        lcd.print(roALFANUMERICO[roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]].ToString());
        lcd.setCursor(4 + coordenadaX, 1);
      }
    }
    // Entonces. ¿Haz pulsado flecha arriba?
    else if (tecla == digitalRead(A1)) // Sí.
    {
      if (textBox == 0)
      {
        roINDICE_NUMERICO++;
        if (roINDICE_NUMERICO >= 8)
        {
          roINDICE_NUMERICO = 0;
        }
        lcd.setCursor(2, 1);
        lcd.print(roNUMERICO[roINDICE_NUMERICO]);
        MostrarLineaNombre();
        lcd.setCursor(2, 1);
      }
      else // textBox == 1
      {
        roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]++;
        if (roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] > 85) // Acá es > 85 (o >= 86) porque 86 es la cantidad
        { // total y al alcanzarla ahí paso al comienzo (0)
          roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX] = 0;
        }
        lcd.print(roALFANUMERICO[roINDICE_ARRAY[roINDICE_NUMERICO][coordenadaX]].ToString());
        lcd.setCursor(4 + coordenadaX, 1);
      }
    }
    // Entonces. ¿Haz pulsado la tecla Enter?
    else if (tecla == digitalRead(A5)) // Sí.
    {
      lcd.cursor();   // Ocultar cursor.
      lcd.noBlink();  // Sin parpadeos el cursor.
      lcd.setCursor(0, 3);
      lcd.print("> ATRÁS     GUARDAR ");
      index = 0;
      while ((tecla2 = Console.ReadKey(true).Key) != digitalRead(A5))
      {
        if ((tecla2 == digitalRead(A4)) || (tecla2 == digitalRead(A3)))
        {
          index = 1 - index;  // Si vale 0 valdrá 1, si vale 1 valdrá 0.
          lcd.setCursor(0, 3);
          if (index == 0)
          {
            lcd.print("> ATRÁS     GUARDAR ");
          }
          else
          {
            lcd.print("  ATRÁS   > GUARDAR ");
          }
        }
      }
      if (index == 1)  // Se pulsó Enter en Guardar.
      {
        nombresDeLosReles = new String[8];
        for (int a = 0; a < 8; a++)
        {
          for (int b = 0; b < 16; b++)
          {
            nombresDeLosReles[a] += roALFANUMERICO[roINDICE_ARRAY[a][b]].ToString();
          }
        }

        // 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("Haz guardado:");
        lcd.setCursor(2, 3);
        lcd.print((indice + 1).ToString());
        lcd.setCursor(4, 3);
        lcd.print(nombresDeLosReles[indice]);

        // Mientras no pulses la tecla Enter, sigue las demás intrucciones.
        while ((tecla2 = Console.ReadKey(true).Key) != digitalRead(A5))
        {
          // ¿Haz pulsado flecha arriba?
          if (tecla2 == 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 (tecla2 == 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).ToString());
          lcd.setCursor(4, 3);
          lcd.print(nombresDeLosReles[indice]);
        }
        Inicio();
      }
      else if (index == 0)
      {
        break;
      }
    }
  }
}

void Inicio()
{
  //Console.SetWindowSize(20, 5);                   // Establece el ancho y alto de la ventana.
  lcd.clear();                                // Limpiar ventana.
  lcd.setCursor(2, 0);                // Posición del cursor.
  lcd.print("Nombre de Relés:    ");
  lcd.setCursor(0, 3);
  lcd.print("  ATRÁS     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] != roALFANUMERICO[c]; c++)
            {
              ;
            }
            roINDICE_ARRAY[a][b] = c;
          }
        }
      }
      cargado = true;
    }
  */
  //#########################################################################################

  MostrarLineaNombre();
  lcd.setCursor(2, 1);
  lcd.print(roNUMERICO[roINDICE_NUMERICO]);
  if (textBox == 0)
  {
    lcd.setCursor(2, 1);
  }
  else
  {
    lcd.setCursor(4 + coordenadaX, 1);
  }
}

void MostrarLineaNombre()
{
  lcd.setCursor(4, 1);
  for (int a = 0; a < 16; a++)
  {
    lcd.print(roALFANUMERICO[roINDICE_ARRAY[roINDICE_NUMERICO][a]]);
  }
}

Falla en el almacenamiento o detección de botones de Arduino que no se como se hace como en C#.

Gracias.
 
Última edición:
Arriba