RFID DOMINATOR: cronómetro Domination para Airsoft y Paintball
Acerca de RFID DOMINATOR – Cronómetro de Airsoft
RFID DOMINATOR es un cronómetro creado para Airsoft, Paintball, que aumenta la experiencia de juego y aporta equidad. Son adecuados para el modo de juego DOMINATOR, Capture the Point. DOMINATOR crea un punto que es ocupado por un jugador del equipo. El dispositivo incluye una pantalla LCD de caracteres que informa sobre el tiempo actual de cada equipo. Al mismo tiempo, un diodo LED señala el equipo activo en el punto. El jugador ocupa el punto DOMINATOR colocando una pulsera o tarjeta RFID. Cuando el punto está ocupado, suena una alarma que anuncia un cambio en el punto. El tiempo del equipo se cuenta hasta que un jugador de otro equipo coloca su etiqueta RFID, o hasta que el árbitro detiene el tiempo. El tiempo continúa contando después de que el punto está ocupado. DOMINATOR cuenta el tiempo total ocupado por todos los equipos en el juego. Puede usarse para 2 o 4 equipos en un juego. Además de detener el reloj, el árbitro también puede reiniciarlo antes de un nuevo juego.
Escenarios de uso
Ideal para patios de recreo, campos que ofrecen experiencia de Airsoft / Paintball. Eventos como LARP, MilSim, Scenario, Speedball, debido al tamaño del flash que admite cientos de etiquetas RFID en una sola aplicación
Hardware compatible
Con la PCB RFID DOMINATOR 2.0, los siguientes componentes son compatibles
Firmware DEMO
RFID DOMINATOR ofrece firmware DEMO gratuito que le permite probar el dispositivo y sus funciones básicas, si está cableado correctamente como en los esquemas disponibles en la página web de RFID DOMINATOR
Diseño modular, firmware portátil
El diseño modular de RFID DOMINATOR permite al usuario reemplazar los componentes principales sin necesidad de soldar nada. Mediante el método de intercambio en caliente, puede quitar el módulo y colocar uno nuevo en cuestión de segundos. El usuario puede copiar y clonar el firmware a cualquier cantidad de dispositivos. Pague la licencia una vez y úsela tantas veces como necesite para sus dispositivos.
Asequible
Clonable
Fácil de usar
Compatible con hardware de código abierto
Compatible con RFID
Diseño modular
Salida de pantalla
Soporte y comentarios
Detalles
PCB
Especificaciones de PCB de RFID DOMINATOR 2.0
104 x 103 x 1,6 mm, PCB de doble cara tipo FR4. La serigrafía en la PCB marca la posición y orientación de los componentes, y cómo deben soldarse.
Compatibilidad con hardware de código abierto
Hardware compatible con hardware de código abierto
El hardware de RFID DOMINATOR está relacionado con el uso de hardware de código abierto. Utiliza módulos Arduino y la propia placa Arduino para un diseño modular y aprovecha las ventajas del hardware de código abierto (rentable, fácil de reemplazar).
PCB ensamblado
Ver en PCB, después de haber sido ensamblada con componentes compatibles
Después de ensamblar la PCB RFID DOMINATOR 2.0, la altura total de la PCB se extiende a 45 mm. En la parte frontal, hay una pantalla LCD2004A y un lector MFRC522, junto con diodos LED y un zumbador. Desde la parte posterior, hay un controlador Arduino Nano V3.0. Los componentes principales utilizan conectores de pines.
Carcasa
Carcasa impresa en 3D para RFID DOMINATOR 2.0
Carcasa compatible con la PCB de RFID DOMINATOR 2.0. Las dimensiones de la carcasa son 124 x 123 x 47 mm. La PCB se monta desde el interior, en la parte frontal de la carcasa, utilizando 4 tornillos M3. Es posible utilizar una correa de sujeción de 25 mm (ancho) en la carcasa para montarla en árboles o vigas.
Diagrama de cableado
Diagrama de cableado para RFID DOMINATOR 2.0
El diagrama de cableado muestra cómo Arduino Nano está conectado a todos los demás componentes. Para LCD2004A, se utiliza un bus I2C cableado por hardware y para el bus SPI MFRC522. Se utilizan GPIO adicionales para las indicaciones de los diodos LED y para el zumbador con soporte PWM.
Botón DOMINATOR
Prototipo del botón mecánico DOMINATOR
La PCB estándar de RFID DOMINATOR 2.0 también se puede utilizar para el botón DOMINATOR. La única diferencia es que se retira el lector RFID y se insertan dos botones con diámetro opcional. También es posible usar botones con retroiluminación LED.
Galería
Preguntas frecuentes
A continuación, se muestran las preguntas más frecuentes de nuestra comunidad.
¿Cuál es el consumo de energía del sistema?
El sistema normalmente consume entre 40 y 60 mAh a 5 V, lo que equivale a entre 0,2 y 0,3 W. Una fuente de alimentación de 2000 mAh puede hacer funcionar el sistema durante 30 a 35 horas, según la carga.
¿Puedo alimentarlo a través de un banco de energía?
Sí, el RFID DOMINATOR se puede alimentar directamente usando un banco de energía a través de su salida de 5 V. El RFID DOMINATOR requiere un conector MiniUSB, también puede haber algunas versiones de Arduino Nano con conector microUSB.
¿Cómo puedo cargar el firmware?
Ya sea que se trate de un firmware DEMO o FINAL, utilice el archivo .hex proporcionado compatible con Arduino. Cárguelo utilizando la herramienta XLoader. Para Arduino Nano con el cargador de arranque antiguo, configure la velocidad a 57600 baudios/s, para el cargador de arranque nuevo, utilice 115200 baudios/s. La carga exitosa se confirma mediante un mensaje de XLoader, que puede informarle sobre un proceso de carga fallido.
¿Cómo copiar el firmware existente?
Simplemente cargue el mismo archivo de firmware (.hex) que recibió por correo electrónico en su próxima unidad RFID DOMINATOR. Funcionará de la misma manera y reaccionará a las mismas pulseras y tarjetas RFID. No hay límite para la cantidad de clones que puede crear, usted decide.
¿Se puede cambiar el nombre de un equipo?
No por el momento, pero pronto será posible, cuando se termine la extensión de los comandos AT. Los nombres de los equipos deben tener un máximo de 3 letras (el software lo limitará).
¿Se puede utilizar DOMINATOR en exteriores?
DOMINATOR no tiene una carcasa resistente al agua. Si está seco, también se puede utilizar en exteriores. Se utiliza principalmente en interiores o bajo techo.
¿En qué formato está disponible DOMINATOR?
RFID DOMINATOR está disponible en forma de código fuente de versión mínima: zumbador eliminado, uso exclusivo de pantalla LCD 20x4, máx. 1 tarjeta RFID por entidad. El botón DOMINATOR está disponible como código de máquina .hex, que se puede ejecutar directamente en una MCU ATmega328P (Arduino Uno, Nano), sin acceso al código fuente. Los archivos de diseño DPS y los archivos .STL de la caja impresa en 3D no se proporcionan con el software.
RFID DOMINATOR - código fuente:
Versión mínima, 1 tarjeta por equipo, sin timbre, solo para pantalla LCD de 20x4
¡Prueba RFID DOMINATOR en el simulador Wokwi! - Haz clic aquí
//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
}