Go Down

Topic: Lecteur de carte à puce (Read 2639 times) previous topic - next topic

Bonjour je travaille actuellement sur un projet de lecteur de carte à puce pour ouvrir une porte.
Bien que j'aie réussie mon exercice j'ai souhaité l'améliorer en créant une carte admin qui permet de changer le type de carte accepté sauf que problème le programme ne fonctionne et là je bloque donc si quelqu'un pouvait m'expliquer d'où vient l'erreur dans mon programme (je pense que c'est le for mais je ne voix pas comment faire autrement).

Déclaration et initialisation des variables
Quote
#include <EEPROM.h>

int RAZ = 5;
int H = 2;
int ACK = 3; // capteur présence carte
int S = 4;
int val  ;
int gache = 9;
int ledV = 13;
int ledR = 12;
boolean CarteState;
boolean BitState;
boolean value [8];
boolean value2 [8];


void setup()   {       
Serial.begin(9600);
  // prints title with ending line break
    // initialisation des entrées analogiques;
  pinMode(RAZ, OUTPUT);
  pinMode(H, OUTPUT);
  pinMode(S, INPUT);
  pinMode(ACK, INPUT);
  pinMode(gache, OUTPUT);
  pinMode(ledV, OUTPUT);
  pinMode(ledR, OUTPUT); 
}



Début de la boucle principale avec vérification si il y a présence d'une carte et initialisation de celle-ci
Quote
void loop (){   

CarteState = digitalRead(ACK);
while (CarteState == HIGH ){
  Serial.println("carte absente")  ;
  delay (1000);
  CarteState = digitalRead(ACK);
}
Serial.println("carte presente");


//initialisation de la carte

digitalWrite (RAZ, LOW); //début RAZ
digitalWrite (H,LOW);
delay (25);

digitalWrite (RAZ, LOW);
digitalWrite (H, HIGH);
delay (25);

digitalWrite (RAZ, LOW);
digitalWrite (H, LOW);
   
delay (50);
//fin initialisation de la carte



Début de lecture du premier valeur qu'on stock dans une variable value et on effectué 7 fois la boucle pour acquérir les 8 premiers bits
Quote
digitalWrite (RAZ, HIGH); // lecture bit 1

//debut de lecture carte

for (int i=0; i <= 7; i++)
{
      // impulsion de ratio HAUT/BAS fonction de i sur la broche 10
    digitalWrite (H, LOW);
    delay (25);
    value=digitalRead(S);
    digitalWrite (H, HIGH);
    if(value==HIGH){Serial.println("1");}
    else {Serial.println("0");}
    delay (25);
}



[font=Verdana]C'est à partir de là que je ne suis pas sûr de mon programme[/font]

J'insère une carte ,si les 8 premiers bits (value) de ma carte sont égales à une valeur que j'aurai préalablement stocker dans l'EEPROM alors on allume la led verte et on ouvre la gâche sinon on allume la del rouge
Quote
for (byte i=0; i <=7; i++)
    if (  value == EEPROM.read (i) )
    {
    digitalWrite (gache , HIGH);
    digitalWrite ( ledV, HIGH);

    delay (5000);
    digitalWrite (gache , LOW);
    digitalWrite ( ledV, LOW);
  }

  else
     {
     digitalWrite ( ledR, HIGH);
     delay (5000);
     digitalWrite (ledR, LOW);
   }
   


Ou sinon si la carte insérer à les mêmes valeurs que celles écrites que celle écrite à la suite (c'est à dire 10110111) alors on enclenche le mode admin et le capteur de carte reste sur le niveau haut pour que je puisse changer de carte sans repartir au début de ma boucle.
Quote
if ( value
  • == 1 && value [1] == 0 && value [2] == 1 && value [3] == 1 && value [4] == 0 && value [5] == 1 && value [6] == 1 && value [7] == 1 )// Carte 1 ADMIN
        {
       // digitalWrite (ACK, HIGH);     
        digitalWrite (ledR, HIGH);
        digitalWrite (ledV, HIGH);
             delay (5000);
                 delay (5000);
                     delay (5000);
                         delay (5000);
                             delay (5000);
                                 delay (5000);
                                     delay (5000);
                                         delay (5000);
                                             delay (5000);
                                                 delay (5000);
                                         



On refait une nouvelle initialisation de la nouvelle carte
Quote
//initialisation de la carte

    digitalWrite (RAZ, LOW); //début RAZ
    digitalWrite (H,LOW);
    delay (25);
   
    digitalWrite (RAZ, LOW);
    digitalWrite (H, HIGH);
    delay (25);
   
    digitalWrite (RAZ, LOW);
    digitalWrite (H, LOW);
       
    delay (50);
    //fin initialisation de la carte



On relit les 8 premiers bits de la carte mais cette fois-ci on les stock dans une variable value2 et on écrit ses valeurs dans l'EEPROM pour remplacer les anciennes.
Quote
digitalWrite (RAZ, HIGH); // lecture bit 1
   
    //debut de lecture carte
     
    for (int i=0; i <= 7; i++)
    {
          // impulsion de ratio HAUT/BAS fonction de i sur la broche 10
        digitalWrite (H, LOW);
        delay (25);
        value2=digitalRead(S);
        EEPROM.write(i, value2);
        digitalWrite (H, HIGH);
        if(value==HIGH){Serial.println("1");}
        else {Serial.println("0");}
        delay (25);
    }
      }
     
      else
         {
         digitalWrite ( ledR, HIGH);
         delay (5000);
         digitalWrite (ledR, LOW);
       }


}




Merci d'avance

zoroastre

#1
Feb 13, 2012, 03:09 pm Last Edit: Feb 13, 2012, 04:00 pm by zoroastre Reason: 1
Yep!

Tout d'abord, il n'y a pas de stockage de la variable value, tu ne fais que l'afficher.

Remplacer boolean value[8] par byte value[8] (idem pour value2, tu travailles avec des bytes, autant garder ce type du début à la fin)

Code: [Select]
for (int i=0; i <= 7; i++)
{
  temp=digitalRead(S); // on stocke temporairement la valeur
  ...
  if(temp==HIGH){value[i] = 1;} // archivage dans le tableau value a l'index i
  else {value[i] = 0;}
...
}


Ensuite, pour la comparaison avec les valeurs stockées dans l'eeprom :

Changes :
Code: [Select]
for (byte i=0; i <=7; i++)
    if (  value == EEPROM.read (i) )

En :
Code: [Select]
for (byte i=0; i <=7; i++)
    if (  value[i] == EEPROM.read(i) )


C'est en gros ce que j'ai vu de plus flagrant ;)

@+

Zoroastre.
Gné! ;)

Merci de ta réponse par contre je ne comprends pas cette partie?

Code: [Select]
for (int i=0; i <= 7; i++)
{
  temp=digitalRead(S); // on stocke temporairement la valeur
  ...
  if(temp==HIGH){value[i] = 1;} // archivage dans le tableau value a l'index i
  else {value[i] = 0;}
...
}




zoroastre

#3
Feb 13, 2012, 06:53 pm Last Edit: Feb 13, 2012, 07:02 pm by zoroastre Reason: 1
Yep!

byte value[8] est un tableau de 8 bytes.

A chaque incrémentation de i, tu mets la valeur de S dans le tableau value à l'index i
value[0] <- Première lecture i = 0,
value[1] <- Deuxième lecture i = 1,
etc.
Ex : [1, 1, 0, 0, 1, 1, 1, 0]

On pourrait directement faire :

Code: [Select]
value[i] = digitalRead(S);

ou

Code: [Select]

if (digitalRead(S) == HIGH) { value[i] = 1; }
...


Comme tu as des changements d'état entre 2, je suis passé par une variable temporaire pour respecter ton code.

Dans ton code original, tu effectuais simplement un Serial.print de la valeur et tu ne remplissais pas le tableau du début à la fin.

Code: [Select]
value=digitalRead(S);

@+

Zoroastre.
Gné! ;)

#4
Feb 14, 2012, 07:35 pm Last Edit: Feb 14, 2012, 09:26 pm by Jean-François Reason: 1
Après test ça marche pas du tout j'ai trouvé et ça bloque au niveau du for qui ne s'effectue pas correctement.
Code: [Select]
for (byte i=0; i <=7; i++)
   if (  value == EEPROM.read (i) )
   {
   digitalWrite (gache , HIGH);
   digitalWrite ( ledV, HIGH);

   delay (5000);
   digitalWrite (gache , LOW);
   digitalWrite ( ledV, LOW);
 }

 else
    {
    digitalWrite ( ledR, HIGH);
    delay (5000);
    digitalWrite (ledR, LOW);
  }

zoroastre

#5
Feb 14, 2012, 07:50 pm Last Edit: Feb 14, 2012, 08:04 pm by zoroastre Reason: 1
Yep!

Ajoutes des Serial.println(value) ici et là dans ton sketch. Regardes le resultat dans le moniteur et relis ce que j'ai écrit plus haut.
Tu attends une variable de 8 bytes et elle en contiendra qu'un seul...

@+

Zoroastre.
Gné! ;)

Alors en fait désolé mais les n'apparaissent pas dans mon code mais ils sont bien présent.

Jean-François

Edite tes message et mets le code dans les balises que tu auras avec le boutons "#".
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Ok merci donc voici le programme
Code: [Select]
#include <EEPROM.h>

int RAZ = 5;
int H = 2;
int ACK = 3;
int S = 4;
int val  ;
int gache = 9;
int ledV = 13;
int ledR = 12;
boolean CarteState;
boolean BitState;
byte value [8];
byte value2 [8];


void setup()   {       
Serial.begin(9600);
  // prints title with ending line break
    // initialisation des entrées analogiques;
  pinMode(RAZ, OUTPUT);
  pinMode(H, OUTPUT);
  pinMode(S, INPUT);
  pinMode(ACK, INPUT);
  pinMode(gache, OUTPUT);
  pinMode(ledV, OUTPUT);
  pinMode(ledR, OUTPUT); 
}

void loop (){   

CarteState = digitalRead(ACK);
while (CarteState == HIGH ){
  Serial.println("carte absente")  ;
  delay (1000);
  CarteState = digitalRead(ACK);
}
Serial.println("carte presente");


//initialisation de la carte

digitalWrite (RAZ, LOW); //début RAZ
digitalWrite (H,LOW);
delay (25);

digitalWrite (RAZ, LOW);
digitalWrite (H, HIGH);
delay (25);

digitalWrite (RAZ, LOW);
digitalWrite (H, LOW);
   
delay (50);
//fin initialisation de la carte
digitalWrite (RAZ, HIGH); // lecture bit 1

//debut de lecture carte

for (int i=0; i <= 7; i++)
{
      // impulsion de ratio HAUT/BAS fonction de i sur la broche 10
    digitalWrite (H, LOW);
    delay (25);
    value[i]=digitalRead(S);
    digitalWrite (H, HIGH);
    if(value[i]==HIGH){Serial.println("1");}
    else {Serial.println("0");}
    delay (25);
}

for (byte i=0; i <=7; i++)
    if (  value [i] == EEPROM.read (i) )
    {
    digitalWrite (gache , HIGH);
    digitalWrite ( ledV, HIGH);

    delay (5000);
    digitalWrite (gache , LOW);
    digitalWrite ( ledV, LOW);
  }

  else
     {
     digitalWrite ( ledR, HIGH);
     delay (5000);
     digitalWrite (ledR, LOW);
   }
   
    if ( value [0] == 1 && value [1] == 0 && value [2] == 1 && value [3] == 1 && value [4] == 0 && value [5] == 1 && value [6] == 1 && value [7] == 1 )// Carte 1 ADMIN
    {
   // digitalWrite (ACK, HIGH);     
    digitalWrite (ledR, HIGH);
    digitalWrite (ledV, HIGH);
         delay (5000);
             delay (5000);
                 delay (5000);
                     delay (5000);
                         delay (5000);
                             delay (5000);
                                 delay (5000);
                                     delay (5000);
                                         delay (5000);
                                             delay (5000);
                                     

 
      //initialisation de la carte

    digitalWrite (RAZ, LOW); //début RAZ
    digitalWrite (H,LOW);
    delay (25);
   
    digitalWrite (RAZ, LOW);
    digitalWrite (H, HIGH);
    delay (25);
   
    digitalWrite (RAZ, LOW);
    digitalWrite (H, LOW);
       
    delay (50);
    //fin initialisation de la carte
    digitalWrite (RAZ, HIGH); // lecture bit 1
   
    //debut de lecture carte
     
    for (int i=0; i <= 7; i++)
    {
          // impulsion de ratio HAUT/BAS fonction de i sur la broche 10
        digitalWrite (H, LOW);
        delay (25);
        value2[i]=digitalRead(S);
        EEPROM.write(i, value2[i]);
        digitalWrite (H, HIGH);
        if(value[i]==HIGH){Serial.println("1");}
        else {Serial.println("0");}
        delay (25);
    }
      }
     
      else
         {
         digitalWrite ( ledR, HIGH);
         delay (5000);
         digitalWrite (ledR, LOW);
       }


}






osaka

Yop yop,

Question qui m'intéresse et qui pourrait nous aider à comprendre ton code, tu pourrais donner les détails de ton lecteur de carte à puce ?
Sinon pour le programme tu peux remplacer tout tes int (2 octet) par des byte (1 octet pour les valeurs allant de 0 à 255).
Voir également l'instruction #define qui pourrais être intéressante.
Autre chose qui pourrais être intéressant, enfin plus au niveau de l'apprentissage histoire de t'amélioré et bon à savoir, c'est de travaillé au niveau binaire plutôt qu'utilisé des tableau de t'aille 8 (donc 8 octet), 1 octet c'est justement 8 bit. (c'est pas un hasard je suppose que les valeurs de ta carte soient de taille 8 ) (tu peux toujours demandé quelques astuces ou explication si tu veux le faire, on t'aidera)
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Bitabit
Beaucoup de delay() peut être songer à ceci par exemple http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Là j'ai du mal à comprendre.  :smiley-sad-blue: :smiley-mr-green:
Code: [Select]

        delay (5000);
            delay (5000);
                delay (5000);
                    delay (5000);
                        delay (5000);
                            delay (5000);
                                delay (5000);
                                    delay (5000);
                                        delay (5000);
                                            delay (5000);


Enfin pas vraiment de solution pour ton programme (manque d'info sur ton lecteur) s'il subsiste encore des problèmes, mais plus quelques petit conseils utiles, on sais jamais.  ;)

Voici les infos sur mon lecteur avec de la doc http://pascool.cool.free.fr/lecteur.doc
Sinon mon lecteur peut lire les 256 bits mais moi je m'intéressent juste aux 8 premiers.
Pour la tempo c'est le seule moyens que j'ai trouvé pour laisser le signal ACK au niveau  haut le temps de changer de carte

osaka

#11
Feb 15, 2012, 07:17 pm Last Edit: Feb 15, 2012, 07:32 pm by osaka Reason: 1

Voici les infos sur mon lecteur avec de la doc http://pascool.cool.free.fr/lecteur.doc

J'ai regardé rapidement mais ça à l'air sympa  :smiley-surprise: .


Sinon mon lecteur peut lire les 256 bits mais moi je m'intéressent juste aux 8 premiers.



Pour la tempo c'est le seule moyens que j'ai trouvé pour laisser le signal ACK au niveau  haut le temps de changer de carte


C'est pas ceci qui te permettrait un tempo entre changement de carte ?
Code: [Select]

CarteState = digitalRead(ACK);
while (CarteState == HIGH ){
 Serial.println("carte absente")  ;
 delay (1000);
 CarteState = digitalRead(ACK);
}
Serial.println("carte presente");


Si pas besoin de CarteState dans le reste du code tu peux faire directement:
Code: [Select]

while (digitalRead(ACK))
{
 Serial.println("carte absente")  ;
 delay (1000);
}
Serial.println("carte presente");


Tu peux même faire.
Code: [Select]

void loop()
{
 if(!digitalRead(ACK)) // si l'entrée est à 0 ('!' ici veux dire différent et comme toute valeurs différentes de 0 est considéré comme vrai)
 {
   Serial.println("carte presente");
   //tout le reste du code
 }
 else
 {
   Serial.println("carte absente")  ;
   delay (1000);
 }
}


Il faut initialisé la carte à chaque lecture (en boucle) ?
(je crois que tu as dupliqué du code ou mauvais copier coller)
Lecture 1 seul fois lors de l'insertion de la carte ou constamment ?
(! au cas ou, voir loop comme une boucle infinie)

Alors le CarteState est juste là pour le serial monitor
Oui il faut à chaque fois initialiser dès qu'une carte est mis.
Ensuite je fais une boucle for pour lire les 8 premiers bits.

osaka

#13
Feb 15, 2012, 08:24 pm Last Edit: Feb 15, 2012, 08:33 pm by osaka Reason: 1

Alors le CarteState est juste là pour le serial monitor
Oui il faut à chaque fois initialiser dès qu'une carte est mis.
Ensuite je fais une boucle for pour lire les 8 premiers bits.


Donc initialisation et lecture qu'une seule fois à l'insertion de la carte.
Bien faire attention à la fonction "void loop()" qui correspond à une boucle infinie en réalité (while(1)).

Code: [Select]

void loop()
{
 //code bouclé constament
}


est identique à

Code: [Select]

while(1)
{
 //code bouclé constament
}


Le véritable visage du code final arduino.

Code: [Select]

int main(void)
{
init();

setup();
   
for (;;)
loop();
       
return 0;
}


donc tout le code que tu mets dans loop est répété constamment.
Ce que tu dois faire normalement (je suppose) c'est initialisé et lire une seule fois à l'introduction d'une carte ?
Parce que là en plus tu vas rapidement  avoir un problème avec ton eeprom qui est limité en cycles de lecture/écriture (100 000 ?)

Oui je sais et justement c'est un lecteur de carte donc tu met ta carte la gâche s'ouvre et tu enlève ta carte donc c'est bon.
En ce qui concerne l'EEPROM il n'y a qu'une carte qui permet d'écrire dans l'eeprom: carte admin

Go Up