Repository with test software implementations for Airsoft points: Airsoft - WiFi points - Arduino
The firmware is available free of charge
Arduino DOMINATOR WiFi Stopwatch Schematics Pushbutton Capture Points Paintball

WiFi points for Airsoft | Paintball


Entities in the WiFi points project:


Team red - button for user entry
Team RED
Team red - button for user entry
Team GRE

Project description WiFi points:


Capture Points game mode for Airsoft and Paintball sports. The points communicate with each other via WiFi modules from the nRF24L01 series, while they exchange information about the status of the point (whether it is occupied and by which team). One point is a permanent transmitter and requires communication from the other point. The second point is the receiver and responds to the data received by the transmitter, thus avoiding collisions when communicating on the WiFi frequency 2.4 GHz. Each of the points uses an Arduino control microcontroller (Arduino Uno / Nano), or a separate chip (Atmel) AtMega328P, which controls the entire logic of the system. There are 2 teams in the game - RED team a GRE team, who play against each other and try to occupy both points by pressing the appropriate button.


Button input indicates the action of occupying a point by a member of the RED or GRE team. The pushbuttons connected in the INPUT_PULLUP mode are used (input of Arduino is connected to internal pullup resistor). Pressing the button brings GND signal to the Arduino digital input terminal (Active-LOW switching signal). Press (hold) duration / number of presses is not implemented. The point responds immediately to a button press without any delay. Game ends when both points are occupied by the same team. On button press, it is indicated by buzzer for all players nearby (information about change). At the end of game both buzzers will beep in infinite loop. At the same time WiFi communication between the nRF24L01 modules is closed.
WiFi modules nRF24l01 communicate at 2.4 GHz. nRF24l01 (without + PA + LNA) communicate at about 70 meters, nRF24l01 + PA + LNA also per kilometer, respectively in the forest and otherwise disturbed environment at the level of 450-700 meters at maximum transmission power. For external power supply, it is necessary to use a YL-adapter with a 3.3V converter and power it via an external adapter. Do not use a 5V power supply from the Arduino, there is a risk of destroying the controller, as well as the 3V3 terminal is not suitable for powering the module, as it has a high current consumption in more powerful transmission modes. Restart of both points is performed by resetting the Arduín button, or by pulling out and connecting the power supply (power-on cycle).

Wireless modules communicate at 2.4GHz, it is not WiFi technology, they do not require a router or access point! The modules have their own communication channel with a choice of up to 140 channels.

Supported module speeds nRF24L01:


  • 250 kbps - this option is not supported for older nRF24L01!
  • 1 Mbps
  • 2 Mbps

  • Power modes of nRF24L01 modules:


  • RF24_PA_MIN = -18 dBm --> 0,0158 mW
  • RF24_PA_LOW = -12 dBm --> 0,0631 mW
  • RF24_PA_MED = -6 dBm --> 0,2512 mW
  • RF24_PA_HIGH = 0 dBm --> 1 mW

  • Block diagram - WiFi points - Airsoft:


    Bloková schéma / Block scheme - Capture Points - Airsoft / Paintball, Arduino, nRF24L01

    Compatible control hardware for WiFi Airsoft points:



    Peripherals for WiFi Airsoft points:


    2x WiFi module nRF24L01 / nRF24L01 + PA + LNA
    2x WiFi module nRF24L01 / nRF24L01 + PA + LNA
    Pushbutton (pushbutton)
    4x Pushbutton
    Buzzer
    2x Buzzer
    2x LEDs
    4x LEDs

    Wiring diagram - WiFi points


    WiFi body - DOMINATOR - schéma zapojenia - Arduino / Airsoft, stopwatch, DOMINATION

    WiFi points - test connection


    WiFi body - - Arduino pre Airsoft, Paintball

    WiFi points - Capture Points - How it works:


    Table connection of terminals - Configurable DOMINATOR - fully corresponds to the wiring diagram:

    Arduino Uno / Nano (AtMega328P) nRF24L01
    GND GND
    3V3 / external source Vcc
    D3 CSN
    D4 CE
    D11 MOSI
    D12 MISO
    D13 SCK
    Arduino Uno / Nano (AtMega328P) LED diodes
    GND GND
    D7 IN (RED)
    D8 IN (GREEN)
    Arduino Uno / Nano (AtMega328P) Pushbuttons (INPUT_PULLUP)
    GND GND
    D5 IN (RED)
    D6 IN (GRE)
    Arduino Uno / Nano (AtMega328P) Buzzer
    D2 IO
    GND GND

    Program - WiFi points


    Program - NODE 1 (permanent transmitter)


    // nRF24L01 transmitter
    #include <SPI.h>
    #include "RF24.h"
    #define CE 4
    #define CS 3
    RF24 nRF(CE, CS);
    int response = 8;
    int received = 12;
    const int buzzer = 2;
    const int red_team = 5;
    const int blue_team = 6;
    const int red_led = 7;
    const int blue_led = 8;
    byte adresaPrijimac[] = "prijimac00";
    byte adresaVysilac[] = "vysilac00";
    void setup() {
      Serial.begin(9600);
      pinMode(buzzer, OUTPUT);
      pinMode(red_led, OUTPUT);
      pinMode(blue_led, OUTPUT);
      pinMode(red_team, INPUT_PULLUP);
      pinMode(blue_team, INPUT_PULLUP);
      nRF.begin();
      nRF.setDataRate( RF24_250KBPS );
      nRF.setPALevel(RF24_PA_LOW);
      nRF.openWritingPipe(adresaVysilac);
      nRF.openReadingPipe(1, adresaPrijimac);
      nRF.startListening();
    }
    
    void loop() {
      if (response == received) {
        tone( buzzer, 900, 800);
        delay(1000);
      } else {
        nRF.stopListening();
        int output_red = digitalRead(red_team);
        int output_blue = digitalRead(blue_team);
        if (output_red == LOW) {
          response = 1;
          digitalWrite(red_led, HIGH);
          digitalWrite(blue_led, LOW);
        } else if (output_blue == LOW) {
          response = 2;
          digitalWrite(red_led, LOW);
          digitalWrite(blue_led, HIGH);
        }
        nRF.write( &response, sizeof(response) );
        nRF.startListening();
        while (nRF.available()) {
          nRF.read( &received, sizeof(received) );
        }
        Serial.println("Received datas: ");
        Serial.println(received);
        Serial.println("Response: ");
        Serial.println(response);
        delay(50);
      }
    }
    

    Program - NODE 2 (permanent receiver with callback to the transmitter)


    // nRF24L01 receiver
    #include <SPI.h>
    #include "RF24.h"
    int response = 3;
    int received = 4;
    const int buzzer = 2;
    const int red_team = 5;
    const int blue_team = 6;
    const int red_led = 7;
    const int blue_led = 8;
    #define CE 4
    #define CS 3
    RF24 nRF(CE, CS);
    byte adresaPrijimac[] = "prijimac00";
    byte adresaVysilac[] = "vysilac00";
    void setup() {
      Serial.begin(9600);
      pinMode(buzzer, OUTPUT);
      pinMode(red_led, OUTPUT);
      pinMode(blue_led, OUTPUT);
      pinMode(red_team, INPUT_PULLUP);
      pinMode(blue_team, INPUT_PULLUP);
      nRF.begin();
      nRF.setDataRate( RF24_250KBPS );
      nRF.setPALevel(RF24_PA_LOW);
      nRF.openWritingPipe(adresaPrijimac);
      nRF.openReadingPipe(1, adresaVysilac);
      nRF.startListening();
    }
    
    void loop() {
      if (response == received) {
        tone( buzzer, 900, 800);
        delay(1000);
      } else {
        if ( nRF.available()) {
          while (nRF.available()) {
            nRF.read( &received, sizeof(received) );
          }
          Serial.println("Received datas:: ");
          Serial.println(received);
          Serial.println("Response: ");
          Serial.println(response);
          nRF.stopListening();
          int output_red = digitalRead(red_team);
          int output_blue = digitalRead(blue_team);
          if (output_red == LOW) {
            response = 1;
            digitalWrite(red_led, HIGH);
            digitalWrite(blue_led, LOW);
          } else if (output_blue == LOW) {
            response = 2;
            digitalWrite(red_led, LOW);
            digitalWrite(blue_led, HIGH);
          }
          nRF.write( &response, sizeof(response) );
          nRF.startListening();
        }
      }
    }