Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Serratura elettronica

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Serratura elettronica

Messaggioda Foto Utenteguidonetto » 12 apr 2015, 9:15

Ciao, mi date un consiglio del perche non va la parte di codice per far funzionare una serratura elettronica?
In pratica memorizzo il codice, lo digito sulla tastiera, se il codice è esatto accendo il led su LATD0.
La parte di codice che riguarda il tastierino funziona, infatti vedo solo i tasti premuti.
Uso un pic18f4550 con MplabX V. 2.35.
Grazie

Codice: Seleziona tutto
/*Nota: codice tratto da settorezero, riadattato da: StefA */

#include <xc.h>

#include "PIC18F4550_config.h"

#define  LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"

#include "delay.h"
#include "delay.c"


//*************************************
//     Prototipi di funzione
//*************************************
void board_initialization (void);
//void serratura_elettronica (void);

/* tastierino numerico collegato su PORTB
uso un tastierino 4x4 (16 pulsanti)
Per comodità ho collegato il tastierino in questo modo
(C=colonna R=riga)
R1 = RB1
R2 = RB3
R3 = RB5
R4 = RB7
C1 = RB0
C2 = RB2
C3 = RB4
C4 = RB6
I pin di riga saranno input ed attiveremo le resistenze di pullup interne
i pin di colonna saranno output e messi a 1 di default
*/

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le colonne una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore colMask[0] al valore colMask[3], porto a massa le colonne una alla volta. */
unsigned char colMask[]=
   {
   0b11111110, // Colonna 1 => RB0 a massa
   0b11111011, // Colonna 2 => RB2 a massa
   0b11101111, // Colonna 3 => RB4 a massa
   0b10111111 // Colonna 4 => RB6 a massa
   };
unsigned char colScan=0; // va da 0 a 3 per scansionare l'array colMask

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le righe una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore rowMask[0] al valore rowMask[3], porto a massa le righe una alla volta. */
unsigned char rowMask[]=
   {
   0b00000010, // Riga 1
   0b00001000, // Riga 2
   0b00100000, // Riga 3
   0b10000000 // Riga 4
   };
unsigned char rowScan=0; // va da 0 a 3 per scansionare l'array rowMask

//Array che contiene i simboli disegnati sui pulsanti del tastierino, disposti in un certo ordine:
unsigned char keys[]={'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'};
unsigned char keypressed=0; // peso numerico del pulsante premuto
unsigned char keyok; // flag del pulsante premuto

//unsigned char x=1;
//unsigned char y=2;
//unsigned char z=3;

unsigned char k;

// Impostazione codice segreto e inizializzazione codice digitato

#define dim 4  // lunghezza del codice segreto
unsigned char key_code[dim] = {'1','2','3','4'};
unsigned char pressed_code[dim];
char code_index = 0;
char code_ok = 0;  // variabile per determinare se il codice è esatto



//*************************************
//     Programma principale
//*************************************
int main (void){

    unsigned char frase [] = "   StefA TEST   ";

    // Abilita i resistori di pull-up sulla PORTB
    INTCON2bits.RBPU = 0x00;

    keyok=0;

    board_initialization ();

    //serratura_elettronica ();

    // Inizializzo il display LCD con quarzo a 20MHz
    LCD_initialize (20);

    LCD_backlight (LCD_TURN_ON_LED);

    LCD_write_message ("Tastiera Matrice");

    LCD_goto_line (2);

    LCD_write_string (frase);

    delay_s(2);

    LCD_clear();

    LCD_write_message ("Premere un tasto");

    // Ciclo infinito
    while(1) {
        /*Effettuo la scansione delle colonne contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array colMask */
        for (colScan=0; colScan<4; colScan++) // porto a massa una colonna alla volta
        {
            PORTB=0xFF; // porto tutte le colonne a 1
            PORTB &= colMask[colScan]; // porto a zero la colonna attuale

        /*Effettuo la scansione delle righe contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array rowMask */
            for (rowScan=0; rowScan<4; rowScan++) {
                /*Controllo se la riga attuale si trova a massa effettuando un AND
                 *con l?elemento dell?array rowScan che mi permette di verificare soltanto
                 *il bit che mi interessa su tutta la porta */
                if (!(PORTB & rowMask[rowScan])) // Riga rowScan trovata a massa
                {
                    delay_ms(50); //Ritardo spike
                    if (!(PORTB & rowMask[rowScan])) {
                        /*Se viene confermato che un pulsante è stato premuto, imposto
                         *il valore che permette di risalire al tasto e indico al programma
                         *che un pulsante è stato premuto */
                        keypressed=rowScan+(4*colScan); // numero di pulsante premuto
                        keyok=1; // è stato premuto un pulsante
                    }
                }
            } // fine scansione righe
        }//for // fine scansione colonne

        if (keyok) // è stato premuto un pulsante
        {
            // Solo dopo che ho controllato in che punto si trova il
            // cursore posso piazzare il carattere premuto
            LCD_goto_line (2);
            LCD_write_char(keys[keypressed]);
         
            keyok=0; // resetto il flag del pulsante premuto

            // rimango in un ciclo continuo fino a che il pulsante non viene rilasciato
            PORTB=0b10101010;
            while(PORTB != 0b10101010)
                /*Se voglio che i simboli visualizzati siano senpre visibili sul
                 display (cioè cambino alla pressione del tasto) omettere:
                 LCD_goto_line (2);
                 LCD_write_message ("      ");*/
                LCD_goto_line (2);

            //delay_s(1);  //determino per quanto tempo voglio visualizzare il simbolo
             delay_ms(800);

                LCD_write_message ("      ");
                   {continue;}
        }//if (keyok)

        if (code_index == dim) {  // controllo codice
   for ( k=0; k=<dim; k++) {

   if (key_code[k] == pressed_code[k]){
    code_ok = 1;
     }//if (code_index == dim
   else {  // cifra del codice errata, codice sbagliato
    code_ok = 0;  // codice errato, esce dal ciclo
         
     }//else
    }//for
if (code_ok == 1){  // se il codice è giusto accendo LATD0
  LATDbits.LATD0  = 1;
}//if (code_ok == 1
  else { 
   LATDbits.LATD0 = 0;
  }//else
   code_ok = 0;  // resetto la variabile se il codice è giusto (cioè se code_ok era = 1)
   code_index = 0;  // resetto l'indice che scorre l'array del codice

     } // if (code_index == dim)
    }//while
}//main


//*************************************
//     Implementazione della funzione
//*************************************
void board_initialization (void) {
//******************//
//Impostazione porte//
//******************//
   // Imposto PORTA tutti ingressi
   LATA = 0x00;
   TRISA = 0x00;

   // Imposto PORTB
   LATB = 0x00;
   TRISB = 0b10101010;

   // Imposto PORTC tutti ingressi e RC1 come uscita
   LATC = 0x00;
   TRISC = 0b11111101;

   // Imposto PORTD tutte uscite
   LATD = 0x00;
   TRISD = 0x00;

   // Imposto PORTE tutti ingressi
   LATE = 0x00;
   TRISE = 0xFF;
}//void board_initialization (void)

//*************************************
//          Funzione serratura
//*************************************
//void serratura_elettronica (void){
 

     /*if ( tasto1 == 0 ) {
        //Questa funzione serve a far scorrere la scritta.
//x determina di quanto deve spostarsi la scritta.
//y se 1 la scritta scorre sopra, se 2 sotto.
LCD_goto_xy (x,2);
    LCD_write_message ("*");

  }//if
else {
// Altrimenti codice errato, led spento
LATAbits.LATA1 = 0;
     }//else

  if ( tasto2 == 0 ) {
        //Questa funzione serve a far scorrere la scritta.
//x determina di quanto deve spostarsi la scritta.
//y se 1 la scritta scorre sopra, se 2 sotto.
LCD_goto_xy (y,2);
    LCD_write_message ("*");

  }//if
else {
// Altrimenti codice errato, led spento
LATAbits.LATA1 = 0;
     }//else
  */
 
// }//void serratura_elettronica


Parte codice serratura

Codice: Seleziona tutto
unsigned char k;

// Impostazione codice segreto e inizializzazione codice digitato

#define dim 4  // lunghezza del codice segreto
unsigned char key_code[dim] = {'1','2','3','4'};
unsigned char pressed_code[dim];
char code_index = 0;
char code_ok = 0;  // variabile per determinare se il codice è esatto



if (code_index == dim) {  // controllo codice
   for ( k=0; k=<dim; k++) {

   if (key_code[k] == pressed_code[k]){
    code_ok = 1;
     }//if (code_index == dim
   else {  // cifra del codice errata, codice sbagliato
    code_ok = 0;  // codice errato, esce dal ciclo
         
     }//else
    }//for
if (code_ok == 1){  // se il codice è giusto accendo LATD0
  LATDbits.LATD0  = 1;
}//if (code_ok == 1
  else { 
   LATDbits.LATD0 = 0;
  }//else
   code_ok = 0;  // resetto la variabile se il codice è giusto (cioè se code_ok era = 1)
   code_index = 0;  // resetto l'indice che scorre l'array del codice

     } // if (code_index == dim)

Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

2
voti

[2] Re: Serratura elettronica

Messaggioda Foto Utentebobina » 12 apr 2015, 11:21

La variabile code_index non viene mai incrementata quinti è come se non venisse premuto nessun tasto.
Dentro if di keyok potresti aggiungere l'incremento
Codice: Seleziona tutto

    if (keyok) // è stato premuto un pulsante
    {
        code_index++;     


Altre 2 cose lo vedo debole come meccanismo di debounce, io arriverei ad almeno 200ms o comunque farei più di 2 verifiche.
Codice: Seleziona tutto
                if (!(PORTB & rowMask[rowScan])) // Riga rowScan trovata a massa
                {
                    delay_ms(50); //Ritardo spike
                    if (!(PORTB & rowMask[rowScan])) {


nel ciclo for quando c'è un codice sbagliato nel commento c'è scritto che esci dal ciclo for ma poi non c'è nessun break:

Codice: Seleziona tutto
   else {  // cifra del codice errata, codice sbagliato
    code_ok = 0;  // codice errato, esce dal ciclo
    break; // <<<<<<=== aggiunto break
     }//else

senza il break in caso di cifra sbagliata e l'ultima cifra è corretta la serratura viene aperta :-)
Avatar utente
Foto Utentebobina
212 6
Frequentatore
Frequentatore
 
Messaggi: 177
Iscritto il: 27 dic 2009, 14:22

0
voti

[3] Re: Serratura elettronica

Messaggioda Foto Utenteguidonetto » 12 apr 2015, 15:26

Ciao, e grazie per la risposta, ho portato le modifiche al codice, ora ricevo un errore dal compilatore.


Codice: Seleziona tutto

/*Nota: codice tratto da settorezero, riadattato da: StefA */

#include <xc.h>

#include "PIC18F4550_config.h"

#define  LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"

#include "delay.h"
#include "delay.c"


//*************************************
//     Prototipi di funzione
//*************************************
void board_initialization (void);
//void serratura_elettronica (void);

/* tastierino numerico collegato su PORTB
uso un tastierino 4x4 (16 pulsanti)
Per comodità ho collegato il tastierino in questo modo
(C=colonna R=riga)
R1 = RB1
R2 = RB3
R3 = RB5
R4 = RB7
C1 = RB0
C2 = RB2
C3 = RB4
C4 = RB6
I pin di riga saranno input ed attiveremo le resistenze di pullup interne
i pin di colonna saranno output e messi a 1 di default
*/

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le colonne una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore colMask[0] al valore colMask[3], porto a massa le colonne una alla volta. */
unsigned char colMask[]=
   {
   0b11111110, // Colonna 1 => RB0 a massa
   0b11111011, // Colonna 2 => RB2 a massa
   0b11101111, // Colonna 3 => RB4 a massa
   0b10111111 // Colonna 4 => RB6 a massa
   };
unsigned char colScan=0; // va da 0 a 3 per scansionare l'array colMask

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le righe una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore rowMask[0] al valore rowMask[3], porto a massa le righe una alla volta. */
unsigned char rowMask[]=
   {
   0b00000010, // Riga 1
   0b00001000, // Riga 2
   0b00100000, // Riga 3
   0b10000000 // Riga 4
   };
unsigned char rowScan=0; // va da 0 a 3 per scansionare l'array rowMask

//Array che contiene i simboli disegnati sui pulsanti del tastierino, disposti in un certo ordine:
unsigned char keys[]={'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'};
unsigned char keypressed=0; // peso numerico del pulsante premuto
unsigned char keyok; // flag del pulsante premuto

//unsigned char x=1;
//unsigned char y=2;
//unsigned char z=3;

unsigned char k;

// Impostazione codice segreto e inizializzazione codice digitato

#define dim 4  // lunghezza del codice segreto
unsigned char key_code[dim] = {'1','2','3','4'};
unsigned char pressed_code[dim];
char code_index = 0;
char code_ok = 0;  // variabile per determinare se il codice è esatto



//*************************************
//     Programma principale
//*************************************
int main (void){

    unsigned char frase [] = "   StefA TEST   ";

    // Abilita i resistori di pull-up sulla PORTB
    INTCON2bits.RBPU = 0x00;

    keyok=0;

    board_initialization ();

    //serratura_elettronica ();

    // Inizializzo il display LCD con quarzo a 20MHz
    LCD_initialize (20);

    LCD_backlight (LCD_TURN_ON_LED);

    LCD_write_message ("Tastiera Matrice");

    LCD_goto_line (2);

    LCD_write_string (frase);

    delay_s(2);

    LCD_clear();

    LCD_write_message ("Premere un tasto");

    // Ciclo infinito
    while(1) {
        /*Effettuo la scansione delle colonne contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array colMask */
        for (colScan=0; colScan<4; colScan++) // porto a massa una colonna alla volta
        {
            PORTB=0xFF; // porto tutte le colonne a 1
            PORTB &= colMask[colScan]; // porto a zero la colonna attuale

        /*Effettuo la scansione delle righe contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array rowMask */
            for (rowScan=0; rowScan<4; rowScan++) {
                /*Controllo se la riga attuale si trova a massa effettuando un AND
                 *con l?elemento dell?array rowScan che mi permette di verificare soltanto
                 *il bit che mi interessa su tutta la porta */
                if (!(PORTB & rowMask[rowScan])) // Riga rowScan trovata a massa
                {
                    delay_ms(200); //Ritardo spike
                    if (!(PORTB & rowMask[rowScan])) {
                        /*Se viene confermato che un pulsante è stato premuto, imposto
                         *il valore che permette di risalire al tasto e indico al programma
                         *che un pulsante è stato premuto */
                        keypressed=rowScan+(4*colScan); // numero di pulsante premuto
                        keyok=1; // è stato premuto un pulsante
                    }
                }
            } // fine scansione righe
        }//for // fine scansione colonne

        if (keyok) // è stato premuto un pulsante
        {

             code_index++;
            // Solo dopo che ho controllato in che punto si trova il
            // cursore posso piazzare il carattere premuto
            LCD_goto_line (2);
            LCD_write_char(keys[keypressed]);
         
            keyok=0; // resetto il flag del pulsante premuto

            // rimango in un ciclo continuo fino a che il pulsante non viene rilasciato
            PORTB=0b10101010;
            while(PORTB != 0b10101010)
                /*Se voglio che i simboli visualizzati siano senpre visibili sul
                 display (cioè cambino alla pressione del tasto) omettere:
                 LCD_goto_line (2);
                 LCD_write_message ("      ");*/
                LCD_goto_line (2);

            //delay_s(1);  //determino per quanto tempo voglio visualizzare il simbolo
             delay_ms(800);

                LCD_write_message ("      ");
                   {continue;}
        }//if (keyok)

        if (code_index == dim) {  // controllo codice
   for ( k=0; k=<dim; k++) {

   if (key_code[k] == pressed_code[k]){
    code_ok = 1;
     }//if (code_index == dim
   else {  // cifra del codice errata, codice sbagliato
    code_ok = 0;  // codice errato, esce dal ciclo
         break; // <<<<<<=== aggiunto break
     }//else
    }//for
if (code_ok == 1){  // se il codice è giusto accendo LATD0
  LATDbits.LATD0  = 1;
}//if (code_ok == 1
  else { 
   LATDbits.LATD0 = 0;
  }//else
   code_ok = 0;  // resetto la variabile se il codice è giusto (cioè se code_ok era = 1)
   code_index = 0;  // resetto l'indice che scorre l'array del codice

     } // if (code_index == dim)
    }//while
}//main


//*************************************
//     Implementazione della funzione
//*************************************
void board_initialization (void) {
//******************//
//Impostazione porte//
//******************//
   // Imposto PORTA tutti ingressi
   LATA = 0x00;
   TRISA = 0x00;

   // Imposto PORTB
   LATB = 0x00;
   TRISB = 0b10101010;

   // Imposto PORTC tutti ingressi e RC1 come uscita
   LATC = 0x00;
   TRISC = 0b11111101;

   // Imposto PORTD tutte uscite
   LATD = 0x00;
   TRISD = 0x00;

   // Imposto PORTE tutti ingressi
   LATE = 0x00;
   TRISE = 0xFF;
}//void board_initialization (void)

//*************************************
//          Funzione serratura
//*************************************
//void serratura_elettronica (void){
 

     /*if ( tasto1 == 0 ) {
        //Questa funzione serve a far scorrere la scritta.
//x determina di quanto deve spostarsi la scritta.
//y se 1 la scritta scorre sopra, se 2 sotto.
LCD_goto_xy (x,2);
    LCD_write_message ("*");

  }//if
else {
// Altrimenti codice errato, led spento
LATAbits.LATA1 = 0;
     }//else

  if ( tasto2 == 0 ) {
        //Questa funzione serve a far scorrere la scritta.
//x determina di quanto deve spostarsi la scritta.
//y se 1 la scritta scorre sopra, se 2 sotto.
LCD_goto_xy (y,2);
    LCD_write_message ("*");

  }//if
else {
// Altrimenti codice errato, led spento
LATAbits.LATA1 = 0;
     }//else
  */
 
// }//void serratura_elettronica


errore:

Codice: Seleziona tutto
Serratura elettronica.c:174: error: (195) expression syntax
(908) exit status = 1
nbproject/Makefile-default.mk:94: recipe for target 'build/default/production/Serratura elettronica.p1' failed
make[2]: *** [build/default/production/Serratura elettronica.p1] Error 1
make[2]: Leaving directory 'C:/Users/guido/MPLABXProjects/Serratura elettronica.X'
make[1]: *** [.build-conf] Error 2
nbproject/Makefile-default.mk:78: recipe for target '.build-conf' failed
make: *** [.build-impl] Error 2
make[1]: Leaving directory 'C:/Users/guido/MPLABXProjects/Serratura elettronica.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed

BUILD FAILED (exit value 2, total time: 1s)


dove:

for ( k=0; k=<dim; k++) {
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[4] Re: Serratura elettronica

Messaggioda Foto UtenteDanteCpp » 12 apr 2015, 15:36

#define dim 4 // lunghezza del codice segreto
unsigned char key_code[dim] = {'1','2','3','4'};
unsigned char pressed_code[dim];
char code_index = 0;
char code_ok = 0; // variabile per determinare se il codice è esatto

if (code_index == dim) {
...


essendo code_index = 0 e dim = 4, non si verificherà mai code_index == dim

O_/
Avatar utente
Foto UtenteDanteCpp
4.730 3 9 13
Master EY
Master EY
 
Messaggi: 1106
Iscritto il: 15 dic 2011, 18:51

0
voti

[5] Re: Serratura elettronica

Messaggioda Foto Utentebobina » 12 apr 2015, 19:41

Penso che l'errore di compilazione che hai dipende da questo pezzo di codice:

Codice: Seleziona tutto
            while(PORTB != 0b10101010)
                /*Se voglio che i simboli visualizzati siano senpre visibili sul
                 display (cioè cambino alla pressione del tasto) omettere:
                 LCD_goto_line (2);
                 LCD_write_message ("      ");*/
                LCD_goto_line (2);

            //delay_s(1);  //determino per quanto tempo voglio visualizzare il simbolo
             delay_ms(800);

                LCD_write_message ("      ");
                   {continue;}

il ciclo while può diventare

Codice: Seleziona tutto
while(PORTB != 0b10101010){}
o
while(PORTB != 0b10101010);

e l'ultima riga {continue;} può scomparire, quell'errore di compilazione credo di fosse anche prima.
Avatar utente
Foto Utentebobina
212 6
Frequentatore
Frequentatore
 
Messaggi: 177
Iscritto il: 27 dic 2009, 14:22

0
voti

[6] Re: Serratura elettronica

Messaggioda Foto Utenteguidonetto » 12 apr 2015, 20:08

Ciao, ho fatto le correzioni, non va.

Codice: Seleziona tutto
/*Nota: codice tratto da settorezero, riadattato da: StefA */

#include <xc.h>

#include "PIC18F4550_config.h"

#define  LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"

#include "delay.h"
#include "delay.c"


//*************************************
//     Prototipi di funzione
//*************************************
void board_initialization (void);
//void serratura_elettronica (void);

/* tastierino numerico collegato su PORTB
uso un tastierino 4x4 (16 pulsanti)
Per comodità ho collegato il tastierino in questo modo
(C=colonna R=riga)
R1 = RB1
R2 = RB3
R3 = RB5
R4 = RB7
C1 = RB0
C2 = RB2
C3 = RB4
C4 = RB6
I pin di riga saranno input ed attiveremo le resistenze di pullup interne
i pin di colonna saranno output e messi a 1 di default
*/

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le colonne una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore colMask[0] al valore colMask[3], porto a massa le colonne una alla volta. */
unsigned char colMask[]=
   {
   0b11111110, // Colonna 1 => RB0 a massa
   0b11111011, // Colonna 2 => RB2 a massa
   0b11101111, // Colonna 3 => RB4 a massa
   0b10111111 // Colonna 4 => RB6 a massa
   };
unsigned char colScan=0; // va da 0 a 3 per scansionare l'array colMask

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le righe una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore rowMask[0] al valore rowMask[3], porto a massa le righe una alla volta. */
unsigned char rowMask[]=
   {
   0b00000010, // Riga 1
   0b00001000, // Riga 2
   0b00100000, // Riga 3
   0b10000000 // Riga 4
   };
unsigned char rowScan=0; // va da 0 a 3 per scansionare l'array rowMask

//Array che contiene i simboli disegnati sui pulsanti del tastierino, disposti in un certo ordine:
unsigned char keys[]={'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'};
unsigned char keypressed=0; // peso numerico del pulsante premuto
unsigned char keyok; // flag del pulsante premuto

//unsigned char x=1;
//unsigned char y=2;
//unsigned char z=3;

unsigned char k;

// Impostazione codice segreto e inizializzazione codice digitato

#define dim 4  // lunghezza del codice segreto
unsigned char key_code[dim] = {'1','2','3','4'};
unsigned char pressed_code[dim];
char code_index = 0;
char code_ok = 0;  // variabile per determinare se il codice è esatto



//*************************************
//     Programma principale
//*************************************
int main (void){

    unsigned char frase [] = "   StefA TEST   ";

    // Abilita i resistori di pull-up sulla PORTB
    INTCON2bits.RBPU = 0x00;

    keyok=0;

    board_initialization ();

    //serratura_elettronica ();

    // Inizializzo il display LCD con quarzo a 20MHz
    LCD_initialize (20);

    LCD_backlight (LCD_TURN_ON_LED);

    LCD_write_message ("Tastiera Matrice");

    LCD_goto_line (2);

    LCD_write_string (frase);

    delay_s(2);

    LCD_clear();

    LCD_write_message ("Premere un tasto");

    // Ciclo infinito
    while(1) {
        /*Effettuo la scansione delle colonne contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array colMask */
        for (colScan=0; colScan<4; colScan++) // porto a massa una colonna alla volta
        {
            PORTB=0xFF; // porto tutte le colonne a 1
            PORTB &= colMask[colScan]; // porto a zero la colonna attuale

        /*Effettuo la scansione delle righe contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array rowMask */
            for (rowScan=0; rowScan<4; rowScan++) {
                /*Controllo se la riga attuale si trova a massa effettuando un AND
                 *con l?elemento dell?array rowScan che mi permette di verificare soltanto
                 *il bit che mi interessa su tutta la porta */
                if (!(PORTB & rowMask[rowScan])) // Riga rowScan trovata a massa
                {
                    delay_ms(200); //Ritardo spike
                    if (!(PORTB & rowMask[rowScan])) {
                        /*Se viene confermato che un pulsante è stato premuto, imposto
                         *il valore che permette di risalire al tasto e indico al programma
                         *che un pulsante è stato premuto */
                        keypressed=rowScan+(4*colScan); // numero di pulsante premuto
                        keyok=1; // è stato premuto un pulsante
                    }
                }
            } // fine scansione righe
        }//for // fine scansione colonne

        if (keyok) // è stato premuto un pulsante
        {
             code_index++;   
            // Solo dopo che ho controllato in che punto si trova il
            // cursore posso piazzare il carattere premuto
            LCD_goto_line (2);
            LCD_write_char(keys[keypressed]);

            keyok=0; // resetto il flag del pulsante premuto

            // rimango in un ciclo continuo fino a che il pulsante non viene rilasciato
            PORTB=0b10101010;
            while(PORTB != 0b10101010)
                /*Se voglio che i simboli visualizzati siano senpre visibili sul
                 display (cioè cambino alla pressione del tasto) omettere:
                 LCD_goto_line (2);
                 LCD_write_message ("      ");*/
                LCD_goto_line (2);

            //delay_s(1);  //determino per quanto tempo voglio visualizzare il simbolo
             delay_ms(800);

                LCD_write_message ("      ");
                   {continue;}
        }//if (keyok)

        if (code_index == dim) {  // controllo codice
   for ( k=0; k<dim-1; k++) {

   if (key_code[k] == pressed_code[k]){
    code_ok = 1;
     }//if (code_index == dim
   else {  // cifra del codice errata, codice sbagliato
    code_ok = 0;  // codice errato, esce dal ciclo
        break; // <<<<<<=== aggiunto break
     }//else
    }//for
if (code_ok == 1){  // se il codice è giusto accendo LATD0
  LATDbits.LATD0  = 1;
}//if (code_ok == 1
  else {
   LATDbits.LATD0 = 0;
  }//else
   code_ok = 0;  // resetto la variabile se il codice è giusto (cioè se code_ok era = 1)
   code_index = 0;  // resetto l'indice che scorre l'array del codice

     } // if (code_index == dim)
    }//while
}//main


//*************************************
//     Implementazione della funzione
//*************************************
void board_initialization (void) {
//******************//
//Impostazione porte//
//******************//
   // Imposto PORTA tutti ingressi
   LATA = 0x00;
   TRISA = 0x00;

   // Imposto PORTB
   LATB = 0x00;
   TRISB = 0b10101010;

   // Imposto PORTC tutti ingressi e RC1 come uscita
   LATC = 0x00;
   TRISC = 0b11111101;

   // Imposto PORTD tutte uscite
   LATD = 0x00;
   TRISD = 0x00;

   // Imposto PORTE tutti ingressi
   LATE = 0x00;
   TRISE = 0xFF;
}//void board_initialization (void)

//*************************************
//          Funzione serratura
//*************************************
//void serratura_elettronica (void){


     /*if ( tasto1 == 0 ) {
        //Questa funzione serve a far scorrere la scritta.
//x determina di quanto deve spostarsi la scritta.
//y se 1 la scritta scorre sopra, se 2 sotto.
LCD_goto_xy (x,2);
    LCD_write_message ("*");

  }//if
else {
// Altrimenti codice errato, led spento
LATAbits.LATA1 = 0;
     }//else

  if ( tasto2 == 0 ) {
        //Questa funzione serve a far scorrere la scritta.
//x determina di quanto deve spostarsi la scritta.
//y se 1 la scritta scorre sopra, se 2 sotto.
LCD_goto_xy (y,2);
    LCD_write_message ("*");

  }//if
else {
// Altrimenti codice errato, led spento
LATAbits.LATA1 = 0;
     }//else
  */

// }//void serratura_elettronica


Posto anche il codice della sola tastiera a matrice.

Codice: Seleziona tutto
/*Nota: codice tratto da settorezero, riadattato da: StefA */

#include <xc.h>

#include "PIC18F4550_config.h"

#define LCD_DEFAULT
#include "LCD_44780.h"
#include "LCD_44780.c"

#include "delay.h"
#include "delay.c"

//*************************************
//     Prototipo di funzione
//*************************************
void board_initialization (void);

/* tastierino numerico collegato su PORTB
uso un tastierino 4x4 (16 pulsanti)
Per comodità ho collegato il tastierino in questo modo
(C=colonna R=riga)
R1 = RB1
R2 = RB3
R3 = RB5
R4 = RB7
C1 = RB0
C2 = RB2
C3 = RB4
C4 = RB6
I pin di riga saranno input ed attiveremo le resistenze di pullup interne
i pin di colonna saranno output e messi a 1 di default
*/

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le colonne una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore colMask[0] al valore colMask[3], porto a massa le colonne una alla volta. */
unsigned char colMask[]=
   {
   0b11111110, // Colonna 1 => RB0 a massa
   0b11111011, // Colonna 2 => RB2 a massa
   0b11101111, // Colonna 3 => RB4 a massa
   0b10111111 // Colonna 4 => RB6 a massa
   };
unsigned char colScan=0; // va da 0 a 3 per scansionare l'array colMask

/* Definisco un array, che scansiona con un ciclo FOR, esso permette di mettere a massa
* le righe una alla volta e riporta a livello logico alto le altre.
* Andando quindi dal valore rowMask[0] al valore rowMask[3], porto a massa le righe una alla volta. */
unsigned char rowMask[]=
   {
   0b00000010, // Riga 1
   0b00001000, // Riga 2
   0b00100000, // Riga 3
   0b10000000 // Riga 4
   };
unsigned char rowScan=0; // va da 0 a 3 per scansionare l'array rowMask

//Array che contiene i simboli disegnati sui pulsanti del tastierino, disposti in un certo ordine:
unsigned char keys[]={'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'};
unsigned char keypressed=0; // peso numerico del pulsante premuto
unsigned char keyok; // flag di pulsante premuto


//*************************************
//     Programma principale
//*************************************
int main (void){

    unsigned char frase [] = "   StefA TEST   ";

    // Abilita i resistori di pull-up sulla PORTB   
    INTCON2bits.RBPU = 0x00;

    keyok=0;

    board_initialization ();

    // Inizializzo il display LCD con quarzo a 20MHz
    LCD_initialize (20);

    LCD_backlight (LCD_TURN_ON_LED);

    LCD_write_message ("Tastiera Matrice");

    LCD_goto_line (2);

    LCD_write_string (frase);

    delay_s(2);

    LCD_clear();

    LCD_write_message ("Premere un tasto");

    // Ciclo infinito
    while(1) {
        /*Effettuo la scansione delle colonne contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array colMask */
        for (colScan=0; colScan<4; colScan++) // porto a massa una colonna alla volta
        {
            PORTB=0xFF; // porto tutte le colonne a 1
            PORTB &= colMask[colScan]; // porto a zero la colonna attuale

        /*Effettuo la scansione delle righe contando da zero a 3 e metto i relativi
         *pin a livello logico basso uno alla volta, ripristinando a 1 gli altri facendo
         *uso dell?array rowMask */
            for (rowScan=0; rowScan<4; rowScan++) {
                /*Controllo se la riga attuale si trova a massa effettuando un AND
                 *con l?elemento dell?array rowScan che mi permette di verificare soltanto
                 *il bit che mi interessa su tutta la porta */
                if (!(PORTB & rowMask[rowScan])) // Riga rowScan trovata a massa
                {
                    delay_ms(50); //Ritardo spike
                    if (!(PORTB & rowMask[rowScan])) {
                        /*Se viene confermato che un pulsante è stato premuto, imposto
                         *il valore che permette di risalire al tasto e indico al programma
                         *che un pulsante è stato premuto */
                        keypressed=rowScan+(4*colScan); // numero di pulsante premuto
                        keyok=1; // è stato premuto un pulsante
                    }
                }
            } // fine scansione righe
        }//for // fine scansione colonne

        if (keyok) // è stato premuto un pulsante
        {
            // Solo dopo che ho controllato in che punto si trova il
            // cursore posso piazzare il carattere premuto
            //WriteCharLCD(keys[keypressed]);
            LCD_goto_line (2);
            LCD_write_char(keys[keypressed]);
    //         sound();
           

            keyok=0; // resetto il flag del pulsante premuto

            // rimango in un ciclo continuo fino a che il pulsante non viene rilasciato
            PORTB=0b10101010;
            while(PORTB != 0b10101010)
                /*Se voglio che i simboli visualizzati siano senpre visibili sul
                 display (cioè cambino alla pressione del tasto) omettere:
                 LCD_goto_line (2);
                 LCD_write_message ("      ");*/
                LCD_goto_line (2);
            //delay_s(1);  //determino per quanto tempo voglio visualizzare il simbolo
             delay_ms(800);
                LCD_write_message ("      ");
                   {continue;}
        }//if (keyok)
    }//while
}//main


//*************************************
//     Implementazione della funzione
//*************************************
void board_initialization (void) {
//******************//
//Impostazione porte//
//******************//
   // Imposto PORTA tutti ingressi
   LATA = 0x00;
   TRISA = 0xFF;

   // Imposto PORTB
   LATB = 0x00;
   TRISB = 0b10101010;

   // Imposto PORTC tutti ingressi e RC1 come uscita
   LATC = 0x00;
   TRISC = 0b11111101;

   // Imposto PORTD tutte uscite
   LATD = 0x00;
   TRISD = 0x00;

   // Imposto PORTE tutti ingressi
   LATE = 0x00;
   TRISE = 0xFF;
}//void board_initialization (void)



Vi ringrazio dei vostri suggerimenti.
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[7] Re: Serratura elettronica

Messaggioda Foto Utentebobina » 12 apr 2015, 20:17

Questa parte non è cambiata:

Codice: Seleziona tutto
            while(PORTB != 0b10101010)
                /*Se voglio che i simboli visualizzati siano senpre visibili sul
                 display (cioè cambino alla pressione del tasto) omettere:
                 LCD_goto_line (2);
                 LCD_write_message ("      ");*/
                LCD_goto_line (2);
            //delay_s(1);  //determino per quanto tempo voglio visualizzare il simbolo
             delay_ms(800);
                LCD_write_message ("      ");
                   {continue;}

Non mi è chiaro il senso. Il ciclo while dovrebbe essere un loop infinito in attesa che il tasto venga rilasciato, dopo il rilascio viene spostato il cursore del LCD alla riga 2 ed attende 800ms e cancella la riga.
Avatar utente
Foto Utentebobina
212 6
Frequentatore
Frequentatore
 
Messaggi: 177
Iscritto il: 27 dic 2009, 14:22

0
voti

[8] Re: Serratura elettronica

Messaggioda Foto Utenteguidonetto » 12 apr 2015, 20:45

Si, quello che hai scritto è giusto.
ho postato il codice della sola tastiera, se hai un'altra idea di come scrivere il programma per la serratura, ottimo, ti seguo.
Avatar utente
Foto Utenteguidonetto
13 1 5
Frequentatore
Frequentatore
 
Messaggi: 124
Iscritto il: 8 mag 2011, 21:08

0
voti

[9] Re: Serratura elettronica

Messaggioda Foto Utentebobina » 12 apr 2015, 20:55

Quello che volevo dire però, il cambio che ti avevo suggerito per risolvere il problema di compilazione non c'è nell'ultimo sorgente che hai postato, è una distrazione di copia e incolla oppure c'è rimasto quel {continue;}
non credo perché la compilazione fallirebbe.
Così com'è strutturato il codice dovrebbe funzionare.
Avatar utente
Foto Utentebobina
212 6
Frequentatore
Frequentatore
 
Messaggi: 177
Iscritto il: 27 dic 2009, 14:22

1
voti

[10] Re: Serratura elettronica

Messaggioda Foto UtenteWALTERmwp » 12 apr 2015, 21:19

Ciao Foto Utenteguidonetto, ma esattamente, a prescindere, ora, dall'errore di compilazione puoi essere più chiaro nel descrivere quanto non corrisponde alle aspettative ?
Presuppongo poi che i collegamenti hardware corrispondano a quanto previsto.

Un'altra cosa, quel
Codice: Seleziona tutto
{continue;}
che senso avrebbe ?

Potresti magari evitare quel
Codice: Seleziona tutto
break; // <<<<<<=== aggiunto break
?

Poi, nel primo Post hai riportato il codice completo e, di seguito, hai ripreso un'altra porzione del medesimo, se non erro; in tal caso evita di farlo, dai evidenza, nel primo, di quanto vuoi segnalare.
Evitiamo ridondanze e rendiamo il thread più leggibile.
Grazie

Saluti

p.s.
(rendiamo il thread più leggibile ... ) stessa cosa per il Post [6].
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8981
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 7 ospiti