Salut à tous!
Voila je débute en programation arduino mais je me debrouille pour réussir ce que je veux en général mais la je sèche...
Le concept de mon projet est le suivant
J'ai un capteur RFID RC522 sur un arduino NANO.
Lorsque je pose le bon tag sur le capteur l'arduino allume via un système transistor un petit Ruban led (ça c'est ok pour moi), lorsque je retire le tag le ruban led s'éteind. Lorsque je met un mauvais tag il ne se passe rien.
Mon problème est le suivant lorsque je met le bon tag le ruban s'allume mais lorsque je le retire le ruban ne s'éteind pas... j'ai essayer plusieurs choses mais rien n'y fait... le mieux que j'ai obtenue c'est que le ruban s'éteind bien quand on retire le tag mais lorsque qu'il est allumé il clignotte.
Voici le code (un peu bordélique) ce code allume le ruban mais ne l'éteind pas.
Il y aurait t'il une solution pour que le ruban led reste allumé tant que le tag est présent devant le scanner et qu'il s'éteingne lorsque l'on retire le tag comme par exemple :
-Lecture RFID : TAG ok
-Allumage LED
-Mémorisation TAG ok
-Nouvelle lecture RFID
-Si TAG ok ne rien faire
-Si TAG absent ou différent
-LED OFF
J'epère etre assez clair dans mon explication
Merci d'avance
/*******************************************************************************
RFID LEDs
Exemple d'utilisation de la bibliothèque MFRC522 par Miguel Balboa
Lorsque le tag RFID est accepté, une LED verte s'allume pendant 3 secondes
Lorsque le tag RFID est refusé, une LED rougeo s'allume pendant 3 secondes
Pour plus de détails:
https://electroniqueamateur.blogspot.com/2017/04/module-rfid-rc522-et-arduino.html
***********************************************************************************/
#include <SPI.h>
#include <MFRC522.h>
// copier ici le résultat du sketch "lectureUID.ino":
const byte bonUID[4] = {196, 179, 128, 20};
const int pinLEDStrip = 7; // LED verte
const int pinRST = 9; // pin RST du module RC522
const int pinSDA = 10; // pin SDA du module RC522
bool (tag) = false;
MFRC522 rfid(pinSDA, pinRST);
void setup()
{
SPI.begin();
rfid.PCD_Init();
pinMode(pinLEDStrip, OUTPUT);
}
void loop()
{
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
{
tag = true;}
else{
tag = false;
}
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é
{
if (tag)
{
// on allume la LED verte pendant trois secondes
digitalWrite(pinLEDStrip, HIGH);
}
}
}
}
J'ai regardé comment mieux tourner ton programme, car tel quel c'était difficile.
J'ai déplacé le test de l'UID dans une fonction boolean cardCheck(byte bonUID[]) qui fait le nécessaire pour dire si l'UID est OK ou pas.
Ainsi, dès que l'UID est OK, la LED s'allume au moins 3 secondes, ensuite le programme attend que la carte soit retirée pour éteindre le LED.
/*******************************************************************************
RFID LEDs
Exemple d'utilisation de la bibliothèque MFRC522 par Miguel Balboa
Lorsque le tag RFID est accepté, une LED verte s'allume pendant 3 secondes
Lorsque le tag RFID est refusé, une LED rougeo s'allume pendant 3 secondes
Pour plus de détails:
https://electroniqueamateur.blogspot.com/2017/04/module-rfid-rc522-et-arduino.html
***********************************************************************************/
#include <SPI.h>
#include <MFRC522.h>
// copier ici le résultat du sketch "lectureUID.ino":
const byte bonUID[4] = {196, 179, 128, 20};
const int pinLEDStrip = 7; // LED verte
const int pinRST = 9; // pin RST du module RC522
const int pinSDA = 10; // pin SDA du module RC522
bool (tag) = false;
MFRC522 rfid(pinSDA, pinRST);
void setup()
{
Serial.begin(115200);
SPI.begin();
rfid.PCD_Init();
pinMode(pinLEDStrip, OUTPUT);
}
void loop()
{
if (cardCheck(bonUID))
{
Serial.println("Card OK");
digitalWrite(pinLEDStrip, HIGH); // on allume la LED verte pendant trois secondes
delay(3000);
while(cardCheck(bonUID)) {} // tant que cette carte n'est pas retirée
digitalWrite(pinLEDStrip, LOW); // on éteind la LED une fois que la carteest retirée
}
}
boolean cardCheck(byte bonUID[])
{
boolean check = false;
rfid.PCD_Init();
if(rfid.PICC_IsNewCardPresent())
{
if (rfid.PICC_ReadCardSerial()) // on a lu avec succès son contenu
{
check = true;
for (byte i = 0; i < rfid.uid.size; i++) // comparaison avec le bon UID
{
if (rfid.uid.uidByte[i] != bonUID[i])
{
check = false;
}
}
}
}
return check;
}
Oui!
Tu devrais savoir, que je teste toujours les programmes que je mets en ligne, si ce n'est pas le cas, je le signale.
En lisant ce programme tu verra un rfid.PCD_Init();.
certes ! (mais la question était sans sous entendu)
j'avais raté le rfid.PCD_Init(); qui remet tout à zéro effectivement
PS:
pour chipoter si on retire la carte 2 secondes et qu'on la remet le programme ne s'en rend pas compte alors (pas votre faute, c'est la spécification qui n'est pas précise )
on pourrait régler cela avec votre code en ne faisant aucun délai ou ça revient à faire une loop toute simple qui allume la LED tant que la carte est détectée
void loop() {
digitalWrite(pinLEDStrip, cardCheck(bonUID) ? HIGH : LOW);
}
et pour chipoter un peu plus, si je présente une carte qui a un UID de 10 octets, on accède au tableau bonUID au delà de ses bornes.
On pourrait corriger comme cela:
boolean cardCheck(byte bonUID[]) {
rfid.PCD_Init();
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) // on a lu avec succès son contenu
return (memcmp(rfid.uid.uidByte, bonUID, 4) == 0);
return false;
}
Pour moi, c'est utile à "l'ergonomie" du programme
Oui et non, j'aime beaucoup cette possibilité de test, je la trouve élégante et je l'utilise assez souvent, mais je doute de sa pertinence, dans ce cas.
En effet, un programme de lecteur de cartes RFID ne se cantonne que rarement voire pas du tout au simple allumage d'une LED. Or cette fonction avec ? ne permet qu'une action, alors allumer une LED + une temporisation + attendre le retrait de la carte + éventuellement faire tirer un relais oblige à avoir un if() traditionnel.
Tes "chipotages" démontrent qu'il y a autant de façon de programmer qu'il y a de programmeurs
Tout à fait ! Et que le cahier des charges est important - soit on colle au sujet, soit on prévoit des extensions futures probables ou on traite les cas non attendus (carte avec plus de 4 octets pour l’ID - et encore ici il faudrait faire plus et vérifier que la longueur de lID est 4 pas uniquement que les 4 premiers sont identiques)
De même une attente active n’est pas toujours souhaitable - une approche par état pourrait être nécessaire si le programme doit faire différentes tâches tant que la carte est posée
L’important reste de donner des idées de code à ceux qui viennent poser des questions, et toutes les idées pertinentes sont bonnes à prendre !
Désolé pour la réponse tardive je n'avais pas accès à mon ordinateur jusqu’à aujourd’hui
Déjà merci pour vos réponses je vais regarder et tester tout ça ! (je reviens vers vous pour vous dire si cela fonctionne chez moi et si j'ai tout compris ou pas
Pour le moment le programme ne doit effectivement faire que ça et n’évolueras pas sur ce projet mais peu être que dans un futur plus ou moins proche cela arriveras pour un autre projet je vais regarder tout ça!
donc la version du sketch proposée par @jpbbricole doit être tout à fait fonctionnelle ou la version un peu plus "compacte" (que je n'ai absolument pas testée au contraire de jpbricole)
const byte pinLEDStrip = 7; // pin LED verte
const byte pinRST = 9; // pin RST du module RC522
const byte pinSDA = 10; // pin SDA du module RC522
const byte bonUID[] = {196, 179, 128, 20}; // copier ici le résultat du sketch "lectureUID.ino":
#include <MFRC522.h>
MFRC522 rfid(pinSDA, pinRST);
void setup() {
SPI.begin();
rfid.PCD_Init();
pinMode(pinLEDStrip, OUTPUT);
}
void loop() {
digitalWrite(pinLEDStrip, cardCheck() ? HIGH : LOW);
delay(100); // on vérifie ~10 fois par seconde
}
boolean cardCheck() {
rfid.PCD_Init();
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) // on a lu avec succès son contenu
return (memcmp(rfid.uid.uidByte, bonUID, sizeof bonUID) == 0);
return false;
}