RFID (NFC) DOMINATOR


  • During several hour events in extreme games such as Airsoft / Paintball / Nerf, different modes are played, such as King of The Hill, for which this project is designed (classic DOMINATOR). Each team earns points for the duration of the placement, or for the time it is held. I used Arduino, RFID reader, LCD display, detector and relay / separate ledgers.
  • Two independent times for two teams that work after adding one of the team cards just to start the team time. In practice, each member of the RFID team has a keypad that can be attached to the reader and activate the time.
  • Maximum time range:
  • 999 hours, 59 minutes and 59 seconds
  • The time is added to the moment until he / she is stopped by the second team by attaching his / her card or the organizer / arbitrator who can pause or the special key / card to reset.
  • The detector signals the card attachment to the reader and the LEDs / relays indicate the current status of the stopwatch signals the color of the team to which the time is added.
  • The project is designed for (almost) an unlimited number of keys, so all teams, event organizers, result deletion cards can be called. Also suitable for clubs that play similar events regularly or for service providers in the industry.
  • Keychains are usually color-differentiated for that team. Relays are used when stronger lights / diodes are used to indicate the active team to which the time is added.
  • The time is displayed on the 16x2 or 20x4 character display.
  • Just add the key to the reader, the time will begin to count and the other team will stop. The organizer stops both times and starts adding up after adding one of the player"s keys to a team. Eraser will delete both times immediately after the card is inserted (before the new game).
  • The solution is universal, once the key codes are added to the code and it works permanently. I will also add to the project the circuit diagram, the necessary libraries and the Arduino sketch in .ino format.
  • Hardware for the project:
  • Arduino Uno Arduino Uno
  • RFID reader RC522 (13.56MHz) RFID reader (NFC)
  • Keychains / card / combination Kľúčenky na 13.56MHz
  • Detector (passive buzzer) Buzzer
  • 2-channel relays, diodes Relé

  • The result


    Relé

    Get addresses:

    #include <SPI.h>
    #include <MFRC522.h>
    #define RST_PIN         9
    #define SS_1_PIN        10
    #define NR_OF_READERS   1
    byte ssPins[] = {SS_1_PIN};
    MFRC522 mfrc522[NR_OF_READERS];
    void setup() {
      Serial.begin(9600);
      while (!Serial);
      SPI.begin();
      for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
        mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN);
        Serial.print(F("Reader "));
        Serial.print(reader);
        Serial.print(F(": "));
        mfrc522[reader].PCD_DumpVersionToSerial();
      }
    }
    
    void loop() {
      for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
        if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
          Serial.print(F("Reader "));
          Serial.print(reader);
          Serial.print(F(": Card UID:"));
          dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
          Serial.println();
          Serial.print(F("PICC type: "));
          MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
          Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));
          mfrc522[reader].PICC_HaltA();
          mfrc522[reader].PCD_StopCrypto1();
        }
      }
    }
    
    void dump_byte_array(byte *buffer, byte bufferSize) {
      for (byte i = 0; i < bufferSize; i++) {
      }
      Serial.print("Kod:");
      unsigned long kod = 10000 * buffer[4] + 1000 * buffer[3] + 100 * buffer[2] + 10 * buffer[1] + buffer[0]; //finalny kod karty
      Serial.print(kod);
    }
            

    Put addresses + DOMINATOR logic:

    #include <LiquidCrystal_I2C.h>
    #include <SPI.h>
    #include <MFRC522.h>
    
    #define RST_PIN         9          // Configurable, see typical pin layout above
    #define SS_1_PIN        10         // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 2
    #define SS_2_PIN        8          // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 1
    
    #define NR_OF_READERS   1
    
    byte ssPins[] = {SS_1_PIN, SS_2_PIN};
    
    MFRC522 mfrc522[NR_OF_READERS];   // Create MFRC522 instance.
    
    #define I2C_ADDR    0x3F  // Define I2C Address where the PCF8574A is
                              // Address can be changed by soldering A0, A1, or A2
                              // Default is 0x27
    
    // map the pin configuration of LCD backpack for the LiquidCristal class
    #define BACKLIGHT_PIN 3
    #define En_pin  2
    #define Rw_pin  1
    #define Rs_pin  0
    #define D4_pin  4
    #define D5_pin  5
    #define D6_pin  6
    #define D7_pin  7
    
    LiquidCrystal_I2C lcd(I2C_ADDR,
                          En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,
                          BACKLIGHT_PIN, POSITIVE);
    unsigned long kod;
    boolean run = false;
    boolean run2 = false;
    long timer = 0; //The timer
    int second = 0;
    int minute = 0;
    int tenth = 0;
    int hour =0;
    int second2 = 0;
    int minute2 = 0;
    int tenth2 = 0;
    int hour2 =0;
    const int rfrele = 3;
    const int gdprele = 4;
    const int buzzer = 5;
    void setup() {
      Serial.begin(9600);
      SPI.begin();
      pinMode(rfrele,OUTPUT);
      pinMode(gdprele,OUTPUT);
      pinMode(buzzer,OUTPUT);
        for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
        mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN); // Init each MFRC522 card
        Serial.print(F("Reader "));
        Serial.print(reader);
        Serial.print(F(": "));
        mfrc522[reader].PCD_DumpVersionToSerial();
      }
      lcd.begin(20, 4);                // intialise the LCD.
         lcd.setBacklight(HIGH); // Turn on backlight, LOW for off
      lcd.setCursor(0,0);
      lcd.print("  RP2018 DOMINATOR");
      lcd.setCursor(0,1);
       lcd.print("--------------------");
      lcd.setCursor(0,2);
      lcd.print("RF  00:00:00");
       lcd.setCursor(0,3);
       lcd.print("GDP 00:00:00");
    }
    
    void tickClock() {
      if((timer - millis()/100) >= 100 || timer == 0) {
        tick();
        tick2();
        timer = millis()/100;
      }
      
    }
    
    void loop() {
       for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
        if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
          Serial.print(F("Reader "));
          Serial.print(reader);
          // Show some details of the PICC (that is: the tag/card)
          Serial.print(F(": Card UID:"));
          dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
          Serial.println();
          Serial.print(F("PICC type: "));
          MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
          Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));
    
          // Halt PICC
          mfrc522[reader].PICC_HaltA();
          // Stop encryption on PCD
          mfrc522[reader].PCD_StopCrypto1();
        } //if (mfrc522[reader].PICC_IsNewC
      } //for(uint8_t reader
      if(kod==4294946665 || kod==23101 || kod==8151 || kod==4294951443 || kod==4294953039 || kod==24519 || kod==4294945657 || kod==3801 || kod==4294945187){
         
           digitalWrite(rfrele, LOW);
                 digitalWrite(gdprele, HIGH);
          run = false;
          run2 = true;
            }else if(kod==4294956915 || kod==4294958051 || kod==4294961082 || kod==4294960491 || kod==4294958039 || kod==4294958091 || kod==4294946987 || kod==4294961057 || kod==4294959927){
            
               digitalWrite(rfrele, HIGH);
                 digitalWrite(gdprele, LOW);
              run = true;
          run2 = false;
              }else if(kod==12619){
                
                 digitalWrite(rfrele, LOW);
                 digitalWrite(gdprele, LOW);
                run = false;
          run2 = false; 
                }else if(kod==4294962506){
               
                 digitalWrite(rfrele, LOW);
                 digitalWrite(gdprele, LOW);
           second = 0;
     minute = 0;
     tenth = 0;
     hour =0;
     second2 = 0;
     minute2 = 0;
     tenth2 = 0;
     hour2 =0;
     updateLCD();
     updateLCD2();
      run = false;
          run2 = false; 
                  }
      tickClock(); //Start ticking the clock
    }
    
    void tick() {
      if(run) {
        updateLCD();
        
        
        
        if(tenth == 9) {
          tenth = 0;
          
          if(second == 59) {
            second = 0;
            minute++;
            
          }else {
            second++;
          }
          
          if(minute == 60) {
            minute = 0;
            hour++;
            
          } 
        } else {
        tenth++;
        }
      }
    }
    void tick2() {
      if(run2) {
        updateLCD2();
        
        
        
        if(tenth2 == 9) {
          tenth2 = 0;
          
          if(second2 == 59) {
            second2 = 0;
            minute2++;
            
          }else {
            second2++;
          }
          
          if(minute2 == 60) {
            minute2 = 0;
            hour2++;
            
          } 
        } else {
        tenth2++;
        }
      }
    }
    void updateLCD() {
       lcd.setCursor(4,2);
     if(hour < 10) {      // If hour does not have 2 digits
        lcd.print("0");
      }
       lcd.print(hour, DEC);
      lcd.print(":");
      if(minute < 10) {      // If hour does not have 2 digits
        lcd.print("0");
      }
      lcd.print(minute, DEC);
      lcd.print(":");
    
      if(second < 10) {    // If minute does not have 2 digits
        lcd.print("0");
      }
      lcd.print(second, DEC);
      //
      
    }
    void updateLCD2() {
      lcd.setCursor(4,3);
      if(hour2 < 10) {      // If hour does not have 2 digits
        lcd.print("0");
      }
       lcd.print(hour2, DEC);
      lcd.print(":");
      if(minute2 < 10) {      // If hour does not have 2 digits
        lcd.print("0");
      }
      lcd.print(minute2, DEC);
      lcd.print(":");
    
      if(second2 < 10) {    // If minute does not have 2 digits
        lcd.print("0");
      }
      lcd.print(second2, DEC);
      
    }
    
    void dump_byte_array(byte *buffer, byte bufferSize) {
      for (byte i = 0; i < bufferSize; i++) {
    
      }
      kod = 10000*buffer[4]+1000*buffer[3]+100*buffer[2]+10*buffer[1]+buffer[0];  
        tone(buzzer, 4000, 100);
      Serial.println("Zaznamenany kod karty: ");
      Serial.println(kod);
    }
    
    

    Libs

  • RFID - https://github.com/miguelbalboa/rfid
  • I2C pre LCD - https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
  • Wiring:

    Arduino --> I2C LCD:
  • A4 --> SDA
  • A5 --> SCK/SCL
  • 5V --> Vcc
  • GND --> GND
  • Arduino --> RFID RC522:
  • 3.3V --> 3.3V
  • GND --> GND
  • D9 --> RST
  • D10 --> CS
  • D11 --> MOSI
  • D12 --> MISO
  • D13 --> SCK
  • Arduino --> buzzer:
  • 5V --> 5V
  • D5 --> INPUT
  • GND --> GND
  • Arduino --> LED + relay:
  • 5V --> 5V relay
  • GND --> GND
  • D3--> LED + relay IN1
  • D4 --> LED + relay IN2
  • Case:

    RFID DOMINATOR CASE Thing Inverse