Autor Tema: Problemas multiplexado y contraseña.  (Leído 1496 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Theisas

  • PIC10
  • *
  • Mensajes: 1
Problemas multiplexado y contraseña.
« en: 31 de Octubre de 2016, 00:15:28 »
Hola, este año estoy haciendo una alarma con un teclado 4x4 para activarla como proyecto de fin de año y estoy teniendo muchos problemas en la contraseña.


Estoy usando un pic 16f877a como se ve en el codigo.

#include <16f877a.h>
#fuses XT,NOWDT
#use delay (clock = 4M)
#byte trisb=0x86
#byte portb=0x06
#byte trisc=0x87
#byte portc=0x07
#use fast_io(D)
#include <kbd1.c>

void main () {
   kbd_init();
   port_b_pullups (true);
   bit_clear(trisb,0);
   bit_clear(trisb,1);
   bit_clear(trisb,2);
   bit_clear(trisb,3);
   bit_clear(trisb,4);
   bit_clear(trisb,5);
   bit_clear(trisb,6);
   bit_clear(trisb,7);
   set_tris_c(0b11100000);
   //----------- pin_c0:microfono     /
   //----------- pin_c1:apertura     < ENTRADAS
   //----------- pin_c2:movimiento    \
   output_low(pin_c3);//buzzer       /
   output_low(pin_c4);//rele         |
   output_low(pin_c5);//rgb rojo     < SALIDAS
   output_low(pin_c6);//rgb verde    |
   output_low(pin_c7);//rgb azul     \
   char a;//primer caracter de la contraseña
   char b;//segundo caracter de la contraseña
   char c;//tercero caracter de la contraseña
   char d;//cuarto caracter de la contraseña
   char e;//errores
   char f;//activar alarma por exceso de errores
   char g;//contador de flancos decrecientes
   char h;//contador de flancos decrecientes
   a='1';
   b='2';
   c='3';
   d='4';
   while(true)
   {
     
//--------------------------ACTIVAR LA ALARMA O ABRIR LA PUERTA----------------
     
      while(true)
      {
seguir:while(true)//prengunta char a
      {
  reint0:if(a==kbd_getc())
         {
            e++;
            output_high(pin_c6);
            delay_ms(100);
            output_low(pin_c6);
            delay_ms(500);
            break;
         }
         else
         {
            if(kbd_getc()==0)
            {
               goto reint0;
            }
            else
            {
               output_high(pin_c5);
               delay_ms(500);
               output_low(pin_c5);
               break;
            }
         }
      }
      while(true)//prengunta char b
      {
      mm:if(b==kbd_getc())
         {
            e++;
            output_high(pin_c6);
            delay_ms(100);
            output_low(pin_c6);
            delay_ms(500);
            break;
         }
         else
         {
            if(kbd_getc()==0)
            {
               goto mm;
            }
            else
            {
               output_high(pin_c5);
               delay_ms(500);
               output_low(pin_c5);
               break;
            }
         }
      }
      while(true)//prengunta char c
      {
     mmm:if(c==kbd_getc())
         {
            e++;
            output_high(pin_c6);
            delay_ms(100);
            output_low(pin_c6);
            delay_ms(500);
            break;
         }
         else
         {
            if(kbd_getc()==0)
            {
               goto mmm;
            }
            else
            {
               output_high(pin_c5);
               delay_ms(500);
               output_low(pin_c5);
               break;
            }
         }
      }
      while(true)//prengunta char d
      {
   mmmmm:if(d==kbd_getc())
         {
            e++;
            output_high(pin_c6);
            delay_ms(100);
            output_low(pin_c6);
            delay_ms(500);
            break;
         }
         else
         {
            if(kbd_getc()==0)
            {
               goto mmmmm;
            }
            else
            {
               output_high(pin_c5);
               delay_ms(500);
               output_low(pin_c5);
               break;
            }
         }
      }
      while(true)//reintentar
      {
         if(e==4)
         {
            output_high(pin_c6);//     /
            delay_ms(100);//           |
            output_low(pin_c6);//      |
            delay_ms(100);//           |
            output_high(pin_c6);//     |
            delay_ms(100);//           < CONTRASEÑA ACTIVADA(VERDE)
            output_low(pin_c6);//      |
            delay_ms(100);//           |
            output_high(pin_c6);//     |
            delay_ms(100);//           |
            output_low(pin_c6);//      \
            e=0;
            goto reint0;
         }
         else
         {
            output_high(pin_c5);//     /
            delay_ms(100);//           |
            output_low(pin_c5);//      |
            delay_ms(100);//           |
            output_high(pin_c5);//     |
            delay_ms(100);//           < CONTRASEÑA ERRONEA(ROJO)
            output_low(pin_c5);//      |
            delay_ms(100);//           |
            output_high(pin_c5);//     |
            delay_ms(100);//           |
            output_low(pin_c5);//      \
            goto reint0;
         }
      }
      }
      }
   }

Gracias de antemano.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problemas multiplexado y contraseña.
« Respuesta #1 en: 31 de Octubre de 2016, 10:39:24 »
No entiendo a que te referis con multiplexado... Que es lo que queres multiplexar? un display 7 segmentos?
Deberias tambien poner una descripcion de que queres que haga tu programa para asi entender al mismo.

Tus problemas son los delays claramente. Pero pienso que hay mas problemas o tal ves estas no estas usando algunas herramientas de C.

Cosas que me parecen mal..

Código: C
  1. kbd_init();
  2.    port_b_pullups (true);
  3.    bit_clear(trisb,0);
  4.    bit_clear(trisb,1);
  5.    bit_clear(trisb,2);
  6.    bit_clear(trisb,3);
  7.    bit_clear(trisb,4);
  8.    bit_clear(trisb,5);
  9.    bit_clear(trisb,6);
  10.    bit_clear(trisb,7);
  11.    set_tris_c(0b11100000);

kbd_init() realiza el cambio de algunos tris.. estas seguro de que puerto esta cambiando? Asi no lo cambias de nuevo con tus bit_clear y set_tris
Luego de eso comenzas a cambiar los tris de los demas puertos como es el B y el C, pero curiosamente el unico que tiene el FAST_IO es el D, entonces si en algun momento haces input_pin(PIN_B0) ese pin se va a convertir en entrada. Si vas a setear los tris vos, entonces ponelos a todos como FAST_IO, y asi el compilador no lo cambia a su gusto, sino que respeta lo que vos queres.
Para cambiar los tris tenes set_tris_x(), EJemplo para tu caso del PORTB seria set_tris_b(0); y le carga a todo el puerto el valor 0, es decir todas salidas. Por que hacerlo uno por uno como lo haces ?

Entonces ahi tendrias mal el orden si es que no sabes que hace KBD. Y podrias resumir todo en 3 lineas y no tanto.

Código: C
  1. //----------- pin_c0:microfono     /
  2.    //----------- pin_c1:apertura     < ENTRADAS
  3.    //----------- pin_c2:movimiento    \
  4.    output_low(pin_c3);//buzzer       /
  5.    output_low(pin_c4);//rele         |
  6.    output_low(pin_c5);//rgb rojo     < SALIDAS
  7.    output_low(pin_c6);//rgb verde    |
  8.    output_low(pin_c7);//rgb azul     \

Esta como muchas mas otras.. si usas el FAST_IO(C) y haces ouput_c(0); tendrias el mismo resultado, es decir se mantendrian como entradas las que deben y todo eso pasa a ser 1 sola linea.

Código: C
  1. char a;//primer caracter de la contraseña
  2.    char b;//segundo caracter de la contraseña
  3.    char c;//tercero caracter de la contraseña
  4.    char d;//cuarto caracter de la contraseña

Cuando se trata de que ingresan numeros o letras, es mejor usar un array, es decir
Código: [Seleccionar]
unsigned char contrasena[4] = {1,2,3,4}; //Contraseña inicia con los valores 1234Ya que tomar el valor y actuar usualmente es repetitivo, observaras para tu caso que para a,b,c y d haces exactamente lo mismo.. Entonces podriamos poner un for y compactar eso.

Citar
reint0:
Intenta evitar hacer saltos con un goto, C provee las herramientas suficientes como para hacerlo sin esto.. Muy pocos casos vi donde se ha usado. Y hablando de codigos muchos mas complejos

-------------------------------------------------------

Cuando comparas una contraseña, existe un potencial problema.. si vos das aviso de cual es erroneo la contraseña no sirve para nada por que seria facil de sacar. Ejemplo supongamos que la contraseña es 1234, presiono el 1 y me da correcto, presiono 1 de vuelta y me dice incorrecto, aca podria hacer 2 cosas comenzar del principio o si estoy avisando que esta mal, avizar y quedarme donde estoy que es lo que haces.
Si comienzo del principio, le estoy avisando al atacante que la contraseña ese valor es incorrecto, entonces solo debe probar como maximo 10 combinaciones 10 ,11 ,12 ,13 ..., 19 hasta que uno le de valido y pueda seguir...

El proceso correcto es tomar los 4 valores sin decir NADA.y una ves esten los 4 valores compararlos con la contraseña.Existen muchas mas precauciones a tomar pero para el momento es suficiente.

--------------------------------------------------------

Dividir el problema en distintas etapas..

- Detectar la contraseña
- Compararla
- Actuar

--------------------------------------------------------

Código: C
  1. unsigned char contrasena_detectada[4] = {0,0,0,0};              // Donde va a ir la contraseña ingresada
  2. const char contrasena[4] = {1,2,3,4};                                   // Contraseña guardada y a comparar
  3. char letra = 0;                                                                                 // Variable donde voy a almacenar lo leido del teclado
  4. char letra_anterior = 0;                                                                // Variable que mantiene el valor de la ultima tecla presionada, asi no cuenta 2 veces lo mismo
  5. bool contra_correcta = false;                                                   // Variable para saber si luego de la comparacion fue correcto o no lo ingresado
  6.  
  7. void main(void)
  8. {
  9.         unsigned char indice = 0;
  10.  
  11.         setup()
  12.  
  13.         while(1)
  14.         {
  15.                 // Tomamos los valores!
  16.                 while(1)
  17.                 {
  18.                         //Guardamos el valor en unavariable
  19.                         letra = kbd_get();
  20.  
  21.                         // Revisamos que hay algo presionado, y que sea distinto a lo detectado anteriormente
  22.                         if( letra != 0 && letra != letra_anterior)
  23.                         {
  24.                                 // Guardo contraseña
  25.                                 contrasena_detectada[indice];
  26.                                 // Aumento el indice
  27.                                 indice++;
  28.                                 // Entraron todos los valores?
  29.                                 if(indice >= sizeof(contrasena);
  30.                                 {
  31.                                         //Salgo del while
  32.                                         break;
  33.                                 }
  34.                         }
  35.                         // Guardo el ultimo valor ingresado asi si alguien mantiene presionado el boton no cuenta 2 veces
  36.                         letra_anterior = letra;
  37.                 }
  38.  
  39.                 // Ya tengo guardado las cosas, ahora a comparar
  40.  
  41.                 contra_correcta = true;
  42.                 for(indice = 0; indice < sizeof(contrasena); indice++)
  43.                 {
  44.                         if(contrasena[indice] != contrasena_detectada[indice])
  45.                         {
  46.                                 contra_correcta = false;
  47.                                 break;
  48.                         }
  49.                 }
  50.  
  51.                 // Actuo ahora que se el resultado
  52.                 if(contra_correcta == true)
  53.                 {
  54.                 }
  55.         }
  56. }

No recuerdo si el kbd retorna enteros o caracteres, sino solo tendrias que reemplazar

const char contrasena[4] = {1,2,3,4};                  

por

const char contrasena[4] = {'1','2','3','4'};                  

Desconectado arusti

  • PIC10
  • *
  • Mensajes: 2
Re:Problemas multiplexado y contraseña.
« Respuesta #2 en: 31 de Octubre de 2016, 14:18:16 »
Buenas tardes, ante todo muchas gracias por la respuesta.

Soy el compañero de grupo de el, la idea en general es hacer una alarma que con el microcontrolador se comande la activación y desactivacion, con una contraseña a través de un keypad multiplexado de 4x4, de 3 sensores, los mismo deben estar preguntando de manera constante y si alguno cambia la alarma se debe disparar. También se debería dar acceso a una puerta a través de una combinación de teclas ej: * # 0 .
El compilador que usamos es el PCW.
Compile el programa y me dice que setup() no es algo valido, busque en la ayuda del compilador pero habla de setup distintos a ese.

El código que intente compilar es separado a la alarma en si, solo para probar la contraseña, el que nos compartiste:

Código: [Seleccionar]
#include <16f877a.h>
#fuses XT,NOWDT
#use delay (clock = 4M)
#byte trisb=0x86
#byte portb=0x06
#byte trisc=0x87
#byte portc=0x07
#include <kbd1.c>
void main(void)
{
kbd_init();
unsigned char contrasena_detectada[4] = {0,0,0,0};              // Donde va a ir la contraseña ingresada
const char contrasena[4] = {1,2,3,4};                           // Contraseña guardada y a comparar
char letra = 0;                                                 // Variable donde voy a almacenar lo leido del teclado
char letra_anterior = 0;                                        // Variable que mantiene el valor de la ultima tecla presionada, asi no cuenta 2 veces lo mismo
int1 contra_correcta = false;                                 // Variable para saber si luego de la comparacion fue correcto o no lo ingresado

        unsigned char indice = 0;
 
       setup()
 
        while(1)
        {
                // Tomamos los valores!
                while(1)
                {
                        //Guardamos el valor en unavariable
                        letra = kbd_getc();
 
                        // Revisamos que hay algo presionado, y que sea distinto a lo detectado anteriormente
                        if( letra != 0 && letra != letra_anterior)
                        {
                                // Guardo contraseña
                                contrasena_detectada[indice];
                                // Aumento el indice
                                indice++;
                                // Entraron todos los valores?
                                if(indice >= sizeof(contrasena));
                                {
                                        //Salgo del while
                                        break;
                                }
                        }
                        // Guardo el ultimo valor ingresado asi si alguien mantiene presionado el boton no cuenta 2 veces
                        letra_anterior = letra;
                }
 
                // Ya tengo guardado las cosas, ahora a comparar
 
                contra_correcta = true;
                for(indice = 0; indice < sizeof(contrasena); indice++)
                {
                        if(contrasena[indice] != contrasena_detectada[indice])
                        {
                                contra_correcta = false;
                                break;
                        }
                }
 
                // Actuo ahora que se el resultado
                if(contra_correcta == true)
                {
                }
        }
}

Desde ya muchas gracias por la ayuda.

Editado: ya cambie el color y la negrita la saque, perdon por incomodar.
« Última modificación: 31 de Octubre de 2016, 17:05:22 por arusti »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problemas multiplexado y contraseña.
« Respuesta #3 en: 31 de Octubre de 2016, 14:58:26 »
Primero , no escriban en rojo ni negrita, si quieren remarcar algo si pueden hacerlo en negrita.

El codigo que les pase obviamente no esta completo.

El setup() lo puse para que ahi definieran los TRIS, pongan el kbd_init, etc... Es ahi donde se produce la inicializacion de los modulos o "setup" para comenzar a trabajar.. Es decir puse una funcion para que ustedes se dieran cuenta de que va ahi y no una funcion real.

Respecto a lo demas que debe hacer la alarma, con el codigo que les comparti es muy simple de solucionar.

Para hacer al sistema que responda, sin utilizar ningun tipo de interrupcion, deberiamos reemplazar el while(1) que toma las cosas del teclado por otra cosa. Es mas se los voy a hacer mas facil, ya que imagino que kbd va a devolver caracteres ASCII.

Código: C
  1. #include <string.h>
  2.  
  3. unsigned char contrasena_detectada[4] = {0,0,0,0};              // Donde va a ir la contraseña ingresada
  4. char letra = 0;                                                 // Variable donde voy a almacenar lo leido del teclado
  5. char letra_anterior = 0;                                        // Variable que mantiene el valor de la ultima tecla presionada, asi no cuenta 2 veces lo mismo
  6.  
  7.         while(1)
  8.         {
  9.                 // Tomamos los valores!
  10.  
  11.                 //Guardamos el valor en unavariable
  12.                 letra = kbd_getc();
  13.  
  14.                 // Algo presionado?
  15.                 if( letra != 0 )
  16.                 {
  17.  
  18.                         // Revisamos que hay algo presionado, y que sea distinto a lo detectado anteriormente
  19.                         if(letra != letra_anterior)
  20.                         {
  21.                                 // Guardo contraseña
  22.                                 contrasena_detectada[indice] = letra;
  23.                                 // Aumento el indice
  24.                                 indice++;
  25.                         }
  26.                 }
  27.  
  28.  
  29.                 // Guardo el ultimo valor ingresado asi si alguien mantiene presionado el boton no cuenta 2 veces
  30.                 letra_anterior = letra;
  31.  
  32.                 // Se completo el pass?
  33.                 if( indice >= sizeof(contrasena) )
  34.                 {
  35.                         if(!strncmp("1234",contrasena_detectada,4))
  36.                         {
  37.                                 //Aca detecte el pass 1234, hacer lo que debo hacer
  38.                         }
  39.  
  40.                         if(!strncmp("*#0*",contrasena_detectada,4))
  41.                         {
  42.                                 //Aca detecte el pass *#0*, hacer lo que debo hacer
  43.                         }
  44.  
  45.  
  46.                         indice = 0;     // Reestablecemos el indice para una nueva contraseña
  47.                 }
  48.  
  49.                 if(sensores == 1)
  50.                 {
  51.                         //Activo alarma
  52.                 }
  53.         }

La velocidad con que respondan los sensores a activar la alarma va a depender de lo que hagan cuando se detecte una contraseña valida.

Nuevamente, el codigo esta para que lo lean y lo entiendan. Un copy y paste no les va a ayudar a unir las cosas.
Ademas podria haber realizado al comparacion en una funcion aparte y puesto esa funcion dentro de la deteccion del teclado.. Pero para mas claridad para alguien que recien comienza, mejor ir "por partes"

Desconectado arusti

  • PIC10
  • *
  • Mensajes: 2
Re:Problemas multiplexado y contraseña.
« Respuesta #4 en: 31 de Octubre de 2016, 17:06:05 »
Muchas Gracias, voy a revisarlo de nuevo.