Parámetros que no se pasan correctamente a la funcion

Hola de nuevo, hoy os escribo porque me pasa algo que no alcanzo a entender y seguro que es una tontería pero llevo media tarde con esto y no sé ni como buscar lo que me pasa en Google.

Para ponernos en situación, he creado una función con varios parámetros, todos se pasan correctamente salvo dos, que en vez de pasar el valor de la variable me pasa ¿La posición :sweat_smile: ?. Es decir, si ne la función pongo primero atrás y luego siguiente, atrás me vale 2 y siguiente 3, y si lo pongo al revés siguiente me vale 2 y atrás 3. Nunca ne mi vida me había pasado algo parecido y no tiene sentido ninguno, no me llego a imaginar qué está pasando.

Os paso el código a ver si veis el error o qué hago mal o qué puede ser lo que sea que me esté pasando.

char Menu_texto(char cad_1[21], char cad_2[], unsigned int *menu, int maximo, int siguiente, int atras){ 
Imprimir(cad_1, cad_2, 0);

 char key;

while(!(key=='*' || key=='#' || (key> 48 && key<(58-(10-maximo))))){ //Mientras no le demos al teclado un valor válido, Ponemos (58-(10-maximo)) para acotar la entrada
  key = keypad.getKey(); 
}

switch (key) {
          case '*':
            *menu=siguiente;
            lcd.setCursor(0,2);
  lcd.print("Siguiente");
  delay(300);
            break;
          case '#':
            *menu=atras;
            lcd.setCursor(0,2);
  lcd.print("Atras");
  delay(300);
            break;
          default:
            *menu=key-48;
            lcd.setCursor(0,2);
  lcd.print(*menu, DEC);
  delay(300);
      }
      lcd.setCursor(0,2);
      lcd.print(*menu,DEC);
 delay(300);
return key;
}  

void setup() {
  lcd.begin(20,4); // Indicamos al micro el n�mero de filas y columnas del display
  lcd.display();
}



void loop() {

unsigned int menu;
char key=1;

 

switch (menu) {
    case 1:
      Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,'51',8);
              lcd.setCursor(1,2);
      lcd.print(menu,DEC);
 delay(300);
      break;
    case 2:
      Menu_texto("Menu principal", "2)Secuencuas", &menu,3,3,1);
      break;
    default:
      Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,3,2);
}
if (menu>=10){

}

}

Muchas gracias a todos de antemano y feliz navidad !

Saludos
Ante todo deberías leer las normas del foro. Para introducir un código debes usar los tags

Ejemplo

char Menu_texto(char cad_1[21], char cad_2[], unsigned int *menu, int maximo, int siguiente, int atras){ 
 Imprimir(cad_1, cad_2, 0);

  char key;

 while(!(key=='*' || key=='#' || (key> 48 && key<(58-(10-maximo))))){ //Mientras no le demos al teclado un valor válido, Ponemos (58-(10-maximo)) para acotar la entrada
   key = keypad.getKey(); 
 }
 
 switch (key) {
           case '*':
             *menu=siguiente;
             lcd.setCursor(0,2);
   lcd.print("Siguiente");
   delay(300);
             break;
           case '#':
             *menu=atras;
             lcd.setCursor(0,2);
   lcd.print("Atras");
   delay(300);
             break;
           default:
             *menu=key-48;
             lcd.setCursor(0,2);
   lcd.print(*menu, DEC);
   delay(300);
       }
       lcd.setCursor(0,2);
       lcd.print(*menu,DEC);
  delay(300);
 return key;
}  

void setup() {
   lcd.begin(20,4); // Indicamos al micro el n�mero de filas y columnas del display
   lcd.display();
}



void loop() {
 
 unsigned int menu;
 char key=1;

  

 switch (menu) {
     case 1:
       Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,'51',8);
               lcd.setCursor(1,2);
       lcd.print(menu,DEC);
  delay(300);
       break;
     case 2:
       Menu_texto("Menu principal", "2)Secuencuas", &menu,3,3,1);
       break;
     default:
       Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,3,2);
 }
 if (menu>=10){

 }

}

Ahora me imagino que estas apenas probando tu funcion porque como modificas "menú" en el loop?
Para que colocas &menu pudiendo colocar solo menú, y si vas a enviar un entero porque colocas '51'?

En menu_texto no coloques *menu solo menu. Y prueba. Además donde esta la función imprime()?

Hola amigo, gracias por responder, siento haber pegado el código así, lo modifico y lo dejo correcto.

Coloco &menu en el loop y *menu en la función para hacer un paso por referencia de una variable local a la otra función y así evito crear una variable global menú.
El '5' lo he puesto para probar otra manera y pasar un carácter que al fin y al cabo es como un entero.

Imprime es esta función, pero no interviene:

void Imprimir(char cad_1[21], char cad_2[], int mostrar_numero){

  int i=0;
    lcd.clear();
    lcd.setCursor(i,0);
    lcd.print(cad_1);
    lcd.setCursor(i,1);
    lcd.print(cad_2);
    if (mostrar_numero==1){ // Así podemos elegir si se muestra el número o no
	    lcd.setCursor(i,2);
	    lcd.print(numero, DEC);
	}
    lcd.setCursor(i,3);
    lcd.print("Atras");
    lcd.setCursor(11+i,3);
    lcd.print("Siguiente");

}

A ver si ahora están bien los tags ahora :slight_smile:

Alguna sugerencia más? Gracias a todos.

Saludos
Es que no necesitas declarar una variable global si entre los parámetros pasas una variable local a una función a través de sus argumentos. Es decir no importa si es local el pasa el valor. O por lo menos así me funciona.

Hola de nuevo, gracias por responder.

A ver, el valor a la función se pasa pero al volver al loop menu se queda con el valor inicial, el que tenía en el loop de antes de llamar a la función, no con el valor que tenía en la función y como una función sólo puede devolver un valor pues es la única manera que se me ocurre de hacerlo.

No sé si me me explico.

Un saludo.

Si posteas un código por favor que sea el código que estas usando no partes de el.
Tu primer post al compilarlo salta que falta imprimir() que luego agregaste.
Ahora sumo la función imprimir() y falta la librería keypad.h

Entonces??

Porque no subes tu código completo, lo revisas, ves si compila y luego intentamos resolver tus errores?

Está plagado de errores, falta keypad, falta la definición del display, hay errores menores al compilar.

Bueno ya agregué todo lo que faltaba, y lo estoy simulando.
EL único problema que falta es número en tu rutina imprimir().
numero no esta definido y no se que pretendes mostrar en el display

También te faltó explicar que

  • va hacia adelante en el menú

va hacia atras

Este código al menos compila y hasta ahora presenta los datos pero no avanza.

#include <Keypad.h>
// include the library code:
#include <LiquidCrystal.h>

// For phi-1 shield LCD_D7 is 4. For phi-2 shield LCD_D7 is 3
#define LCD_RS 8
#define LCD_EN 6
#define LCD_D4 12
#define LCD_D5 11
#define LCD_D6 10
#define LCD_D7 9

LiquidCrystal lcd(LCD_RS,LCD_EN,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // Create the lcd object

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  { '1','2','3' },
  { '4','5','6' },
  { '7','8','9' },
  { '*','0','#' }
};
byte rowPins[ROWS] = {  2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {  A3, A4, A5}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char Menu_texto(char cad_1[21], char cad_2[], unsigned int *menu, int maximo, int siguiente, int atras){ 
  Imprimir(cad_1, cad_2, 0);

  char key;

  while(!(key=='*' || key=='#' || (key> 48 && key<(58-(10-maximo))))){ //Mientras no le demos al teclado un valor válido, Ponemos (58-(10-maximo)) para acotar la entrada
    key = keypad.getKey(); 
  }

  switch (key) {
  case '*':
    *menu=siguiente;
    lcd.setCursor(0,2);
    lcd.print("Siguiente");
    delay(300);
    break;
  case '#':
    *menu=atras;
    lcd.setCursor(0,2);
    lcd.print("Atras");
    delay(300);
    break;
  default:
    *menu=key-48;
    lcd.setCursor(0,2);
    lcd.print(*menu, DEC);
    delay(300);
  }
  lcd.setCursor(0,2);
  lcd.print(*menu,DEC);
  delay(300);
  return key;
}  


void Imprimir(char cad_1[21], char cad_2[], int mostrar_numero){
  int i=0;
  lcd.clear();
  lcd.setCursor(i,0);
  lcd.print(cad_1);
  lcd.setCursor(i,1);
  lcd.print(cad_2);
  if (mostrar_numero == 1){ // Así podemos elegir si se muestra el número o no
    int numero = 1; 
    lcd.setCursor(i,2);
    lcd.print(numero, DEC);  // ERROR aca agregué algo forzado pero no se que se espera imprimir
  }
  lcd.setCursor(i,3);
  lcd.print("Atras");
  lcd.setCursor(11+i,3);
  lcd.print("Siguiente");

}

void setup() {
  lcd.begin(20,4); // Indicamos al micro el n�mero de filas y columnas del display
  lcd.display();
}



void loop() {

  unsigned int menu;
  char key = 1;

  switch (menu) {
  case 1:
    Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,'51',8);
    lcd.setCursor(1,2);
    lcd.print(menu,DEC);
    delay(300);
    break;
  case 2:
    Menu_texto("Menu principal", "2)Secuencuas", &menu,3,3,1);
    break;
  default:
    Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,3,2);
  }
  if (menu>=10){
  }
}

Ahora a ver el error que consulta en el post Nro 1

Yo de entrada lo que veo es que en esta llamada que haces:

Menu_texto("Menu principal", "1)Prog. sec.", &menu,3,'51',8)

se va a confundir el fin de parentesis despues del 1 con el de final de la llamada a funcion ,creo que en estos casos debe ir antecedido por una barra invertida ) y no se si ese '51' entre comillas sera valido cuando la variable siguiente es int.

Te aseguro que esa llamada no da error pero el programa aun tiene trabajo pendiente

Saludos

Cada vez que tu defines una variable como lo haces aqui:

void loop() {

  unsigned int menu;
...

el valor de esta variable se inicia tambien.
La unica forma que puedes mantenerla asi es utilizando un bucle while luego de iniciada algo como:

#include <Keypad.h>
// include the library code:
#include <LiquidCrystal.h>

// For phi-1 shield LCD_D7 is 4. For phi-2 shield LCD_D7 is 3
#define LCD_RS 8
#define LCD_EN 6
#define LCD_D4 12
#define LCD_D5 11
#define LCD_D6 10
#define LCD_D7 9

LiquidCrystal lcd(LCD_RS,LCD_EN,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // Create the lcd object

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  { '1','2','3' },
  { '4','5','6' },
  { '7','8','9' },
  { '*','0','#' }
};
byte rowPins[ROWS] = {  2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {  A3, A4, A5}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char Menu_texto(char cad_1[21], char cad_2[], unsigned int &menu, int maximo, int siguiente, int atras){ 
  Imprimir(cad_1, cad_2, 0);

  char key;

  while(!(key=='*' || key=='#' || (key> 48 && key<(58-(10-maximo))))){ //Mientras no le demos al teclado un valor válido, Ponemos (58-(10-maximo)) para acotar la entrada
    key = keypad.getKey(); 
  }

  switch (key) {
  case '*':
    menu=siguiente;
    lcd.setCursor(0,2);
    lcd.print("Siguiente");
    delay(300);
    break;
  case '#':
    menu=atras;
    lcd.setCursor(0,2);
    lcd.print("Atras");
    delay(300);
    break;
  default:
    menu=key-48;
    lcd.setCursor(0,2);
    lcd.print(*menu, DEC);
    delay(300);
  }
  lcd.setCursor(0,2);
  lcd.print(menu,DEC);
  delay(300);
  return key;
}  


void Imprimir(char cad_1[21], char cad_2[], int mostrar_numero){
  int i=0;
  lcd.clear();
  lcd.setCursor(i,0);
  lcd.print(cad_1);
  lcd.setCursor(i,1);
  lcd.print(cad_2);
  if (mostrar_numero == 1){ // Así podemos elegir si se muestra el número o no
    int numero = 1; 
    lcd.setCursor(i,2);
    lcd.print(numero, DEC);  // ERROR aca agregué algo forzado pero no se que se espera imprimir
  }
  lcd.setCursor(i,3);
  lcd.print("Atras");
  lcd.setCursor(11+i,3);
  lcd.print("Siguiente");

}

void setup() {
  lcd.begin(20,4); // Indicamos al micro el n�mero de filas y columnas del display
  lcd.display();
}


boolean iniciado=false;
void loop() {

	unsigned int menu;
	char key = 1;
	if(iniciado==fale){
		menu=0;
		iniciado=true;
	}
	while(iniciado){
	  switch (menu) {
	  case 1:
	    Menu_texto("Menu principal", "1)Prog. sec.", menu,3,'51',8);
	    lcd.setCursor(1,2);
	    lcd.print(menu,DEC);
	    delay(300);
	    break;
	  case 2:
	    Menu_texto("Menu principal", "2)Secuencias", menu,3,3,1);
	    break;
	  default:
	    Menu_texto("Menu principal", "1)Prog. sec.", menu,3,3,2);
	  }
	  if (menu>=10){
	  }
	}
}

Date cuenta que modifique la forma en que envias menu y como la recibes como argumento en Menu_texto, ya que estabas usando una forma para C y no para C++.

Hola.
Sin entrar en pormenores sobre lo que estás tratando de hacer, que se me antoja un tanto enrevesado, te comento cómo creo que deberías declarar y pasar parámetros a la función:

  • DECLARACIÓN: char Menu_texto(char *cad_1, char *cad_2, unsigned int &menu, int maximo, int siguiente, int atras){
  • EJEMPLO DE LLAMADA: Menu_texto("Menu principal", "2)Secuencias", menu,3,3,1);

Dentro de la función Menu_texto, no hace falta que utilices *menu, sino menu a secas. Lo que hace la declaración de la función "unsigned int &menu" es tomar por referencia el parámetro.

A menos que sea una tarea del colegio o de la universidad, no veo para que reinventar la rueda con las buenas librerías de menú que existen.
Deberías considerar si vale el esfuerzo en caso de NO hacerlo por hobby.

Surbyte pienso igual, pero este planteamiento me ha hecho estudiar un poco mas. Yo nunca había trabajado con C++ hasta hace unos meses que comencé con Arduino.

He aprendido a pasar punteros a una función y no el valor como tal. Entre otras cosas

En lo que veo de entrada es que usa punteros en la funcion de imprimir y le asigna mal los valores.

Los punteros simplifican el programa y suponen una reduccion importante en el consumo de meroria, pero siempre hay un pero, esto puede ocasionar un desastre si no se es prolijo en el codigo.

aqui hay una explicacion de punteros