Besoin d'aide pour un projet RFID

Bonjour, tout d'abord, je tiens a préciser que j'ai commencé dans l'arduino il y a 2 semaines et que j'ai 11 ans (étant nouveau dans le forum, je n'ai pas pu envoyer de fichier pour le code. Il sera directement dans le texte). J'aimerais créer un code pour lecteur RFID. J'aimerais qu'il y aie un nombre d'essai de scan de badge limité pour que quand une personne passe trop de fois le mauvais badge (3 fois par exemple), le lecteur se bloque pendant une certaine durée(30s). Je saurai afficher un message sur l'écran LCD, mais je ne sais pas comment le faire changer automatiquement(passer de "plus que 2 essais" a "plus que 1 essais")et qu'il se bloque au bout de 3 essai incorrects. Voici le code:

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
#include <SPI.h>
#include <MFRC522.h>
// ecrire ici le numero UID du bon badge
const byte bonUID[4] = {131, 191, 143, 237};
//
const int pinLEDVerte = 2; // LED verte
const int pinLEDRouge = 6; // LED rouge
const int buzzer = 3; // buzzer
const int relais = 4; // relais
const int pinRST = 5; // pin RST du module RC522
const int pinSDA = 53; // pin SDA du module RC522
MFRC522 rfid(pinSDA, pinRST);

void setup() {
lcd.begin(16, 2);
// put your setup code here, to run once:
SPI.begin();
rfid.PCD_Init();
pinMode(pinLEDVerte, OUTPUT);
pinMode(pinLEDRouge, OUTPUT);
pinMode(buzzer, OUTPUT);
pinMode(relais, OUTPUT);
}


void loop() {
  {
lcd.setCursor(0, 0);
  lcd.print(" Scannez votre");
  lcd.setCursor(0, 1);
  lcd.print("     badge");
  delay(700);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Scannez votre");
  lcd.setCursor(0, 1);
  lcd.print("     badge.");
  delay(700);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Scannez votre");
  lcd.setCursor(0, 1);
  lcd.print("     badge..");
  delay(700);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Scannez votre");
  lcd.setCursor(0, 1);
  lcd.print("     badge...");
  delay(700);
  }
lcd.begin(16, 2);
// put your main code here, to run repeatedly:
int refus = 0; // quand cette variable n'est pas nulle, c'est que le code est refusé
if (rfid.PICC_IsNewCardPresent()) // on a dédecté un tag
{
if (rfid.PICC_ReadCardSerial()) // on a lu avec succès son contenu
{
for (byte i = 0; i < rfid.uid.size; i++) // comparaison avec le bon UID
{
if (rfid.uid.uidByte[i] != bonUID[i]) {
refus++;
}
}
if (refus == 0) // UID accepté
{
// allume LED verte et affiche le message d'accès autorisé.
lcd.print("Scan en cours...");
delay(1000);
lcd.clear();
digitalWrite(pinLEDVerte, HIGH);
digitalWrite(relais, HIGH);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
lcd.setCursor(0, 0);
lcd.print(" Acces autorise");
lcd.setCursor(0, 1);
lcd.print("   Bienvenue");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("    La porte");
lcd.setCursor(0, 1);
lcd.print("   est ouverte");
delay(4000);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
lcd.clear();
delay(100);  
digitalWrite(pinLEDVerte, LOW);
digitalWrite(relais, LOW);
}
else { // UID refusé
// allume LED rouge et active buzzer 3 fois pendant 200ms et affiche le message d'accès refusé
lcd.print("Scan en cours...");
delay(1000);
lcd.clear();
lcd.print("  Acces refuse");
digitalWrite(pinLEDRouge, HIGH);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(200);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(200);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(1500);
lcd.clear();
lcd.print("  Badge errone");
delay(2000);
lcd.clear();
lcd.print("Plus que");
lcd.setCursor(0, 1);
lcd.print("2 essais");
delay(100);
digitalWrite(pinLEDRouge, LOW);
digitalWrite(buzzer, LOW);
}
}
}
}

J'espère avoir été bien clair. Bon après-midi a tous.

Salut @Elo22 et bienvenue sur le forum :wave: !

Moi 13, et tu fais bien moins de fautes d'orthographe que moi à ton âge :wink:
Mais revenons à nos moutons...


Pour ton problème :
Commence par formater correctement ton code avec le raccourci Ctrl+T (si tu es sur IDE Arduino !). Se sera plus lisible.
Ensuite, dans ton code, il y a beaucoup de delay(time_in_ms). Cette fonction d'Arduino est bloquante jusqu'à la fin du temps. Pour faire ton projet, tu peux utiliser la fonction millis().

Cette fonction compte le temps qu'il y a depuis le lancement du programme. Grâce à a, tu peux créer des système de temps non bloquants, par exemple "Blink without delay" d'Arduino :

/*
  Blink without Delay

  Turns on and off a light emitting diode (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.

  The circuit:
  - Use the onboard LED.
  - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
    and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
    is set to the correct LED pin independent of which board is used.
    If you want to know what pin the on-board LED is connected to on your
    Arduino model, check the Technical Specs of your board at:
    https://www.arduino.cc/en/Main/Products

  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
  modified 11 Nov 2013
  by Scott Fitzgerald
  modified 9 Jan 2017
  by Arturo Guadalupi

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Tu trouveras nombre de tutoriels sur Internet pour cette fonction.


Quand au système permettant de compter les passages des TAGs RFID devant le RC522, crée une variable de type uint8_t (int) qui servira de compteur, et une variable de type bool TagOk = False; qui servira à dire quand le tag est bon. Incrémente cette variable (avec le code nom_de_la_variable += 1; à chaque fois que le module détecte un TAG qui n'est pas le bon - et si le TAG est bon, remettre la variable conteur à 0mettre TagOk à True.

Une fois que c'est fait, faire des tests pour afficher ce que tu veux n'est pas compliqué.

Bien entendu, je suis loin d'être un expert, alors je raconte peut-être n'importe quoi...


Petit conseil, je vois que tu utilises un écran LCD seul, avec la bibliothèque LiquidCrystal.
Si tu veux te simplifier la vie (et ton câblage !), utilise un module I²C (à souder derrière l'écran). Tu pourras alors te contenter de 2 fils data (le SDA et le SCL du module). Pour les bibliothèque, c'est LiquidCrystal_I2C et Wire (gestion de l'I²C). C'est bien plus pratique.

Bonnes bidouilles et bon code !
Cordialement
Pandaroux007

EDIT : Je viens de trouver ça, à voir au chapitre "Programme du contrôle d’accès par un badge"

On préfère. Il y a pas mal de personnes qui consultent le forum depuis leur téléphone et ce n'est pas pratique de gérer les pièces jointes depuis un téléphone.

Merci beaucoup, je vais regarder. Mais je pense que je suis encore un peu trop novice pour ce genre de code. Merci quand même.
A bientot.

lcd.begin() ne doit être utilisé qu'une fois pour initialiser l'écran et non de manière répétitive dans loop(). On le place généralement dans le setup() où il configure l'écran et ensuite on ne l'utilise plus.

Tes 4 affichages de la consigne avec des delay() bloque le programme pendant quasiment 3s ce qui rend le programme peu réactif.
Il serait préférable de faire une boucle plus courte qui affiche la consigne et qui teste donc plus souvent l'état du lecteur.
Ainsi au lieu d'avoir

  1. affichage + tempo
  2. affichage + tempo
  3. affichage + tempo
  4. affichage + tempo
  5. teste l'état du lecteur de badge
  6. retour au ①

Tu aurais

  1. affichage + tempo
  2. teste l'état du lecteur de badge
  3. retour au ①

De plus, la succession affichage + tempo fait papilloter l'écran.
Tu affiches le texte, il est visible 700ms, tu l'effaces, tu le ré-affiches aussitôt,.....
Ce qui a un effet visuel désagréable.
Il serait préférable de faire:

  • afficher le texte " Scannez votre" sur la première ligne
  • afficher sur la deuxième ligne en alternance
    • soit " badge"
    • soit "badge"

C'est visuellement beaucoup plus acceptable
Comme proposé par @pandaroux007 , dans loop il suffit de gérer une variable qui va compter le nombre d'échec et agir en conséquence.

L'utilisation de millis() comme proposé aussi par @pandaroux007 permet de tester le lecteur de badge en permanence et de ne modifier l'affichage que lorsque c'est nécessaire.

Ce n'est pas plus compliqué que ce que tu as déjà écrit.

Bien sur que non !
Du moment que l'on y passe du temps, qu'on s'accroche et qu'on essaye de comprendre, on finit presque toujours à voir le bout.
Bon, as-tu compris ce que je t'ai proposé ? Je vais t'expliquer des bouts de code pour que tu puisse continuer.

Merci. J'ai agit en conséquence et effectivement, c'est visuellement bien plus acceptable
Merci beaucoup

Je ne comprend pas trop. Je ne connais pas les variables.

Il faut voir ça comme des tiroirs dans lesquels on range des informations.
Des variables tu en utilises dans ton code

int refus = 0; // quand cette variable n'est pas nulle, c'est que le code est refusé
for (byte i = 0; // <== i c'est une variable

Il faut un minimum de bases pour être à l'aise en programmation.
Pour commencer, il y a le blog d'Eskimon
https://eskimon.fr/

Sinon (les variables c'est la base d'un code ou presque !), mon tuto (peut-être un peu long, désolé):

Et le blog d'@Eskimon - c'est une vraie pépite !

Merci beaucoup

Bonjour @Elo22 :wave:
Alors, as-tu réussi à faire ton programme ?

Bonne journée
Cordialement
Pandaroux007

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.