Monnayeur RFID avec décompte des crédits sur 7 segments

Bonjour à tous, 8)

Je travaille sur un projet de monnayeur RFID avec décompte individuel des crédits en fonction de plusieurs badges (chaque badge possède sont propre crédit).

J'ai pas mal avancé sur le code, mais il y a plusieurs choses qui me bloque...

Exemple : Je n'arrive pas a afficher les crédits du badge X et à les décrémenter de 1 si j'appui sur un bouton

Pouvez vous jeter un œil à mon code :slight_smile: (une photo de mon montage en PJ pour vous aider à y voir plus clair)

PS : ce qui fonctionne:
-Reconnaissance des différents badges enregistrés
-son buzzer
-affichage led différentes couleurs

#include <SPI.h>
#include <MFRC522.h>                //Library RFID
#include <Wire.h>                   //Library Horloge
#include <DS3231.h>                 

//Définition des Sorties 
#define SS_PIN 10            //pin RFID
#define RST_PIN 9            //""
#define RELAY 8              //pin relais
#define BUZZER 6             //pin buzzer
#define BOUTON 2             //pin bouton play
#define ACCESS_DELAY 5000    //Durée de pause Badge OK
#define DENIED_DELAY 1000    //Durée de pause Badge non-valide
#define ACCESS_MASTER 5000   //Durée de pause Carte Master
int LED_B = A1;               // LED Bleu
int LED_V = A2;               // LED Verte
int LED_R = A3;               // LED Rouge

//N° Sorties et variable du 7_segments
const int dataPin = 5;       // Fil bleu 74HC595 pin 14
const int latchPin = 4;      // Fil vert 74HC595 pin 12
const int clockPin = 3;      // Fil jaune 74HC595 pin 11
const char commune = 'c';    // "c" cathode commune (sinon "a" pour anode commune)

//DEFINITION DES VARIABLES 
DS3231 clock;                             // Déclarer instance Horloge 
RTCDateTime dt;

MFRC522 rfid(SS_PIN, RST_PIN);            // Déclarer instance MFRC522 RFID
MFRC522::MIFARE_Key key;
byte tagok = 0;                           // Variable pour différencier Badge de la carte Master

int etat_bouton;                          // Variable pour différencier état haut ou état bas du bouton
int credit = 5;                           // Nombre de crédit Max
int mem_btn_play = HIGH;                 // etat du bouton moins

//Affichage des chiffres sur le 7_Segments           74HC595 pin       Q0 - Q1 - Q2 - Q3 - Q4 - Q5 - Q6 - Q7 
// 1 = LED on, 0 = LED off, dans cet ordre:           Mappage vers      a    b    c    d    e    f    g   ..
byte chiffre[10] = { 
                    B11111100,  // 0
                    B01100000,  // 1
                    B11011010,  // 2
                    B11110010,  // 3
                    B01100110,  // 4
                    B10110110,  // 5
                    B10111110,  // 6
                    B11100000,  // 7
                    B11111110,  // 8
                    B11100110   // 9
                    };

// Code des Badges
unsigned long sernum[13] = {0,            //poste 0 N° badge lue
                            1669386246,   //Badge 1
                            3009123561,   //Badge 2
                            3009327833,   //Badge 3
                            0,            //Badge 4
                            0,            //Badge 5
                            0,            //Badge 6
                            0,            //Badge 7
                            0,            //Badge 8
                            0,            //Badge 9
                            0,            //Badge 10
                            0,            //Badge 11
                            2778220336};  //Carte Master(12)

//INITIALISATION DE LA CARTE ET DES SORTIES
void setup() 
{
  Serial.begin(9600);       // Initialiser communication avec le serial
  SPI.begin();              // Initialiser le bus SPI
  rfid.PCD_Init();          // Initialiser carte rfid
  clock.begin();            // Initialiser Horloge
  clock.setDateTime(__DATE__, __TIME__);
  
  pinMode(LED_V, OUTPUT);   // Indiquer LED et Buzzer comme sortie
  pinMode(LED_R, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  noTone(BUZZER);
  pinMode(BOUTON, INPUT_PULLUP);
  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, LOW);

  pinMode(dataPin, OUTPUT);  // Indiquer pin du 7_segments comme sortie d'infos
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  Serial.println("Présentez votre badge sur le lecteur ...");
  Serial.println();
}  

  //Permet d'afficher un nombre sur le segment numérique
void sevenSegWrite(byte credit) {
  digitalWrite(latchPin, LOW); 
  shiftOut(dataPin, clockPin, LSBFIRST, chiffre[credit]); 
  digitalWrite(latchPin, HIGH);
}
 
//PROGRAMME 
void loop() {
  
  // Initialisé la boucle si aucun badge n'est présent 
  if ( ! rfid.PICC_IsNewCardPresent()) {
    return; }
  // Vérifier la présence d'un nouveau badge 
  if ( ! rfid.PICC_ReadCardSerial()) {
    return; }
    
  //Affiche date et heure lors du badge sur le moniteur série
  dt = clock.getDateTime();
  //Exemple --> Date : 2-5-2020 16:15:31
  Serial.print("Date : ");
  Serial.print(dt.day);    Serial.print("/");
  Serial.print(dt.month);  Serial.print("/");
  Serial.print(dt.year);   Serial.print(" ");
  Serial.print(dt.hour);   Serial.print("H ");
  Serial.print(dt.minute); Serial.print("min ");
  Serial.print(dt.second); Serial.println("Sec");
  
  //Afficher l'UID sur le moniteur série
  Serial.print("UID Badge :");
  String content= "";
  byte letter;
  for (byte i = 0; i < rfid.uid.size; i++) 
  {
     Serial.print(rfid.uid.uidByte[i] < 0x12 ? " 0" : " ");
     Serial.print(rfid.uid.uidByte[i], HEX);
     content.concat(String(rfid.uid.uidByte[i] < 0x12 ? " 0" : " "));
     content.concat(String(rfid.uid.uidByte[i], HEX));
  }

  //recup num serie lu dans la library des codes badge
  sernum[0] = *((unsigned long *)rfid.uid.uidByte); 

  Serial.print(" ");
  Serial.print(sernum[0]);
  Serial.print(" ");
  Serial.print(sernum[0], HEX);
  Serial.print(" ");
  tagok = 0;
  for  (byte i = 1; i < 12; i++) {
    if (sernum[0] == sernum[i]) tagok = 1; // badge reconnue dans la liste
  }
  if (sernum[0] == sernum[12]) tagok = 255; // carte master reconnue
  
  // faire si carte inconnue
  if (tagok == 0) { 
    Serial.print("Bagge INCONNU");
    Serial.println();
    digitalWrite(LED_R, HIGH);       //Allume LED Rouge + Buzzer son d'erreur
    tone(BUZZER, 300);
    delay(DENIED_DELAY);
    digitalWrite(LED_R, LOW);
    noTone(BUZZER);
  }

  //faire si carte reconnue
  if (tagok >0) 
  {
    digitalWrite(LED_V, HIGH);
    tone(BUZZER,2093,150);                        //Allume LED VERTE + Buzzer son OK            
    digitalWrite(RELAY, HIGH);
    Serial.print("Badge OK");
    if (sernum[0] == sernum[1]) Serial.print(" - Badge 1 " );
    if (sernum[0] == sernum[2]) Serial.print(" - Badge 2 " );
    if (sernum[0] == sernum[3]) Serial.print(" - Badge 3 " );
    if (sernum[0] == sernum[4]) Serial.print(" - Badge 4 " );
    //etc...
    if (sernum[0] == sernum[12]) Serial.print(" - Carte MASTER " );

    //Appui Bouton play pour décrémenter le compteur de 1
    etat_bouton = digitalRead(BOUTON);
    if ((etat_bouton != mem_btn_play)&& (etat_bouton == LOW)){
    credit--;
    }  
    mem_btn_play = etat_bouton;
    sevenSegWrite(credit);
    if(credit < 0){          //ne descend pas en dessous de 0 et ne dépasse pas la valeur 9
    credit = 0;}
    if (credit > 9)
    credit = 9;
    }
    delay(ACCESS_DELAY);
    Serial.println();
    digitalWrite(LED_V, LOW);
    digitalWrite(RELAY, LOW);
    noTone(BUZZER);

  //faire si carte master reconnue
  if (tagok == 255) 
  {
    Serial.println("Carte Master Reconnu");
    tone(BUZZER,1200, 100);
    digitalWrite(LED_B, HIGH);                 //Allume LED VERTE puis BLEU + Double Buzzer son OK + ...
    delay(4000);
    digitalWrite(LED_B, LOW);
    noTone(BUZZER);
   }
}

Cette rubrique est réservée aux "Réalisations et Projets Finis".
STP utilise le lien "Report to moderator" pour demander au modo de déplacer ton message dans le forum principal.

Oups, désolé... Merci de m'avoir prévenu.

J'ai fait la demande de transfert du post :slight_smile:

Déplacé

La routine sevenSegWrite() a t-elle été testée avec un programme basique ?
La tension sur l'entrée bouton est-elle OK quand on appuies sur le bouton ?

le sevenSegWrite fonctionne, il affiche en permanence la variable crédit :sweat_smile: mais je voudrais qu'il affiche uniquement lorsqu'un badge est reconnu...

et pour le bouton, j'ai un doute... Quand on inscrit "INPUT_PULLUP" il n'y a pas besoin de résistance en plus et on branche seulement le pin d'entrée et le GND ??

Pour compter avec le RFID, j'avais trouver un bout de code qui fonctionne avec un LCD et qui distingue plusieurs badges (voir ci-dessous). Mais je n'arrive pas à l'adapter avec mon 7 segment...

#include <SPI.h>
#include <MFRC522.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
 
#define SS_PIN 53
#define RST_PIN 5
 
#define BEEP 6
#define BUTTON 7
 
MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
Adafruit_PCD8544 display = Adafruit_PCD8544(22, 23, 24, 25, 26);
 
bool resetMode = false;
 
void setup() {
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522
 
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF; // Key used is FF FF FF FF FF FF
  }
 
  // Init LCD
  display.begin();
  display.setContrast(50);
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setRotation(2); // using it upside down
  display.setCursor(0, 0);
  display.clearDisplay();
  display.display();
 
  pinMode(BEEP, OUTPUT);
  pinMode(BUTTON, INPUT);
  display.println("Press the bu-tton to reset the counter ");
  display.display();
}
 
void loop() {
 
  if ( digitalRead(BUTTON) == 1) {
    //reset mode
    display.clearDisplay();
    display.println("Swipe the ca-rd to reset  the counter ");
    display.display();
    resetMode = true;
    return;
  }
 
  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;
 
  // Verify if the UID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;
 
  // Check for compatibility
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
          &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
          &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("This only works with MIFARE Classic cards."));
    return;
  }
 
  // Use sector #1 (Block #4 - #7) to store data, to be specific Block #4
  byte sector = 1;
  byte blockAddr = 4;
  byte trailerBlock = 7;
 
  // Initialize data to write
  byte dataBlock[16];
  for (int i = 0; i < 16; i++)
    dataBlock[i] = 0x00;
 
  // Initialize array to store the result
  byte buffer[18];
  byte size = sizeof(buffer);
 
  // Initialize variable for storing counter
  byte count = 0;
 
  MFRC522::StatusCode status;
 
  // Using key A
  Serial.println(F("Authenticating using key A..."));
  status = (MFRC522::StatusCode) rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(rfid.uid));
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("PCD_Authenticate() failed: "));
    Serial.println(rfid.GetStatusCodeName(status));
    return;
  }
 
  if (resetMode) {
    // Reset mode
    status = (MFRC522::StatusCode) rfid.MIFARE_Write(blockAddr, dataBlock, 16);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Write() failed: "));
      Serial.println(rfid.GetStatusCodeName(status));
    }
  } else {
    // Counter mode
 
    //Read the number first
    status = (MFRC522::StatusCode) rfid.MIFARE_Read(blockAddr, buffer, &size);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Read() failed: "));
      Serial.println(rfid.GetStatusCodeName(status));
    }
    count = buffer[15];
 
    //INC
    count++;
 
    //Write the number back
    dataBlock[15] = count;
    status = (MFRC522::StatusCode) rfid.MIFARE_Write(blockAddr, dataBlock, 16);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Write() failed: "));
      Serial.println(rfid.GetStatusCodeName(status));
    }
  }
 
  //Read the number again
  status = (MFRC522::StatusCode) rfid.MIFARE_Read(blockAddr, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Read() failed: "));
    Serial.println(rfid.GetStatusCodeName(status));
  }
  count = buffer[15];
 
  //Turn on the buzzer
  digitalWrite(BEEP, HIGH);
 
  // Print the data to serial
  SerialPrintHex(rfid.uid.uidByte, rfid.uid.size);
  Serial.print(" ");
  Serial.println(count);
 
  // Print the data to LCD
  display.clearDisplay();
  display.println("Press the bu-tton to reset the counter ");
  display.print("UID: ");
  lcdPrintHex(rfid.uid.uidByte, rfid.uid.size);
  display.println();
  display.print("Counter: ");
  display.println(count);
  display.display();
 
  //Turn off the buzzer
  digitalWrite(BEEP, LOW);
 
  //Beep twice if is in reset mode
  if (resetMode) {
    delay(50);
    digitalWrite(BEEP, HIGH);
    delay(100);
    digitalWrite(BEEP, LOW);
    resetMode = false;
  }
  // Halt PICC
  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
}
 
// Function for print byte array in hex
void SerialPrintHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? "0" : "");
    Serial.print(buffer[i], HEX);
  }
}
 
void lcdPrintHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    display.print(buffer[i] < 0x10 ? "0" : "");
    display.print(buffer[i], HEX);
    display.display();
  }
}

up Merci d'avance pour votre aide :slight_smile:

voici le code que vous avez posté ci dessus débarrassé de tout ce qui touche au LCD. maintenant ça n'imprime plus que dans le terminal Série.

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 53
#define RST_PIN 5
MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
bool resetMode = false;


const byte buzzerPin = 6;
const byte buttonPin = 7;

void setup() {
  Serial.begin(115200);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522
  delay(4);       // Optional delay. Some board do need more time after init to be ready, see Readme

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF; // Key used is FF FF FF FF FF FF
  }

  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  Serial.println("Press the button to reset the counter ");
}

void loop() {

  if ( digitalRead(buttonPin) == HIGH) {
    //reset mode
    Serial.println("Swipe the card to reset the counter ");
    resetMode = true;
    return;
  }

  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the UID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  // Check for compatibility
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
          &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
          &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("This only works with MIFARE Classic cards."));
    return;
  }

  byte blockAddr = 4;
  byte trailerBlock = 7;

  // Initialize data to write
  byte dataBlock[16];
  for (int i = 0; i < 16; i++)
    dataBlock[i] = 0x00;

  // Initialize array to store the result
  byte buffer[18];
  byte size = sizeof(buffer);

  // Initialize variable for storing counter
  byte count = 0;

  MFRC522::StatusCode status;

  // Using key A
  Serial.println(F("Authenticating using key A..."));
  status = (MFRC522::StatusCode) rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(rfid.uid));
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("PCD_Authenticate() failed: "));
    Serial.println(rfid.GetStatusCodeName(status));
    return;
  }

  if (resetMode) {
    // Reset mode
    status = (MFRC522::StatusCode) rfid.MIFARE_Write(blockAddr, dataBlock, 16);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Write() failed: "));
      Serial.println(rfid.GetStatusCodeName(status));
    }
  } else {
    // Counter mode

    //Read the number first
    status = (MFRC522::StatusCode) rfid.MIFARE_Read(blockAddr, buffer, &size);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Read() failed: "));
      Serial.println(rfid.GetStatusCodeName(status));
    }
    count = buffer[15];

    //INC
    count++;

    //Write the number back
    dataBlock[15] = count;
    status = (MFRC522::StatusCode) rfid.MIFARE_Write(blockAddr, dataBlock, 16);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Write() failed: "));
      Serial.println(rfid.GetStatusCodeName(status));
    }
  }

  //Read the number again
  status = (MFRC522::StatusCode) rfid.MIFARE_Read(blockAddr, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Read() failed: "));
    Serial.println(rfid.GetStatusCodeName(status));
  }
  count = buffer[15];

  //Turn on the buzzer
  digitalWrite(buzzerPin, HIGH);

  // Print the data to serial
  Serial.println("Press the button to reset the counter ");
  Serial.print("UID: ");
  SerialPrintHex(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  Serial.print("Counter: ");
  Serial.println(count);

  //Turn off the buzzer
  digitalWrite(buzzerPin, LOW);

  //Beep twice if is in reset mode
  if (resetMode) {
    delay(50);
    digitalWrite(buzzerPin, HIGH);
    delay(100);
    digitalWrite(buzzerPin, LOW);
    resetMode = false;
  }
  // Halt PICC
  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
}

// Function for print byte array in hex
void SerialPrintHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? "0" : "");
    Serial.print(buffer[i], HEX);
  }
}

si ça correspond à ce que vous voulez, trouvez là où l'info pertinente est affichée sur le moniteur série et ajoutez votre code pour votre afficheur