RFID DOMINATOR: De ultieme dominantiestopwatch voor airsoft, paintball
Over RFID DOMINATOR – Airsoft Stopwatch
RFID DOMINATOR is een stopwatch die is gemaakt voor Airsoft, Paintball, die de spelervaring verbetert en eerlijkheid brengt. Ze zijn geschikt voor de DOMINATOR, Capture the Point-spelmodus. DOMINATOR creëert een punt dat wordt bezet door een teamspeler. Het apparaat bevat een LCD-karakterdisplay dat informeert over de huidige tijd van elk team. Tegelijkertijd signaleert een LED-diode het actieve team op het punt. De speler bezet het DOMINATOR-punt door een RFID-armband of -kaart te bevestigen. Wanneer het punt bezet is, piept een alarm, dat een verandering op het punt aankondigt. De tijd van het team wordt geteld totdat een speler van een ander team zijn RFID-tag bevestigt, of totdat de tijd door de scheidsrechter wordt gestopt. De tijd blijft tellen nadat het punt is bezet. DOMINATOR telt de totale tijd die alle teams in de wedstrijd in beslag nemen. Kan worden gebruikt voor 2 of 4 teams in één wedstrijd. Naast het stoppen van de klok, kan de scheidsrechter deze ook resetten voor een nieuwe wedstrijd.
Gebruiksscenario's
Ideaal voor speeltuinen, velden die Airsoft/Paintball-ervaring bieden. Gebeurtenissen zoals LARP, MilSim, Scenario, Speedball, dankzij de flash-grootte die honderden RFID-tags in één enkele applicatie ondersteunt
Ondersteunde hardware
De volgende componenten zijn compatibel met RFID DOMINATOR 2.0 PCB
DEMO-firmware
RFID DOMINATOR biedt gratis te gebruiken DEMO-firmware waarmee u het apparaat en de basisfuncties kunt testen, als deze correct zijn aangesloten zoals op de schema's die beschikbaar zijn op de webpagina van RFID DOMINATOR
Modulair ontwerp, draagbare firmware
Modulair ontwerp van RFID DOMINATOR stelt de gebruiker in staat om hoofdcomponenten te vervangen zonder dat er gesoldeerd hoeft te worden. Met de hot-swap-methode kan hij de module verwijderen en binnen enkele seconden een nieuwe plaatsen. De gebruiker kan firmware kopiëren en klonen naar elk gewenst aantal apparaten. Betaal eenmalig voor de licentie en gebruik deze zo vaak als u nodig hebt voor uw apparaten.
Betaalbaar
Kloonbaar
Eenvoudig te gebruiken
Open-source HW-vriendelijk
RFID ingeschakeld
Modulair ontwerp
Weergave-uitvoer
Ondersteuning en feedback
Details
PCB
Specificaties RFID DOMINATOR 2.0 PCB
104 x 103 x 1,6 mm, dubbelzijdige FR4-type PCB. Zeefdruk op de PCB markeert de positie en oriëntatie van componenten, hoe deze gesoldeerd moeten worden.
Open-source hardware-ondersteuning
Hardware compatibel met open-source hardware
De hardware van RFID DOMINATOR is gerelateerd aan open-source hardwaregebruik. Het gebruikt Arduino-modules en het Arduino-bord zelf voor modulair ontwerp en de voordelen van open-source hardware (kosteneffectief, eenvoudig te vervangen).
Geassembleerde PCB
Uitzicht op de PCB, nadat deze is geassembleerd door compatibele componenten
Nadat de RFID DOMINATOR 2.0 PCB is gemonteerd, wordt de totale hoogte van de PCB uitgebreid tot 45 mm. Aan de voorkant bevindt zich het LCD2004A-scherm en de MFRC522-lezer, samen met LED-diodes en een zoemer. Aan de achterkant bevindt zich de Arduino Nano V3.0-controller. De belangrijkste componenten gebruiken pinheaders.
Behuizing
3D-geprinte behuizing voor RFID DOMINATOR 2.0
Behuizing compatibel met PCB van RFID DOMINATOR 2.0. Afmetingen van de behuizing zijn 124 x 123 x 47 mm. PCB zelf wordt van binnenuit gemonteerd, aan de voorkant van de behuizing met behulp van 4 stuks M3-schroeven. Het is mogelijk om een 25 mm (breedte) kabelbinder op de behuizing te gebruiken om deze op de boom of balk te monteren.
Bedradingsschema
Bedradingsschema voor RFID DOMINATOR 2.0
Bedradingsschema toont hoe Arduino Nano is bedraad met alle andere componenten. Voor LCD2004A is er een hardware-bekabelde I2C-bus en voor MFRC522 SPI-bus. Extra GPIO's worden gebruikt voor LED-diodenindicaties en voor zoemer met PWM-ondersteuning.
Knop DOMINATOR
Prototype van de mechanische knop DOMINATOR
De standaardprintplaat van de RFID DOMINATOR 2.0 kan ook worden gebruikt voor de knop DOMINATOR. De enige verandering is dat de RFID-lezer is verwijderd en er twee knoppen met een optionele diameter zijn geplaatst. Ook is het mogelijk om knoppen met led-achtergrondverlichting te gebruiken.
Galerij
Veelgestelde vragen
Hieronder staan de meest gestelde vragen van onze community.
Wat is het energieverbruik van het systeem?
Het systeem verbruikt doorgaans 40–60 mAh @ 5V, wat overeenkomt met 0,2–0,3 W. Een 2000 mAh-voedingsbron kan het systeem 30–35 uur laten werken, afhankelijk van de belasting.
Kan ik hem van stroom voorzien via een powerbank?
Ja, de RFID DOMINATOR kan rechtstreeks van stroom worden voorzien via een powerbank via de 5V-uitgang. RFID DOMINATOR vereist een MiniUSB-connector, er zijn ook enkele versies van Arduino Nano met een microUSB-connector.
Hoe kan ik de firmware uploaden?
Of het nu DEMO of FINALE firmware is, gebruik het meegeleverde .hex-bestand dat compatibel is met Arduino. Upload het met de XLoader-tool. Voor Arduino Nano met de oude bootloader, stel de snelheid in op 57600 baud/s, voor de nieuwe bootloader, gebruik 115200 baud/s. Succesvolle upload wordt bevestigd door een bericht van XLoader, het kan u informeren over het mislukte uploadproces.
Hoe kopieer ik bestaande firmware?
Upload gewoon hetzelfde firmwarebestand (.hex) dat u via e-mail hebt ontvangen naar uw volgende RFID DOMINATOR-eenheid. Het werkt op dezelfde manier en reageert op dezelfde RFID-polsbandjes en kaarten. Er is geen limiet aan het aantal klonen dat u kunt maken, het is aan u.
Kan een teamnaam worden gewijzigd?
Op dit moment nog niet, maar binnenkort wel, wanneer de AT-opdrachtenextensie is voltooid. Teamnamen moeten maximaal 3 letters bevatten (dit wordt beperkt door de software).
Kan DOMINATOR buiten worden gebruikt?
DOMINATOR heeft geen waterdichte behuizing. Als het droog is, kan het ook buiten worden gebruikt. Wordt voornamelijk binnenshuis of onder een afdak gebruikt.
In welke vorm is DOMINATOR beschikbaar?
RFID DOMINATOR is beschikbaar in de vorm van de minimale broncodeversie - verwijderde zoemer, exclusief gebruik van LCD 20x4 display, max. 1 RFID-kaart per entiteit. De knop DOMINATOR is beschikbaar als .hex-machinecode, die direct kan worden uitgevoerd op een ATmega328P MCU (Arduino Uno, Nano), zonder toegang tot de broncode. DPS-ontwerpbestanden, .STL-bestanden van de 3D-geprinte doos worden niet bij de software geleverd.
RFID DOMINATOR - broncode:
Minimale versie, 1 kaart per team, geen zoemer, alleen voor 20x4 LCD-scherm
Probeer RFID DOMINATOR in Wokwi Simulator! - Klik hier
//RFID DOMINATOR 2.0 - Domination Timer for Airsoft, USAGE UNDER MIT LICENSE!
//BLUE AND YELLOW TEAM, MINIMAL FUNCTIONALITY, ONE CARD / WRISTBAND PER TEAM
//BUZZER NOT INCLUDED, only 20x4 LCD screen supported
//Author: Martin Chlebovec (martinius96@gmail.com)
//Revision --> 20th February 2026
//Project info: https://your-iot.github.io/DOMINATOR/
//Installation instructions:
//Download library MFRC522 from: https://github.com/miguelbalboa/rfid/releases/tag/1.4.11 (Click on Source code (zip))
//Download library LiquidCrystal_I2C from: https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library (click on Code --> Download ZIP)
//Open .zip and copy whole directory into C:/Users/[actual user]/Documents/Arduino/libraries
//Now you can compile this source code
//For Arduino Nano with Old Bootloader, navigate to Tools --> Board --> Arduino Nano
//Tools --> Processor --> ATMega328P (Old Bootloader) - that will reduce upload speed to 57600 baud/s
//Standardly all Arduino Nano V3.0 has Old Bootloader (Blue clones)
//For standard bootloader nothing is required to set, only Arduino Nano under Tools --> Board (default)
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <Wire.h>
#include <MFRC522.h>
//Pinout compatible for Arduino Nano with MFRC522 (NXP RC522) on RFID DOMINATOR 2.0 PCB board
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN);
//Known RFID cards UIDs based on teams (You can see UID of your cards in Serial monitor when attached)
const unsigned long TEAM_BLU = 4321; //BLUE TEAM UID --> BLUE CARD
const unsigned long TEAM_YEL = 17933; //YELLOW TEAM UID --> YELLOW CARD
const unsigned long TEAM_REFEREE = 7921; //REFEREE GROUP UID --> GREEN CARD
const unsigned long TEAM_ERASER = 4294948592; //ERASER GROUP UID --> RED CARD
unsigned long code; //UID --> RFID CARD ADDRESS
boolean run = false; //is BLU team active on DOMINATION TIMER?
boolean run2 = false; //is YEL team active on DOMINATION TIMER?
unsigned long timer = 0; //timer 32-bit - GAME TIMER
unsigned long timer2 = 0; //timer 32-bit - RFID CHECK TIMER
boolean once = false; //was once-timed action created yet?
//TIME RELATED VARIABLES FOR TEAM RED
int second = 0; //seconds of team RED
int minute = 0; //minutes of team RED
int hour = 0; //hours of team RED
//TIME RELATED VARIABLES FOR TEAM GRE
int second2 = 0; //seconds of team GRE
int minute2 = 0; //minutes of team GRE
int hour2 = 0; //hours of team GRE
//OUTPUTS
const int BLU_LED = 6; //LED for team RED
const int RED_LED = 4; //LED for team GRE
const int ORA_LED = 7; //LED for team RED
const int GRE_LED = 3; //LED for team GRE
LiquidCrystal_I2C* lcd;
//user-defined functions declaration
void updateLCD();
void updateLCD2();
void tickClock();
void tick();
byte error, address;
void setup() {
Serial.begin(9600); //Start UART bus at 9600 baud/s
Serial.println(F("RFID Domination Timer 2.0 - freeware 9th February 2026"));
Serial.println(F("Creator: Martin Chlebovec (martinius96@gmail.com)"));
Serial.println(F("Project info: https://your-iot.github.io/DOMINATOR/"));
SPI.begin(); //Standard SPI speed for RC522 --> 4 MHz
Wire.begin(); //Standard I2C speed for LCD screen --> 100 kHz
for (address = 1; address < 127; address++ ) //this cycle will scan I2C bus and set LCD display automatically with any I2C address
{
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
break;
}
}
lcd = new LiquidCrystal_I2C(address, 20, 4); //display initialization
pinMode(BLU_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(ORA_LED, OUTPUT);
pinMode(GRE_LED, OUTPUT);
rfid.PCD_Init(); // Init MFRC522
rfid.PCD_SetAntennaGain(rfid.RxGain_max);
rfid.PCD_DumpVersionToSerial(); //Write version of Firmware to UART
lcd->begin(); //Not valid for Wokwi simulator, valid for LiquidCrystal_I2C library from @fdebrabander
lcd->backlight(); //backlight on
lcd->clear();
lcd->setCursor(0, 0);
lcd->print(F(" RFID DOMINATOR 2.0 "));
lcd->setCursor(0, 2);
lcd->print(F(" DEVELOPED BY: "));
lcd->setCursor(0, 3);
lcd->print(F(" Martin Chlebovec "));
for (int i = 0; i < 20; i++) {
// LED animation effect, loading
switch (i % 4) {
case 0:
digitalWrite(BLU_LED, HIGH);
delay(250);
digitalWrite(BLU_LED, LOW);
break;
case 1:
digitalWrite(GRE_LED, HIGH);
delay(250);
digitalWrite(GRE_LED, LOW);
break;
case 2:
digitalWrite(RED_LED, HIGH);
delay(250);
digitalWrite(RED_LED, LOW);
break;
case 3:
digitalWrite(ORA_LED, HIGH);
delay(250);
digitalWrite(ORA_LED, LOW);
break;
}
//print loading bar
lcd->setCursor(i, 1);
lcd->write(byte(255)); // plný znak
}
delay(500);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print(F("BLU 00:00:00")); //BLUE TEAM IN ROW 1
lcd->setCursor(0, 1);
lcd->print(F("YEL 00:00:00")); //YELLOW TEAM IN ROW 2
lcd->setCursor(0, 2);
lcd->print(F(" Martin Chlebovec "));
lcd->setCursor(0, 3);
lcd->print(F(" RFID DOMINATOR 2.0 "));
}
void loop() {
tickClock();
if ((millis() - timer2) >= 300) { //Check for incomming datas from RC522 reader each 300 ms
timer2 = millis();
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
dump_byte_array(rfid.uid.uidByte, rfid.uid.size);
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
if (code == TEAM_BLU) { // WAS CARD FROM TEAM BLUE?
if (!run) {
timer = millis();
}
Serial.println(F("Detected card from team BLU"));
digitalWrite(BLU_LED, HIGH);
digitalWrite(RED_LED, LOW);
digitalWrite(ORA_LED, LOW);
digitalWrite(GRE_LED, LOW);
run = true;
run2 = false;
}
if (code == TEAM_YEL) { //WAS CARD FROM TEAM YELLOW?
if (!run2) {
timer = millis();
}
Serial.println(F("Detected card from team YEL"));
digitalWrite(BLU_LED, LOW);
digitalWrite(RED_LED, LOW);
digitalWrite(ORA_LED, HIGH);
digitalWrite(GRE_LED, LOW);
run = false;
run2 = true;
}
if (code == TEAM_REFEREE) { //WAS CARD FROM TEAM REFEREE?
Serial.println(F("Detected card from REFEREE"));
digitalWrite(BLU_LED, LOW);
digitalWrite(RED_LED, LOW);
digitalWrite(ORA_LED, LOW);
digitalWrite(GRE_LED, LOW);
run = false;
run2 = false;
}
if (code == TEAM_ERASER) { //WAS CARD FROM TEAM ERASER?
Serial.println(F("Detected card from ERASER"));
digitalWrite(BLU_LED, LOW);
digitalWrite(RED_LED, LOW);
digitalWrite(ORA_LED, LOW);
digitalWrite(GRE_LED, LOW);
//Zero each value for times
second = 0;
minute = 0;
hour = 0;
second2 = 0;
minute2 = 0;
hour2 = 0;
updateLCD();
updateLCD2();
//Stop active team
run = false;
run2 = false;
}
}
}
}
void tickClock() {
if ((millis() - timer) >= 1000) { //Timer for counting time each 1000 ms (second resolution)
timer = millis();
//Serial.println(timer); //UNCOMMENT TO GET TIMER PRECISION INFO, if couting in 1000 ms or more
if (once == false) {
timer2 = millis();
once = true;
}
error = Wire.endTransmission(); //check, if display was disconnected during operation, if yes, that will renew is connection and initialization
if (error != 0) {
Serial.println("Display is not communicating");
// Communication error, re-initialize the communication with the LCD
lcd->begin(); //Not valid for Wokwi simulator, valid for LiquidCrystal_I2C library from @fdebrabander
lcd->backlight();
lcd->setCursor(0, 0);
lcd->print(F("BLU : : ")); //BLU TEAM IN ROW 1
updateLCD();
lcd->setCursor(0, 1);
lcd->print(F("YEL : : ")); //YEL TEAM IN ROW 2
updateLCD2();
}
tick();
tick2();
}
}
void tick() {
if (run) {
// updateLCD(); //print team 1 numbers (BLUE)
second++;
if (second >= 60)
{
second = 0;
minute++;
if (minute >= 60)
{
minute = 0;
hour++;
}
}
updateLCD();
}
}
void tick2() {
if (run2) {
// updateLCD2(); //print team 2 numbers (YELLOW)
second2++;
if (second2 >= 60)
{
second2 = 0;
minute2++;
if (minute2 >= 60)
{
minute2 = 0;
hour2++;
}
}
updateLCD2();
}
}
void updateLCD() {
lcd->setCursor(4, 0);
if (hour < 10) {
lcd->print(F("0"));
}
lcd->print(hour, DEC);
lcd->setCursor(7, 0);
if (minute < 10) {
lcd->print(F("0"));
}
lcd->print(minute, DEC);
lcd->setCursor(10, 0);
if (second < 10) {
lcd->print(F("0"));
}
lcd->print(second, DEC);
}
void updateLCD2() {
lcd->setCursor(4, 1);
if (hour2 < 10) {
lcd->print(F("0"));
}
lcd->print(hour2, DEC);
lcd->setCursor(7, 1);
if (minute2 < 10) {
lcd->print(F("0"));
}
lcd->print(minute2, DEC);
lcd->setCursor(10, 1);
if (second2 < 10) {
lcd->print(F("0"));
}
lcd->print(second2, DEC);
}
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
}
Serial.print(F("Detected UID (code) of RFID CARD: "));
code = 10000 * buffer[4] + 1000 * buffer[3] + 100 * buffer[2] + 10 * buffer[1] + buffer[0]; //Final UID (reverse order, byte 5 as MSB
Serial.println(code); //UID
}