Herný režim Capture Points je vhodný pre športy Airsoft, Paintball. Body medzi sebou komunikujú prostredníctvom WiFi modulov nRF24L01, pričom si medzi sebou vymieňajú informácie o stave bodu (či je obsadený a akým tímom). Prvý bod pracuje v režime permanentného vysielača a po vysielaní informácie očakáva odpoveď od druhého bodu. Druhý bod pracuje v režime prijímač a odpovedá na prijatie dát vysielaču (callback). Tento mechanizmus komunikácie predchádza kolíziám. Situácia, žeby oba body vysielali súčasne a nedokázali prijať informáciu tak nehrozí. Každý z bodov využíva riadiaci mikrokontróler Arduino (Arduino Uno / Nano), prípadne samostatný čip (Atmel) ATmega328P, ktorý riadi logiku stlačenia tlačidiel. V hre sú 2 tímy - RED tím a GRE tím, ktoré proti sebe hrajú a snažia sa obsadiť oba body stlačením príslušného tlačidla. Tlačidlový vstup indikuje akciu obsadenia bodu členom tímu RED, alebo GRE. Využívajú sa spínacie tlačidlá zapojené v režime INPUT_PULLUP, spínajú sa proti zemi (active-low signál). Dĺžka stlačenia (držania) / počet stlačení sa v dostupnej programovej implementácii neoveruje. Bod reaguje okamžite na stlačenie tlačidla bez pauzy.
Hra sa končí v momente, kedy sú obsadené oba body rovnakým tímom. Zmenu na bode indikuje hlásič, ktorý pípne vždy pri stlačení tlačidla. Na konci hry oba hlásiče pípajú v nekonečnej slučke. Zároveň sa preruší WiFi komunikácia medzi modulmi nRF24L01, aby neboli prenášané ďalšie informácie a výsledok hry bol definitívny. WiFi moduly nRF24L01 (verzia bez + PA + LNA) komunikujú na cca 70 metrov, nRF24l01 + PA + LNA aj na kilometer, respektíve v lese a inak zarušenom prostredí na úrovni 450-700 metrov pri maximálnom vysielacom výkone 1 mW. Pri externom napájaní je možné použiť adaptér YL-105 s 3.3V prevodníkom a napájať cez externý adaptér v rozsahu 5 až 18V. 5V napájanie z Arduina nie je doporučené, nakoľko, hrozí zničenie regulátora, keďže potrebný prúd pre maximálny výkon nie je schopné dodať. Pri napájaní nRF24L01 cez 3V3 vývod Arduina je možné napájať na najnižší vysielací výkon 0,0158 mW. Reštart oboch bodov prebieha za pomoci reset tlačidla Arduín, alebo vytiahnutím a pripojením napájania (power-on cyklus). Teoreticky je možné WiFi body rozšíriť až na 8 bodov (8 pipelines), ktoré medzi sebou komunikujú, resp. môžu komunikovať iba s vysielačom na základe navrhnutej logiky. Je však nutné pridať identifikátor jednotlivých bodov pre ich rozlíšenie. Vysielač, ktorý komunikáciu inicializuje tak dokáže rozlíšiť obsadenie tímu na všetkých WiFi bodoch, ktoré sú v systéme implementované. Pri prenose väčšieho množstva údajov zároveň je možné využiť aj štruktúru, kde je možné prenášať viac dátových typov súčasne ako jeden paket. Prijímací bod tak dokáže dáta z očakávanej štruktúry získať na základe veľkosti jednotlivých dátových typov.
Arduino Uno / Nano (AtMega328P) | nRF24L01 |
GND | GND |
3V3 / externý zdroj | Vcc |
D3 | CSN |
D4 | CE |
D11 | MOSI |
D12 | MISO |
D13 | SCK |
Arduino Uno / Nano (AtMega328P) | LED diódy |
GND | GND |
D7 | IN (RED) |
D8 | IN (GREEN) | Arduino Uno / Nano (AtMega328P) | Tlačidlá (INPUT_PULLUP) |
GND | GND |
D5 | IN (RED) |
D6 | IN (GRE) | Arduino Uno / Nano (AtMega328P) | Buzzer |
D2 | IO |
GND | GND |
Názov knižnice | Funkcia knižnice | Stiahnuť |
---|---|---|
RF24 |
Knižnica pre AVR mikrokontroléry (ATmega) Arduino Uno / Nano / Mega. Umožňuje ovládať WiFi moduly nRF24L01 (nRF24L01 + PA + LNA) komunikujúce po SPI zbernici. |
Stiahnuť |
// nRF24L01 transmitter //WiFi points for Airsoft Points //Created by: martinius96@gmail.com //Donate coffee: paypal.me/chlebovec #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"; boolean last_packet = false; 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 ); //RF24_250KBPS, RF24_1MBPS, RF24_2MBPS nRF.setPALevel(RF24_PA_LOW); //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX nRF.openWritingPipe(adresaVysilac); nRF.openReadingPipe(1, adresaPrijimac); nRF.startListening(); } void loop() { if (response == received) { if (last_packet == false) { last_packet = true; nRF.stopListening(); nRF.write( &response, sizeof(response) ); delay(50); } 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); } }
// nRF24L01 receiver //WiFi points for Airsoft Points //Created by: martinius96@gmail.com #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"; boolean last_packet = false; 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 ); //RF24_250KBPS, RF24_1MBPS, RF24_2MBPS nRF.setPALevel(RF24_PA_LOW); //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX nRF.openWritingPipe(adresaPrijimac); nRF.openReadingPipe(1, adresaVysilac); nRF.startListening(); } void loop() { if (response == received) { if (last_packet == false) { last_packet = true; nRF.stopListening(); nRF.write( &response, sizeof(response) ); delay(50); } 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(); } } }