Pagina 1 di 2

Serratura elettronica

MessaggioInviato: 12 apr 2015, 9:15
da guidonetto
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)


Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 11:21
da bobina
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 :-)

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 15:26
da guidonetto
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++) {

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 15:36
da DanteCpp
#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_/

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 19:41
da bobina
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.

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 20:08
da guidonetto
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.

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 20:17
da bobina
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.

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 20:45
da guidonetto
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.

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 20:55
da bobina
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.

Re: Serratura elettronica

MessaggioInviato: 12 apr 2015, 21:19
da WALTERmwp
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].