Airsoft / Paintball - Wifi body cez Arduino

Tvoříte zajímavý projekt? Pochlubte se s ním.
Pravidla fóra
Vkládejte prosím jen HOTOVÉ projekty, které chcete představit ostatním.
Odpovědět
martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Airsoft / Paintball - Wifi body cez Arduino

Příspěvek od martinius96 » 02 bře 2019, 21:03

Airsoft je outdoor hra radiacia sa k extrémnym športom. Hra je veľmi populárna a tak si vyslúžila postupom času aj rôzne štýly hrania, teda herné módy. Väčšina z nich je postavená na populárnych FPS tituloch ako Counter Strike či Call of Duty. Od útočných a obranných módov až po Free-for-all. Jedným veľmi obľúbených módom je aj Capture points, respektíve DOMINATION. V tomto hernom móde ide o minimálne dve lokácie, o ktoré tímy bojujú.

Cieľom hry je obsadiť a udržať oba body jedným tímom. Body sú umiestnené v neutrálnej lokácii, napríklad na úrovni stredu mapy po stranách, alebo každý v sídle druhého tímu. Aby bola hra dostatočne rýchla, stačí ak tím obsadí oba body. Ak je zapísaný na oboch bodoch (nemusí ho udržať po x sekúnd), hra sa končí a tím vyhral. Aby som hru urobil zaujímavejšou a využil potenciál Arduina a jeho modulov, vyhotovil som takéto dva body.
Každý bod obsahoval po hardvérovej stránke:
  • Arduino Nano/Uno (alebo možné využiť i samostatný AtMega čip) Obrázek
  • buzzer (typu active/passive) pre ohlásenie konca hry (stačí i 2-pin)Obrázek
  • wifi modul nRF24l01 + PA + LNAObrázek
  • dvojica tlačidiel - pushbuttonovObrázek
  • LED diódy s farbami tímovObrázek
  • *doplnkové relé pre zopnutie silnejších svetiel na 12V/24V/230VObrázek
Ako funguje systém po stránke funkčnosti?
Jedno tlačidlo je pre Tím 1 (žltý tím) a druhé pre Tím 2 (červený tím). Tím pri obsadení stlačí svoje tlačidlo, čo zmení farbu bodu podľa ich tímu. Ak jeden tím obsadí oba body, rozuzvučia sa hlásiče na oboch bodoch (hra sa skončí, alebo pokračuje ďalej podľa pravidiel organizátora akcie, napr. do posledného muža pre druhý bod za hru). Hra nie je časovo ohraničená limitom. Končí sa na akciu organizátora, alebo obsadením bodov!

V reálnom čase medzi sebou obe Arduiná komunikujú s modulmi nRF24l01 + PA + LNA. Odozva medzi oboma Arduinami je na úrovni 1-5ms. Jeden modul vysiela vždy, druhý mu na jeho vysielanie odpovedá, čo prvý modul prijíma. Takáto je koncepcia obojsmerného prenosu. Druhý bod odpovedá na vysielanie prvého, nevysiela non-stop a prvý bod. Vďaka modulom nRF24l01 je možné komunikovať medzi Arduinami na obrovské vzdialenosti, teda na stovky metrov v nezarušenom prostredí (nRF24l01 ponúka vyše 120 kanálov pre komunikáciu na 2,4Ghz.), čo je možné prispôsobiť aj na aktuálne zarušenie v 2.4GHz pásme.

Pri využití externého 5v/3.3v zdroja je možné komunikovať až na 1,1 kilometra v nezarušenom prostredí najnižšou prenosou rýchlosťou (250kb/s). V programe pre Arduino sa určuje komunikačný kanál, výkon nRF modulu, prenosová rýchlosť (250kb/s až 2Mbps). Čím je vyššia rýchlosť zvolená, tým náchylnejší je systém na rušenie. V prostredí lesa sme s najnižšou prenosou rýchlosťou a maximálnym vysielacím výkonom dosiahli prenos na 310 metrov, kedy ešte systém fungoval bez výpadkov.

Princíp je teda veľmi jednoduchý a systém je možné rozšíriť o ďalšie nRF moduly. Jeden modul dokáže komunikovať až s ôsmymi modulmi, systém je teda možné rozšíriť až na 9 bodov, o ktoré sa bojuje. Najvyšší prenosový výkon nie je možné nastaviť pri napájaní z Arduina, nakoľko odber nRF prevyšuje prúdové charakteristiky regulátora, ktorý je na ňom použitý. Využíva sa preto napájanie na 5-12V cez adaptér, do ktorého sa modul zasadí a má on-board regulátor na 3.3V.
Obrázek
Do modulu zapasuje aj modul nRF24l01 (bez PA + LNA). PA + LNA je označenie pre modul s anténou, ktorý je 10-12x lepší dosahovo ako pôvodný nRF24l01 modul. Pôvodný modul má maximálny dosah 100 metrov v nezarušenom prostredí s maximálnym výkonom. Modul nRF24l01 komunikuje po SPI zbernici a má voliteľné piny CE (Chip state) a CS (Chip select). Komunikácia je rýchla s nízkou latenciou. Tieto moduly vedia komunikovať iba medzi sebou, nie je ich možné použiť napríklad pre pripojenie k internetu a pod. Jedná sa výlučne o komunikačné moduly medzi sebou na frekvencii 2,4GHz. Hlavnou nevýhodou týchto modulov je vzdialenosť pinov od seba v oboch radoch, čo neumožňuje modul použiť do breadboardu. Preto sa pri vývoji bez adaptéra zrejme nezaobídete.

Pri použití hlásiča (buzzra) je možné generovať frekvenciu signálu, ktorú bude buzzer vydávať, minimum je 31Hz a možnosť je zvoliť až cez 65 5XXHz. Aktívne i pasívne buzzre k Arduinu znejú prakticky rovnako. Povedal by som, že aktívne sú o niečo hlasnejšie. Z vlastnej skúsenosti používam 800 - 4000Hz pre frekvenciu tónnov, čo sú tóny pomerne zreteľné a vhodné pre pípajúci zvuk, nie sú príliš otravné a je ich dobre počuť. Ovládať hlasitosť ako takú nie je u takýchto modulov možné. Pri nastavení novej hry je možné oba zariadenia odpojiť a pripojiť na batériu/adaptér, alebo obe zariadenia reštartovať tlačidlom pre premazanie uložených stavov tímov, aby hlásič ustal.

Ďalšie zaujímavé projekty vrátane stručných informácii o tomto projekte je možné nájsť na mojom webe: https://arduino.php5.sk/airsoft-wifi.php

Riešenie používa vstavanú knižnicu SPI.h pre komunikáciu a knižnicu RF24.h pre nRF24l01 moduly. Je možné použiť i Radiohead knižnicu, ktorá ale neumožňuje regulovať vysielací výkon a voliť špecifické kanály, využíva tzv. pipes pre komunikačnú cestu, nie navolené číslo kanálu. Priložené zdrojové kódy môžete vyskúšať pre funkcionalitu spísanú vyššie a vyskúšať si takýto štýl hry. Pozor pri zapojení tlačidiel, používa sa zapojenie INPUT_PULLUP, teda tlačidlo je aktívne (stlačené) pri hodnote LOW - zem. Tento systém je vhodný pre športy typu Airsoft, Paintball, Nerf Wars. Vhodný pre tímy, športový areál, akciu a pod.
Zdrojový kód pre BOD 1:

Kód: Vybrat vše

// nRF24L01 BOD1
#include  <SPI.h> 
#include "RF24.h"
#define CE 4
#define CS 3
RF24 nRF(CE, CS);
int odozva = 8;
int prijem = 12;
const int buzzer = 2;
const int cervenytim = 5;
const int zltytim = 6;
const int cervenaled = 7;
const int zltaled = 8;
byte adresaPrijimac[] = "prijimac00";
byte adresaVysilac[] = "vysilac00";
void setup() {
 Serial.begin(9600);
 pinMode(buzzer, OUTPUT);
 pinMode(cervenaled, OUTPUT);
 pinMode(zltaled, OUTPUT);
 pinMode(cervenytim, INPUT_PULLUP);
 pinMode(zltytim, INPUT_PULLUP);
 nRF.begin();
 nRF.setDataRate( RF24_250KBPS );
 nRF.setPALevel(RF24_PA_HIGH);
 nRF.openWritingPipe(adresaVysilac);
 nRF.openReadingPipe(1, adresaPrijimac);
 nRF.startListening();
}

void loop() {
 if (odozva == prijem) {

 tone( buzzer, 900, 800);

 delay(1000);
 } else {
 noTone;
 int vystupcerveny = digitalRead(cervenytim);
 int vystupzlty = digitalRead(zltytim);
 if (vystupcerveny == LOW) {
 odozva = 1;
 digitalWrite(cervenaled, HIGH);
 digitalWrite(zltaled, LOW);
 } else if (vystupzlty == LOW) {
 odozva = 2;
 digitalWrite(cervenaled, LOW);
 digitalWrite(zltaled, HIGH);
 }

 nRF.stopListening();
 nRF.write( &odozva, sizeof(odozva) );
 nRF.startListening();
 while (nRF.available()) {
 nRF.read( &prijem, sizeof(prijem) );
 }
 Serial.println("Prijata volba: ");
 Serial.println(prijem);
 Serial.println("Odozva: ");
 Serial.println(odozva);
 delay(50);
 }
}
		
Zdrojový kód pre BOD 2:

Kód: Vybrat vše

// nRF24L01 BOD2
#include  <SPI.h>
#include "RF24.h"
int odozva = 3;
int prijem = 4;
const int buzzer = 2;
const int cervenytim = 5;
const int zltytim = 6;
const int cervenaled = 7;
const int zltaled = 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(cervenaled, OUTPUT);
 pinMode(zltaled, OUTPUT);
 pinMode(cervenytim, INPUT_PULLUP);
 pinMode(zltytim, INPUT_PULLUP);
 nRF.begin();
 nRF.setDataRate( RF24_250KBPS ); 
 nRF.setPALevel(RF24_PA_HIGH);
 nRF.openWritingPipe(adresaPrijimac);
 nRF.openReadingPipe(1, adresaVysilac);
 nRF.startListening();
}

void loop() {
 if (odozva == prijem) {

 tone( buzzer, 900, 800);

 delay(1000);
 } else {
 noTone(buzzer);
 int vystupcerveny = digitalRead(cervenytim);
 int vystupzlty = digitalRead(zltytim);
 if (vystupcerveny == LOW) {
 odozva = 1;
 digitalWrite(cervenaled, HIGH);
 digitalWrite(zltaled, LOW);
 } else if (vystupzlty == LOW) {
 odozva = 2;
 digitalWrite(cervenaled, LOW);
 digitalWrite(zltaled, HIGH);
 }

 if ( nRF.available()) {
 // čekání na příjem dat
 while (nRF.available()) {
 nRF.read( &prijem, sizeof(prijem) );
 }
 Serial.println("Prijata volba: ");
 Serial.println(prijem);
 Serial.println("Odozva: ");
 Serial.println(odozva);
 nRF.stopListening();
 nRF.write( &odozva, sizeof(odozva) );
 nRF.startListening();
 		}
	}
}
Knižnica RF24.h: https://github.com/maniacbug/RF24

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 6 hostů