Problemas al guardad el ID de los usuarios en una matriz bidimensional

Hola, amigos tengo un problema espero que me ayuden resulta que estoy haciendo un proyecto en el cual el usuario escribe su ID de 4 digitos como maximo y minimo 1 digito.

Si el usuario digita su ID (ya sea menor o igual a 4 digitos) y preciona # busca en el sistema si el usuario existe o no.

Si no exite guarda y si existe muestra un mensaje diciendo que el usuario existe.

Al momento de digitar un ID por ejemplo ‘1’ el sistema lo guarda correctamente, al digitar un ID ‘2’ por ejemplo guarda bien y así sucesivamente…

Si se vuelve a digitar ya sea el ID ‘1’ u ‘2’ el sistema lo detecta correctamente y muestra el mensaje de usuario existente.

Problema:

(Continuación del ejemplo anterior) El problema resulta que cuando el usuario digita un ID mayor de un digito por ejemplo ‘2’ ‘3’ (ID: 23) este guarda normalmente, y si luego preciona los ids que anteriormente guardamos ‘1’ y ‘2’ no detecta la existencia de este y los vuelve a guardar.

void loop() {
int estado;
menu:
lcd.clear();
lcd.setCursor(0,0); lcd.print("ingrese ID"); //Imprime en la lcd      


 for(int i=0; i<6; i++){
    char kp = Teclado (); //Obtiene el valor de la tecla pulsada
    contrasena_ingresada[i]=kp; //Guardar la tecla pulsada en la Matriz "Tecla pulsada"
    if(contrasena_ingresada[i]=='#'){ break;} 
    lcd.setCursor(5+i,3); lcd.print(contrasena_ingresada[i]); //Imprime en la lcd                     
}

if ((contrasena_ingresada[1] == '#') || (contrasena_ingresada[2] == '#') || (contrasena_ingresada[3] == '#') || (contrasena_ingresada[4] == '#') || (contrasena_ingresada[5] == '#')){
  for(int i=0; i<10; i++){ //Filas
    
    if((contrasena_guardada[i][0] == contrasena_ingresada [0]) && (contrasena_guardada[i][1] == contrasena_ingresada [1]) && (contrasena_guardada[i][2] == contrasena_ingresada [2]) && (contrasena_guardada[i][3] == contrasena_ingresada [3]) && (contrasena_guardada[i][4] == contrasena_ingresada [4])){ 
      estado = 1;
      break;      
    }

    if(i == 9){ //Si al llegar a la ultima fila no coinciden ningunas de las contraseña muestra el mensaje "INCORRECTO" //------- Esta condicion es el con el fin de que una vez que haya realizada la busqueda en la matriz contrasena_guardada y ninguna coincida ejecute la siguiente instruccion
      estado = 2;
     }
   }


switch (estado){
  case 1:
      estado = 0;
      lcd.clear ();
      lcd.setCursor(0,0); lcd.print("USUARIO"); 
      lcd.setCursor(0,1); lcd.print("EXISTENTE");
      delay(300);
      if(estado==1){goto menu;}
      estado = 0;
  break;


  case 2:
      estado = 0;
      for(int i=0; i<10; i++){
          if((contrasena_guardada[i][0]== 0x00) && (contrasena_guardada[i][1]== 0x00) && (contrasena_guardada[i][2]== 0x00) && (contrasena_guardada[i][3]== 0x00) && (contrasena_guardada[i][4]== 0x00)){ //Si se encuentra vacio guarda
            for(int j=0; j<5; j++){
              contrasena_guardada[i][j] = contrasena_ingresada [j];
              lcd.clear ();
              lcd.setCursor(0,0); lcd.print("Guardando");
              delay(100);
              }
              break;
           } 
        }
        goto menu;  
      
 break;
} 
}

lcd.clear (); lcd.setCursor(0,0); lcd.print("FIN"); delay(200);

}

Nota:

Estoy seguro que funciona bien cuando se guardan IDs de mismas cantidades de digitos ejemplo:

123
345
123
125

el sistema los detecta bien.

pero al guardar un ID mayor a esos digitos ejemplo: 1234, no detecta los otros ids y se tienen que volver a guardar.

Pienso que esta condicion esta fallando:

if((contrasena_guardada[i][0] == contrasena_ingresada [0]) && (contrasena_guardada[i][1] == contrasena_ingresada [1]) && (contrasena_guardada[i][2] == contrasena_ingresada [2]) && (contrasena_guardada[i][3] == contrasena_ingresada [3]) && (contrasena_guardada[i][4] == contrasena_ingresada [4]))

pero no se como mejorarla.

Adjunto la simulación.

Muchas gracias por su ayuda sinceramente.

por que no comienzas explicando un poco mejor lo que quieres conseguir ,para poder afinar el sketch? te lo digo por ejemplo por el uso de goto ,que esta obsoleto y no se si cuadra bien con la manera de funcionar de arduino,o por los datos que quieres guardar en el array ,por ejemplo si solo vas a guardar el id ,no necesitas un array bidimensional que complica la programacion ,etc ,etc

jose:
por que no comienzas explicando un poco mejor lo que quieres conseguir ,para poder afinar el sketch? te lo digo por ejemplo por el uso de goto ,que esta obsoleto y no se si cuadra bien con la manera de funcionar de arduino,o por los datos que quieres guardar en el array ,por ejemplo si solo vas a guardar el id ,no necesitas un array bidimensional que complica la programacion ,etc ,etc

Hola, jose lo que con respecto a la programación es solo una parte de un programa mas largo.

Lo que pasa es que quiero guardar el ID de un usuario y su contraseña, en la cual, el usuario ingresa su ID (tiene que ser menor de 5 digitos, puede que sea 1, 2, 3, 4 digitos)

cuando el usuario ingresa por ejemplo varios IDs de 1 dígito y suponiendo que todavia no esten guardados en el sistema, el sistema los guarda correctamente. Si el usuario vuelve a ingresar esos mismos IDs el sistema lo detecta correctamente.

El problema surge cuando ingresa un ID mayor a 1 digito, lo cual el sistema se descontrola. Por ejemplo si ingresa un ID de 2 digitos lo guarda correctamente pero los IDs anteriores de un digito no los detecta por lo cual procede a volverlo a guardar.

Ver Video: http://www.mediafire.com/download/1b9coem1kcyeqbv/arduino.mp4

con respecto al goto lo use para que no se salga del sistema y el usuario no tenga que volver a ingresar la contraseña para poder acceder al menu. Si esta obsoleto que puedo usar en vez de goto.

Muchas gracias por su ayuda. Saludos

Es dificil ayudarte si hay partes del codigo que faltan y tampoco aportas ningun dato del hardware como la placa ,metodo de entrada de datos,etc.cuantos mas datos facilites ,mas facil sera tener una perspectiva general.en cuanto a substituir el goto ,hay varias alternativas ,una puede ser por ejemplo una variable booleana que puede ser verdadera o falsa segun el usuario este o no logueado y condicionar la ejecucion de determinado codigo a esta variable:

boolean logged = false; // no logeado
//boolean logged = true; // logueado
if (logged){
  // Codigo si logueado
}
else {
  //codigo si no logueado
}

Tambien ,por ejemplo el ID podria ser el indice del array y la contraseña el contenido:

int users[10];
users[0] = 1234; // id seria 0 ,contraseña 1234
users[1] = 2345; // id seria 1,contraseña 2345

edito: supongo que sabes que en el momento que reinicies arduino o falle la alimentacion ,te quedas sin la informacion del array que esta en la ram....

Y que al almacenarlas, las contraseñas sean "encriptadas" en cierto modo.
Si el almacenamiento es extraíble (como una tarjeta SD), yo sí lo haría...

jose:
Es dificil ayudarte si hay partes del codigo que faltan y tampoco aportas ningun dato del hardware como la placa ,metodo de entrada de datos,etc.cuantos mas datos facilites ,mas facil sera tener una perspectiva general.en cuanto a substituir el goto ,hay varias alternativas ,una puede ser por ejemplo una variable booleana que puede ser verdadera o falsa segun el usuario este o no logueado y condicionar la ejecucion de determinado codigo a esta variable:

boolean logged = false; // no logeado

//boolean logged = true; // logueado
if (logged){
  // Codigo si logueado
}
else {
  //codigo si no logueado
}



Tambien ,por ejemplo el ID podria ser el indice del array y la contraseña el contenido:


int users[10];
users[0] = 1234; // id seria 0 ,contraseña 1234
users[1] = 2345; // id seria 1,contraseña 2345



edito: supongo que sabes que en el momento que reinicies arduino o falle la alimentacion ,te quedas sin la informacion del array que esta en la ram....

Hola, con respecto al goto como puedo sustituirlo con el booleano.

Yo uso goto para 3 cosas; el primero es para limpiar la pantalla al momento que el usuario digita algo y se confunde presiona una tecla y borra la pantalla.

Ejemplo 1:

void loop(){

borrar:
lcd.clear();
lcd.setCursor(1,0);lcd.print("Password");     
                                   
for( i=0; i < sizeof(Ingresar_Contrasena); i++){ 

 kp = Teclado (); //funcion teclado, obtiene el valor de la tecla pulsada
 Ingresar_Contrasena[i]=kp; //guarda en un arreglo  
                                            
  if(Ingresar_Contrasena[i]=='*'){     
                                                
             goto borra; //Si presiona asterisco borra
                                            
    }
                                      
  lcd.setCursor(3+i,3); lcd.print(Ingresar_Contrasena[i]); 

}
}

Tambien uso goto para cuando el programa termina en un break o este no se salga del menu al finalizar la ejecucion del programa.

Ejemplo 2:

void main(){
 
inicio: 
lcd.clear();
lcd.setCursor(1,0);lcd.print("Menu 1"); 
lcd.setCursor(1,0);lcd.print("Menu 2");
kp = Teclado ();//función del teclado


switch(kp){  

case 1: //si preciona 1 ejecuta una función cualquiera

lcd.clear();
lcd.setCursor(1,0);lcd.print("Menu 1");

//*------------------------


funcion



 //*------------------------
goto inicio; 

break;







case 2: //Si presiona 2 ejecuta una funcion cualquiera

lcd.clear();
lcd.setCursor(1,0);lcd.print("Menu 2");

//*------------------------


funcion



 //*------------------------

goto inicio; 
break;

 
}

Y el ultimo lo ocupo cuando el usuario quiere regresar al menu anterior presione una tecla y se salga.

Ejemplo 3:

void main(){

inicio:
lcd.clear();
lcd.setCursor(0,0); lcd.print("Menu 1"); //Imprime en la lcd 
lcd.setCursor(0,1); lcd.print("Menu 2"); //Imprime en la lcd 


kp=Teclado ();

 switch (kp){
  
  case 1: //Si presiona la tecla 1 ejecuta una funcion cualquiera

  lcd.setCursor(0,1); lcd.print("Menu 1"); //Imprime en la lcd 
 
 //-------------------------------------------
      funcion

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

   if(kp=*){
    goto inicio;  //Si el usuario presiona asterisco regresa al menu anterior
   }

  break;



 case 2: //Si preciona 2 ejecuta una funcion cualquiera

  lcd.setCursor(0,1); lcd.print("Menu 2"); 
  
//-------------------------------------------
     funcion

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

   if(kp=*){
    goto inicio;  //Si el usuario presiona asterisco regresa al menu anterior

  break;

}


}

Solo necesito una idea como implementarlo a los ejemplos anteriores.

Si no es mucha molestia, soy nuevo y me gustaría aprender más.

Muchas gracias de antemano.

¡Saludos cordiales!

puedes meter el codigo en funciones y substituir la etiqueta por la llamada a la funcion .ademas tendras la ventaja de poder pasarle parametros si los necesitas.

jose:
puedes meter el codigo en funciones y substituir la etiqueta por la llamada a la funcion .ademas tendras la ventaja de poder pasarle parametros si los necesitas.

Hola, estoy tratando de hacer mi código mas reducido haciendo funciones, pero antes estoy teniendo problemas para dejar de usar el goto y reemplazarlo con otra función.

Este es una parte del codigo:

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>

///////////////////////LCD///////////////////////////////////////

//Incializa la libreria con los numeros de pines a interactuar el LCD
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

///////////////////////////////////////////////////////////////////


//////////////Teclado/////////////////////////////////////////////

//Definición de filas y columnas
const byte Filas = 4; //Cuatro filas
const byte Cols = 4; //Cuatro columnas

//Definición de los pines
byte Pins_Filas[] = {3, 2, 1, 0}; //Pines Arduino para las filas
byte Pins_Cols[] =  {4, 5, 6, 7}; // Pines Arduino para las columnas


//Definición de las teclas
char Teclas [ Filas ][ Cols ] =
{
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

//Se crea una instancia llamada Teclado1 y el cual asignara las teclas que tenemos en el arreglo "Teclas" y le decimos
//que se han conectados los pines de las filas y columnas


Keypad kpd = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);



char Teclado ()
{
  do{
    
    char Tecla = kpd.getKey();         // lee el teclado por si hay alguna tecla pulsada
    
    if(Tecla != NO_KEY)          
    {
      return Tecla;
    }   
  } while (1);
}

int i = 0;
static int cnt = 0;
char kp;
char Estado; 
char Menu;
char Ingresar_Contrasena[10];
char Contrasena1[] = {"123456"};
char Ingresar_Contrasena_Adm[10];
int short Peligro = A1;

void setup() {
 lcd.begin(16, 4); //Configura el LCD con el numero de columas y filas. Para un LCD 16x4: 16 columnas y 4 filas.
  lcd.display(); //Enciende el display
}

void loop() {

borrar:                                                      //------------------------------------Goto borrar
lcd.clear();//Limpia Pantalla
lcd.setCursor(1,0);lcd.print("Administrador");     //Imprime en la LCD
lcd.setCursor(1,1);lcd.print("Ingresar Pass");     //Imprime en la LCD
                                   


for( i=0; i < sizeof(Ingresar_Contrasena); i++){ 

     kp = Teclado (); //Obtiene el valor de la tecla pulsada
     Ingresar_Contrasena[i]=kp;      
                                            
    if(Ingresar_Contrasena[i]=='#'){ 
        Ingresar_Contrasena[i] = '\0'; //Sustituir por el caracter nul    
        break; 
    }
                                        
     else{ //Si presiona * borra pantalla 
           if(Ingresar_Contrasena[i]=='*'){
                  goto borrar;                                             //------------------------------------Goto
           }
    }
                                        

     if(i == (sizeof(Ingresar_Contrasena)- 1)){
           i--;
     }

     lcd.setCursor(3+i,3); lcd.print('*'); 
 }

//Si en las teclas 5, 6, 7, 8, 9 presiono numeral compara si la contraseña es correcta o no, de ser correcta accede al menu, de lo contrario no.

if ((Ingresar_Contrasena[0] == '\0') || (Ingresar_Contrasena[1] == '\0') || (Ingresar_Contrasena[2] == '\0') || (Ingresar_Contrasena[3] == '\0') || (Ingresar_Contrasena[4] == '\0') || (Ingresar_Contrasena[5] == '\0') || (Ingresar_Contrasena[6] == '\0') || (Ingresar_Contrasena[7] == '\0') || (Ingresar_Contrasena[8] == '\0') || (Ingresar_Contrasena[9] == '\0')){
                                        

      //Si estado es cero y las teclas pulsadas coinciden con la contraseña por default accede al menu
        if((cnt<3) && (strcmp (Contrasena1, Ingresar_Contrasena)==0) && (Estado == 0)){ 
                Menu=1;
        }
 
         //Si estado es 1 y las teclas pulsadas coinciden con la contraseña guardada en la memoria eeprom     accede al menu

         else if ((cnt<3) && (strcmp (Ingresar_Contrasena_Adm, Ingresar_Contrasena)==0) && (Estado == 1)){
                    Menu=1;
         }

          //Si ninguna de las contraseña es correcta muestra el mensaje incorrecto
          else{ 
                cnt++;
                lcd.clear(); //Limpia pantalla
                lcd.setCursor(2,1);lcd.print("INCORRECTO");     
                delay(100);
                goto borrar;                                                 //------------------------------------Goto
                
           }
                                        
            //Si el usuario ingreso mal 3 veces la contraseña muestra el mensaje
             
            if(cnt==3){ 
                cnt=0; 
                lcd.clear(); //Limpia pantalla
                lcd.setCursor(4,2);lcd.print("PELIGRO");     //Imprime en la LCD
                digitalWrite(Peligro, HIGH);
                delay(1000);
                digitalWrite(Peligro, LOW); 
             }

             //---------------------------Menu del admnistrador-----------------------------
                                         
              if(Menu==1){
                    lcd.clear();  //Limpia pantalla
                    lcd.setCursor(1,0);lcd.print("1. Ingresar");      //Imprime en la LCD
                    lcd.setCursor(1,2);lcd.print("2. Usuarios");      //Imprime en la LCD
                    lcd.setCursor(1,3);lcd.print("3. Cambiar Pass");   //Imprime en la LCD
                    
                   delay(100);  //Tiempo que muestra el menu. 
                   //Aqui va otro switch

            }

  }


}

Hice eso mismo pero haciendo funciones.

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>

///////////////////////LCD///////////////////////////////////////

//Incializa la libreria con los numeros de pines a interactuar el LCD
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

///////////////////////////////////////////////////////////////////


//////////////Teclado/////////////////////////////////////////////

//Definición de filas y columnas
const byte Filas = 4; //Cuatro filas
const byte Cols = 4; //Cuatro columnas

//Definición de los pines
byte Pins_Filas[] = {3, 2, 1, 0}; //Pines Arduino para las filas
byte Pins_Cols[] =  {4, 5, 6, 7}; // Pines Arduino para las columnas


//Definición de las teclas
char Teclas [ Filas ][ Cols ] =
{
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

//Se crea una instancia llamada Teclado1 y el cual asignara las teclas que tenemos en el arreglo "Teclas" y le decimos
//que se han conectados los pines de las filas y columnas


Keypad kpd = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);



char Teclado ()
{
  do{
    
    char Tecla = kpd.getKey();         // lee el teclado por si hay alguna tecla pulsada
    
    if(Tecla != NO_KEY)          
    {
      return Tecla;
    }   
  } while (1);
}

int i = 0;
static int cnt = 0;
char kp;
char Estado; 
char Menu;
char Ingresar_Contrasena[10];
char Contrasena1[] = {"123456"};
char Ingresar_Contrasena_Adm[10];
int short Peligro = A1;

void setup() {
 lcd.begin(16, 4); //Configura el LCD con el numero de columas y filas. Para un LCD 16x4: 16 columnas y 4 filas.
  lcd.display(); //Enciende el display
}

void loop() {

Ingrese_Contrasena_Admnistrador();

if ((Ingresar_Contrasena[0] == '\0') || (Ingresar_Contrasena[1] == '\0') || (Ingresar_Contrasena[2] == '\0') || (Ingresar_Contrasena[3] == '\0') || (Ingresar_Contrasena[4] == '\0') || (Ingresar_Contrasena[5] == '\0') || (Ingresar_Contrasena[6] == '\0') || (Ingresar_Contrasena[7] == '\0') || (Ingresar_Contrasena[8] == '\0') || (Ingresar_Contrasena[9] == '\0')){

   if((cnt<3) && (strcmp (Contrasena1, Ingresar_Contrasena)==0) && (Estado == 0)){ 
                Menu=1;
        }
 
         //Si estado es 1 y las teclas pulsadas coinciden con la contraseña guardada en la memoria eeprom     accede al menu

         else if ((cnt<3) && (strcmp (Ingresar_Contrasena_Adm, Ingresar_Contrasena)==0) && (Estado == 1)){
                    Menu=1;
         }

          //Si ninguna de las contraseña es correcta muestra el mensaje incorrecto
          else{ 
                cnt++;
                lcd.clear(); //Limpia pantalla
                lcd.setCursor(2,1);lcd.print("INCORRECTO");     
                delay(100);
                goto borrar;                                                 //------------------------------------Goto
                
           }
                                        
            //Si el usuario ingreso mal 3 veces la contraseña muestra el mensaje
             
            if(cnt==3){ 
                cnt=0; 
                lcd.clear(); //Limpia pantalla
                lcd.setCursor(4,2);lcd.print("PELIGRO");     //Imprime en la LCD
                digitalWrite(Peligro, HIGH);
                delay(1000);
                digitalWrite(Peligro, LOW); 
             }

             //---------------------------Menu del admnistrador-----------------------------
                                         
              if(Menu==1){
                    lcd.clear();  //Limpia pantalla
                    lcd.setCursor(1,0);lcd.print("1. Ingresar");      //Imprime en la LCD
                    lcd.setCursor(1,2);lcd.print("2. Usuarios");      //Imprime en la LCD
                    lcd.setCursor(1,3);lcd.print("3. Cambiar Pass");   //Imprime en la LCD
                    
                   delay(100);  //Tiempo que muestra el menu. 
                   //Aqui va otro switch

            }

  }


}


void Ingrese_Contrasena_Admnistrador(){
   
   lcd.clear();//Limpia Pantalla
   lcd.setCursor(1,0);lcd.print("Administrador");     //Imprime en la LCD
   lcd.setCursor(1,1);lcd.print("Ingresar Pass");     //Imprime en la LCD
   
   for( i=0; i < sizeof(Ingresar_Contrasena); i++){ 

            kp = Teclado (); 
            Ingresar_Contrasena[i]=kp;      
            
            if(Ingresar_Contrasena[i]=='#'){ 
                Ingresar_Contrasena[i] = '\0'; //Sustituir por el caracter nul    
                break; 
             }
        
             else{ //Si presiona * borra pantalla 
                if(Ingresar_Contrasena[i]=='*'){
                   Ingrese_Contrasena_Admnistrador();   //Sustituí la funcion por el goto 
                 }
             }
        
            if(i == (sizeof(Ingresar_Contrasena)- 1)){
              i--;
            }

      lcd.setCursor(3+i,3); lcd.print('*'); //Imprime en la lcd
   }
}

Parecia que iba a funcionar remplazando el goto por la función Ingrese_Contrasena_Admnistrador();

 else{ //Si presiona * borra pantalla 
        if(Ingresar_Contrasena[i]=='*'){
            Ingrese_Contrasena_Admnistrador();   //Sustituí la funcion por el goto 
         }
}

pero da errores al momento de validar la contraseña.