No funciona comandos del LCD en funciones externas [SOLUCIONADO]

Buenas gente.

Haber que se me escapa, ya que no puedo mostrar textos en el LCD en un archivo a parte del proyecto llamado MenuPrincipal.h y está declarado en el programa principal.

Hasta tube que poner otra vez el:

// Include el código de la librería.
#include <LiquidCrystal.h>

Por si acaso y nada.

Quiero que me ejecute este comando y me sale error.

  // Limpiar pantalla.
  lcd.clear();

El error.

'lcd' was not declared in this scope

Función completa.

// Include el código de la librería.
#include <LiquidCrystal.h>

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[] =
    {
      "** 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:
        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;
    }
  } while (salir == false);
}

Con ese trozo solo se puede intentar adivinar, publica el codigo completo.
saludos.

Código principal.

No está del todo pulido, ya que solo tiene que llamar la función Menu_Principal(); desde que pulse el pulsador digitalRead(A5);

// Include el código de la librería.
#include <LiquidCrystal.h>
#include "MenuPrincipal.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);

// Pin 10 para saber que es luz de fondo.
//const byte LuzFondo = 10;

// Variables.
// 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_PULLUP); // Arriba.
  pinMode(A2, INPUT_PULLUP); // Abajo.
  pinMode(A3, INPUT_PULLUP); // Izquierda.
  pinMode(A4, INPUT_PULLUP); // Derecha.
  pinMode(A5, INPUT_PULLUP); // 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 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);
  }
  else
  {
    digitalWrite(13, HIGH);
    Menu_Principal();
  }
}

Lo siento pero en el tema de crear librerias me pierdo. ¿Pero porque hacer esa simple funcion una libreria y no añadirla al codigo principal como una simple funcion mas? Si asi lo haces compila perfectamente y no da ningun error.

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

// Pin 10 para saber que es luz de fondo.
//const byte LuzFondo = 10;

// Variables.
// 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_PULLUP); // Arriba.
  pinMode(A2, INPUT_PULLUP); // Abajo.
  pinMode(A3, INPUT_PULLUP); // Izquierda.
  pinMode(A4, INPUT_PULLUP); // Derecha.
  pinMode(A5, INPUT_PULLUP); // 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 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);
  }
  else
  {
    digitalWrite(13, HIGH);
    Menu_Principal();
  }
}


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[] =
    {
      "** 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:
        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;
    }
  } while (salir == false);
}

El código que vez a simple vista de una función, en realidad se trata de hacer un Menú con submenús y no será precisamente pequeño. Ya que está debe estar muy bien organizado, por eso se usa así, para dejar el código lo más organizado posible. De ese se trata, dejar el proyecto bien organizado.

Tengo que averiguar como funciona los LCD en una función a parte, es decir, en otro archivo.

Saludos.

EDIT:
Aquí se muestra como se hace lo del archivo externo para funciones externas, pero claro, con el LCD externo no furula. Xddddddd.

https://forum.arduino.cc/t/crear-funciones-externos-solucionado/667744/3

Saludos.

Y porque no usas las librerías de Menúes que ya existen? Cuando leo a foreros que una y otra vez se atascan en este tema, me pregunto lo mismo, para que gastar tantas horas de su tiempo y el nuestro reinventando la rueda?
Busca LCDMenuLib2 y asunto resuelto.
Si, hay que dedicarle un tiempo pero cada vez que hagas algo con menues y sube menúes lo tienes resuelto de un modo profesional.
Tienes entrada por teclas 3,4 y hasta 6 botones, por terminarl Serie, por BT, por encoder, y alguno otro modo de ingreso que olvido.
image
image

Dedicale un momento @Metaconta, tal vez te ahorre buen tiempo.

Buenas:

Porque me gusta hacerlo desde cero por mi mismo. El diseño lo tengo hecho en C# modo consola y lo quiero adaptar a Arduino. No quiero depender de librerías de terceros al menos en LCD ya que con el tiempo, ni funcionarán o problemas de compatibilidad entre otras cosas. También porque soy terco, xddddddd.

Aún así, quiero saber la manera de que el lcd.clear(); me funcione en archivos.h.

Si no me fallase esto en Arduino, ya estaría hecho una parte. En C# no falla.

Saludos.

No lo haces por ti mismo, porque vienes al foro a preguntar. Asi que me parece un contrasentido de tu parte.
Estas en todo tu derecho de hacerlo como quieras.

Es manera de hablar. Porque me estanqué.

En el lcd.print no se el motivo, se me queja en el otro archivo esterno cuando la función es la misma, y si funciona si está en laprincipal.

Me sale este mensaje.

'lcd' was not declared in this scope

¿Y no está declarado desde el principio?
Si hago lo mismo en el archivo externo llamado MenuPrincipal.h poniendo la librería #include <LiquidCrystal.h>

Tampoco funciona.

Saludos.

Ahh pero MenuPrincipal.h no tiene referencia al objeto lcd que esta en el sketch principal.
El archivo MenuPrincipal.h donde esta? En el post#4 se ve.

En el post#4, el compañero lo ha puesto todo en un mismo archivo, en el proyecto principal. Si el programa fuese corto, me da igual. El programa será largo y hay que organizarlo, para eso se pone todo fuera. La cuestión es.

¿Cómo logro que muestre los lcd.print en el archivo secundario?

No esperaba que Arduino me diera quebradero de cabeza en este aspecto.

Ya que dice: 'lcd' was not declared in this scope

Entonces. ¿Cómo se declara lcd?

Al final el lcd tiene que mostrar este menú principal cuando acabe el código completo de esta parte.

Menú 01

Gracias. :wink:

Edito:
Ya funciona.

// 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, 9, 4, 5, 6, 7);

#include "MenuPrincipal.h"

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.