Whether you make 2 or 250 targets, the system will auto-determine how many you have and trigger them randomly. Each target just needs a few configuration options by default (an id, a name, and 2 mp3s you want it to trigger when triggered and hit).
There is also room for functions to generate actions like additional LED lights or even physical actions like actuators. Functions are fired on activate, hit, and miss.
Please note: You do not need to actually use lasers for these targets. Arcade buttons would work fine for Nerf guns or other uses. Even steel plates in front of arcade buttons could work for things like pellet guns. Get creative! The point is not lasers...it is making flexible targets.
// NOTE: // GPIO // 6-11 are used in the flash process and shouldn't be used. // 34-39 are input only //Special thanks to these 3 Youtubers who kept me sane when I had several weird issues on this project //Simple Electronics - https://www.youtube.com/channel/UC3yasGCIt1rmKnZ8PukocSw //Gadget Reboot - https://www.youtube.com/channel/UCwiKHTegfDe33K5wnmyULog //Pile of Stuff - https://www.youtube.com/user/pileofstuff #include "WiFi.h" #include <PubSubClient.h> //Initial configuration #define DEVICE "cowboy" //This MUST be unique char* mp3 = "cowboy1.mp3|cowboy2.mp3"; //The mp3 when activated then when hit int id = 61; //serves as the final ip address and unique identifier int subnet = 95; //the second to last set of numbers in your ip addresses 192.168.SUBNET.xxx int serverip = 148; //what is the last part of the ip address of your nodered/mqtt server 192.168.SUBNET.SERVERIP const char* ssid = "YOUR_SSID_HERE"; const char* password = "YOUR_WIFI_PASSWORD_HERE"; //IO Variables int powerLed = 25; //green int shootMeLed = 26; //yellow int hitLed = 27; //red int sensor = 14; //laser sensor //State Variables int active = 0; //By default, should not accept input int reading = 0; //Store your sensor readinging char me[10]; //my id to be used in mqtt messages char mp3me[32]; //my mp3 request for setup char avme[32]; //activation request topic //Networking / MQTT Variables that usually don't need to be changed WiFiClient ethClient; PubSubClient client(ethClient); char *cstring; IPAddress arduino_ip ( 192, 168, subnet, id); IPAddress dns_ip ( 8, 8, 8, 8); IPAddress gateway_ip ( 192, 168, subnet, 1); IPAddress subnet_mask(255, 255, 255, 0); IPAddress server(192, 168, subnet, serverip); int request = 0; //GamePlay functions void activate(unsigned long duration){ unsigned long currentMillis = millis(); Serial.println("Looking for input"); //it's not obvious, but this next line will NOT keep looping. Only the stuff in the while loop will. unsigned long stopAt = currentMillis + duration; while(active == 1){ currentMillis = millis(); if (currentMillis <= stopAt) { //tell the world you're active digitalWrite(shootMeLed, HIGH); //read the sensor reading = digitalRead(sensor); if(reading == HIGH){ iveBeenHit(); } }else{ //time is up! deactivate(); client.publish("shooting/miss", "1"); miss(); } } } void deactivate(){ //stop looking for input and go dark digitalWrite(shootMeLed, LOW); active = 0; Serial.println("Deactivating sensor"); } void iveBeenHit(){ deactivate(); client.publish("shooting/hit", me); Serial.println("I have been hit!!!"); } void miss(){ //doing nothing right now } void callback(char* topic, byte* payload, unsigned int length) { for (int i = 0; i < length; i++) { payload[length] = '\0'; cstring = (char *) payload; } request = atof(cstring); Serial.println("msg rec"); if (strstr(topic, "whodere") != NULL) { request = atof(cstring); Serial.println("The request is..."); Serial.println(request); if(request == 1){ //tell the server you're there so you can be added to the target list // sprintf(msg,"%d",id); Serial.println("WhoDere Request Received....responding."); client.publish("shooting/response", mp3me); } } if (strstr(topic, "activate") != NULL) { request = atof(cstring); Serial.println("An activation request has been sent out"); Serial.println("I have been requested to activate for "); unsigned long dur = request; Serial.print(dur); Serial.println(" milliseconds"); active = 1; activate(dur); } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(DEVICE)) { Serial.println("connected"); // ... and resubscribe client.subscribe("shooting/whodere/#"); client.subscribe(avme); // client.subscribe(subscription.c_str()); // client.subscribe(reset.c_str()); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 20 seconds"); // Wait 20 seconds before retrying delay(20000); } } } void setup() { sprintf(me,"%d",id); sprintf(avme,"shooting/activate%d/#",id); sprintf(mp3me,"%d|%s",id,mp3); Serial.begin(57600); Serial.print("My id is "); Serial.println(id); Serial.print("My activation topic is "); Serial.println(avme); //establish mqtt connections client.setServer(server, 1883); client.setCallback(callback); Serial.print("Connecting to "); Serial.println(ssid); WiFi.config(arduino_ip, gateway_ip, subnet_mask); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // Allow the hardware to sort itself out pinMode(powerLed,OUTPUT); pinMode(shootMeLed,OUTPUT); pinMode(hitLed,OUTPUT); pinMode(sensor,INPUT); delay(1500); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); digitalWrite(powerLed,HIGH); }
This laser marker is just one option for shooting the targets. If you want to be able to differentiate between markers, you could use infrared or if you use something like Nerf, you don't need to make this at all.
/* Do whatever you want with this, but BE CAREFUL. I'm not responsible. You'll shoot someone's eye out. This is built on a Wemos D1 Mini Since the Wemos output pins are 3v, I'm using a transistor to switch the 5v on the board on/off to fire the laser Nearly any NPN Transistor would work, but I'm using a 2n222 When you're looking at the "flat" face of the transistor... Left(1) - Emittor Center(2) - Base Right(3) - Collector The wiring goes like this... 1. 5v pin on the wemos to the +(S) side of the laser 2. - Side of the laser to the Collector (right) side of the transistor. 3. Both one wire of the trigger AND the Emittor (left) side of the trasnistor go to Wemos Ground 4. The Base (center) of the transistor goes to pin D2 (AKA GPIO 4) on the Wemos 5. Pin D1 (AKA GPIO 5) goes to the other side of the pushbutton */ #include <ESP8266WiFi.h> #include <PubSubClient.h> #define DEVICE "PewPew" //This MUST be unique int laser = 4; //pin d2 int button = 5; //pin d1 int fired = 0; //Debounce and force people to take their finger off the button to fire again int reading = 0; //reading the button int mode = 0; //for future use int rateLimit = 750; //how often can you send a pew pew sound request int fireDuration = 100; //how long to activate the laser (in milliseconds) unsigned long currentMillis = millis(); unsigned long rateLimitOver = 0; //When am I allowed to send another MQTT message requesting a pew unsigned long canFireAgain = 0; //When am I allowed to send another laser burst int id = 59; //serves as the final ip address and unique identifier int subnet = 95; //the second to last set of numbers in your ip addresses 192.168.SUBNET.xxx int serverip = 148; //what is the last part of the ip address of your nodered/mqtt server 192.168.SUBNET.SERVERIP const char* ssid = "YOUR_SSID_HERE"; const char* password = "YOUR_WIFI_PASSWORD_HERE"; //Networking / MQTT Variables that usually don't need to be changed WiFiClient ethClient; PubSubClient client(ethClient); char *cstring; IPAddress arduino_ip ( 192, 168, subnet, id); IPAddress dns_ip ( 8, 8, 8, 8); IPAddress gateway_ip ( 192, 168, subnet, 1); IPAddress subnet_mask(255, 255, 255, 0); IPAddress server(192, 168, subnet, serverip); int request = 0; void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(DEVICE)) { Serial.println("connected"); // Once connected, publish an announcement... client.publish("shooting/lasercheck", DEVICE); // ... and resubscribe // client.subscribe("relays/#"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 20 seconds"); // Wait 20 seconds before retrying delay(20000); } } } void setup() { Serial.begin(57600); pinMode(laser, OUTPUT); pinMode(button, INPUT_PULLUP); client.setServer(server, 1883); Serial.print("Connecting to "); Serial.println(ssid); WiFi.config(arduino_ip, gateway_ip, subnet_mask); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Booted"); delay(1500); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); currentMillis = millis(); //get the current time of this loop reading = digitalRead(button); //find the state of the button if(currentMillis >= canFireAgain){ //check and see if you should turn the laser off and allow refire digitalWrite(laser, LOW); if(fired == 0){ //Only if the trigger has been released if(reading == LOW){ Serial.println("firing"); digitalWrite(laser, HIGH); canFireAgain = currentMillis + fireDuration; if(currentMillis > rateLimitOver){ client.publish("shooting/pew", "1"); rateLimitOver = currentMillis + rateLimit; } fired = 1; } } } if(fired == 1){ reading = digitalRead(button); if(reading == HIGH){ Serial.println("resetting"); fired = 0; } } }
You will need to have Node-Red and Mosquitto installed and running on a PC or Raspberry Pi. They're both simple to install and run.
To import this code below, go to Node Red, go to the hamburger menu, import, clipboard and paste the code below. You will need to update the MQTT nodes with your own IP address for your MQTT server.
[{"id":"38ca78d7.f31b08","type":"inject","z":"3627a10e.7a9c8e","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":820,"wires":[["f89d093d.090b08","5d1d3556.07aa1c","aef0b95e.ee0df8"]]},{"id":"da250fb0.3b4dc","type":"mqtt out","z":"3627a10e.7a9c8e","name":"","topic":"shooting/whodere","qos":"0","retain":"","broker":"e36485ee.59f3d8","x":670,"y":360,"wires":[]},{"id":"1b22e5f4.80a4ba","type":"mqtt in","z":"3627a10e.7a9c8e","name":"Units Check In","topic":"shooting/response","qos":"0","datatype":"auto","broker":"e36485ee.59f3d8","x":1580,"y":1200,"wires":[["cc2484df.25f8e8"]]},{"id":"72213d66.db4e04","type":"inject","z":"3627a10e.7a9c8e","name":"Activate #65","topic":"","payload":"4000","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1670,"y":1260,"wires":[["949f9dfb.a4444"]]},{"id":"949f9dfb.a4444","type":"mqtt out","z":"3627a10e.7a9c8e","name":"","topic":"shooting/activate65","qos":"0","retain":"","broker":"e36485ee.59f3d8","x":1970,"y":1260,"wires":[]},{"id":"44c9fc6.e04ba04","type":"mqtt in","z":"3627a10e.7a9c8e","name":"","topic":"shooting/hit/#","qos":"0","broker":"e36485ee.59f3d8","x":1510,"y":320,"wires":[["afa8820.06b408","625171e5.a225f","76747054.d0178","a3aef5a4.0b2b88"]]},{"id":"625171e5.a225f","type":"debug","z":"3627a10e.7a9c8e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":2290,"y":300,"wires":[]},{"id":"f89d093d.090b08","type":"function","z":"3627a10e.7a9c8e","name":"Game Setup","func":"var startIp = 60;\nvar stopIp = 66;\nvar gameData = {}; //Create a place to store your game data\nfor (var i = startIp; i <= stopIp; i++) {\n var initial = [0,'click,mp3','boom.mp3'];\n gameData[i] = initial;\n}\n\nglobal.set('startIp',startIp); //What is the Lowest IP you have ever assigned for the game\nglobal.set('stopIp',stopIp); //What is the highest IP you have ever assigned for the game\nglobal.set('minTime',1500); //The minimum amount of time to activate a target\nglobal.set('maxTime',7500); //These ar in ms\nglobal.set('gameTime',60) ; //In seconds\nglobal.set('score',0); //how many targets have been hit\nglobal.set('shown',0); // how many targets have been shown\nglobal.set('lastTarget',0); //for internal use\n\nmsg.payload = 1; //this is what the arduinos look for to check in\nglobal.set('gameData',gameData);\n\nreturn msg;\n","outputs":1,"noerr":0,"x":370,"y":200,"wires":[["12715b12.686bc5","da250fb0.3b4dc","795d9d95.ae48f4","5c2cd856.9729a8"]]},{"id":"12715b12.686bc5","type":"debug","z":"3627a10e.7a9c8e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":890,"y":300,"wires":[]},{"id":"c688128c.3dadc","type":"function","z":"3627a10e.7a9c8e","name":"Get Saved Data","func":"var gameData = global.get('gameData');\nmsg.payload = gameData;\nglobal.set('gameData',gameData);\nreturn msg;\n","outputs":1,"noerr":0,"x":1800,"y":1320,"wires":[["7e725332.62f22c"]]},{"id":"7e725332.62f22c","type":"debug","z":"3627a10e.7a9c8e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1970,"y":1320,"wires":[]},{"id":"dd2f88cb.cdfa98","type":"inject","z":"3627a10e.7a9c8e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1620,"y":1320,"wires":[["c688128c.3dadc"]]},{"id":"cc2484df.25f8e8","type":"function","z":"3627a10e.7a9c8e","name":"Get Saved Data","func":"var incoming = msg.payload.split(\"|\");\nvar gameData = global.get('gameData');\nvar arduino = parseInt(incoming[0]);\n\ngameData[arduino] = [1,incoming[1],incoming[2]];\nglobal.set('gameData',gameData);\nreturn msg;\n","outputs":1,"noerr":0,"x":1780,"y":1200,"wires":[["a3b0a765.d396d8"]]},{"id":"a3b0a765.d396d8","type":"debug","z":"3627a10e.7a9c8e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1970,"y":1200,"wires":[]},{"id":"a4d0fb96.e50e98","type":"ui_text","z":"3627a10e.7a9c8e","group":"d9d089df.9ddee8","order":1,"width":"8","height":"3","name":"Current Time","label":"Timer","format":" <font size=\"+75\">{{msg.payload}}","layout":"col-center","x":1370,"y":820,"wires":[]},{"id":"537fd6a8.eb93a8","type":"switch","z":"3627a10e.7a9c8e","name":"Timer Switch Statement","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"stop","vt":"str"},{"t":"else"}],"checkall":"true","outputs":2,"x":868.9999313354492,"y":734.2000036239624,"wires":[["4ea1f005.a0f71"],["28b88e2d.c45b22"]]},{"id":"5d1d3556.07aa1c","type":"function","z":"3627a10e.7a9c8e","name":"Reset Function","func":"msg.reset = true;\nvar stop = global.set(\"stop\", 0);\n\nreturn msg;","outputs":1,"noerr":0,"x":653.9999160766602,"y":882.6000204086304,"wires":[["22b50424.73b71c"]]},{"id":"6e631ec0.95911","type":"inject","z":"3627a10e.7a9c8e","name":"Reset","topic":"","payload":"reset","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":130,"y":920,"wires":[["5d1d3556.07aa1c","aef0b95e.ee0df8","5c2cd856.9729a8"]]},{"id":"22b50424.73b71c","type":"function","z":"3627a10e.7a9c8e","name":"Reset Final","func":"var newMsg = { payload: msg.payload.length };\n\nmath = 0;\n\nnewMsg.payload = math;\nreturn newMsg;","outputs":1,"noerr":0,"x":882.6998977661133,"y":881.3999586105347,"wires":[["a4d0fb96.e50e98"]]},{"id":"4ea1f005.a0f71","type":"function","z":"3627a10e.7a9c8e","name":"Major Math Going on Here","func":"var newMsg = { payload: msg.payload.length };\nvar time = global.get(\"finalTime\"); \nvar major = global.get(\"majors\");\nvar minor = global.get(\"minors\");\nvar stop = global.get(\"stop\");\nvar time = time * 1; //force to number\nvar major = 30 * major;\nvar minor = 10 * minor;\nvar math = time + major + minor;\nvar h = 0;\nvar m = 0;\nvar s = 0;\nvar t = math;\n \ns = t % 60;\nt = (t - s)/60;\nm = t % 60;\nt = (t - m)/60;\nh = t;\nmath = h+\"h \"+m+\"m \"+s+\"s\";\n\nnewMsg.payload = math;\nreturn newMsg;\n","outputs":1,"noerr":0,"x":1300.9999923706055,"y":719.0000286102295,"wires":[[]]},{"id":"ee4c4904.c2ca28","type":"inject","z":"3627a10e.7a9c8e","name":"StartTimer","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":"","x":120,"y":120,"wires":[["f89d093d.090b08","63088a95.a6d624"]]},{"id":"ee79749d.3ac228","type":"looptimer","z":"3627a10e.7a9c8e","duration":".5","units":"Second","maxloops":"99999999","maxtimeout":"1","maxtimeoutunits":"Hour","name":"","x":480,"y":540,"wires":[["f3b6abe7.137608"],[]]},{"id":"f3b6abe7.137608","type":"counter","z":"3627a10e.7a9c8e","name":"","init":"0","step":".5","lower":"","upper":"","mode":"increment","outputs":"1","x":680,"y":520,"wires":[["91806719.0ded08"]]},{"id":"91806719.0ded08","type":"function","z":"3627a10e.7a9c8e","name":"getCount","func":"var newMsg = {payload:msg.count};\nvar timer = newMsg.payload;\nvar time = global.set(\"finalTime\", timer); \nreturn newMsg;","outputs":1,"noerr":0,"x":840,"y":520,"wires":[["537fd6a8.eb93a8","3416d337.b9863c"]]},{"id":"903ea1e4.8079a","type":"inject","z":"3627a10e.7a9c8e","name":"","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":90,"y":700,"wires":[["ee79749d.3ac228","87d8c403.9987e8"]]},{"id":"aef0b95e.ee0df8","type":"function","z":"3627a10e.7a9c8e","name":"Reset Time","func":"msg.reset = true;\nreturn msg;","outputs":1,"noerr":0,"x":651.9999351501465,"y":839.5999803543091,"wires":[["f3b6abe7.137608"]]},{"id":"28b88e2d.c45b22","type":"function","z":"3627a10e.7a9c8e","name":"forceTWO","func":"var time = msg.payload;\nmsg.payload = (Math.floor(time*100)/100).toFixed(2);\nreturn msg;","outputs":1,"noerr":0,"x":1084.0999946594238,"y":796.2000017166138,"wires":[["a4d0fb96.e50e98"]]},{"id":"87d8c403.9987e8","type":"function","z":"3627a10e.7a9c8e","name":"stop","func":"var stop = global.set(\"stop\", 1);\nreturn msg;","outputs":1,"noerr":0,"x":445.09992599487305,"y":740.1999998092651,"wires":[["537fd6a8.eb93a8"]]},{"id":"3416d337.b9863c","type":"function","z":"3627a10e.7a9c8e","name":"","func":"var endTime = global.get('gameTime') ; //In seconds\n\nif(msg.payload >= endTime){\n global.set('stop',1);\n msg.payload = \"stop\";\n return msg;\n}\n","outputs":1,"noerr":0,"x":990,"y":520,"wires":[["ee79749d.3ac228"]]},{"id":"795d9d95.ae48f4","type":"delay","z":"3627a10e.7a9c8e","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":440,"y":360,"wires":[["ee79749d.3ac228","d969955b.7f5748","ba7384d7.b525a8"]]},{"id":"7c2fc063.4d213","type":"ui_text","z":"3627a10e.7a9c8e","group":"d9d089df.9ddee8","order":1,"width":"8","height":"3","name":"Targets Hit","label":"Targets Hit","format":" <font size=\"+75\">{{msg.payload}}","layout":"col-center","x":2290,"y":380,"wires":[]},{"id":"afa8820.06b408","type":"function","z":"3627a10e.7a9c8e","name":"Set Score","func":"var stop = global.get('stop');\nif(stop === 0){ //don't look for input if the game has been stopped!\nvar score = global.get('score'); //how many targets have been hit\nscore = score + 1;\nglobal.set('score',score);\nmsg.payload = score;\nreturn msg;\n}","outputs":1,"noerr":0,"x":1780,"y":280,"wires":[["7c2fc063.4d213"]]},{"id":"5c2cd856.9729a8","type":"change","z":"3627a10e.7a9c8e","name":"Set Zeros","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1240,"y":520,"wires":[["7c2fc063.4d213","e4397bc3.cb7ec8"]]},{"id":"95121187.f3c35","type":"function","z":"3627a10e.7a9c8e","name":"","func":"var stop = global.get('stop');\nif(stop === 0){ //don't look for input if the game has been stopped!\nvar shown = global.get('shown'); //how many targets have been hit\nshown = shown + 1;\nglobal.set('shown',shown);\nmsg.payload = shown;\nreturn msg;\n}","outputs":1,"noerr":0,"x":1810,"y":520,"wires":[["e4397bc3.cb7ec8"]]},{"id":"e4397bc3.cb7ec8","type":"ui_text","z":"3627a10e.7a9c8e","group":"d9d089df.9ddee8","order":1,"width":"8","height":"3","name":"Targets Shown","label":"Targets Shown","format":" <font size=\"+75\">{{msg.payload}}","layout":"col-center","x":2000,"y":580,"wires":[]},{"id":"d969955b.7f5748","type":"function","z":"3627a10e.7a9c8e","name":"Show Another Target","func":"var stop = global.get('stop');\nif(stop === 0){\nvar gameData = global.get('gameData');\nvar startIp = global.get('startIp');\nvar stopIp = global.get('stopIp');\nvar lastTarget = global.get('lastTarget');\n\nvar avail = [];\nfor (var i = startIp; i <= stopIp; i++) {\n\tif(gameData[i][0] === 1 && i != lastTarget){\n\t\tavail.push(i);\n}\n}\n\nvar random = getRandomInt(0, avail.length-1);\nglobal.set('lastTarget',avail[random]);\nmsg.target = avail[random];\nmsg.topic = \"shooting/activate\"+avail[random];\nmsg.payload = getRandomInt(global.get('minTime'),global.get('maxTime'));\nreturn msg;\n}\n\nfunction getRandomInt(min, max) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}","outputs":1,"noerr":0,"x":1660,"y":900,"wires":[["95121187.f3c35","96f663a9.98daf","aa11cceb.ef1c9"]]},{"id":"9b083f4d.16965","type":"mqtt in","z":"3627a10e.7a9c8e","name":"","topic":"shooting/miss/#","qos":"0","datatype":"auto","broker":"e36485ee.59f3d8","x":1300,"y":320,"wires":[["d969955b.7f5748"]]},{"id":"96f663a9.98daf","type":"mqtt out","z":"3627a10e.7a9c8e","name":"Turn on new target","topic":"","qos":"0","retain":"","broker":"e36485ee.59f3d8","x":1990,"y":640,"wires":[]},{"id":"63088a95.a6d624","type":"exec","z":"3627a10e.7a9c8e","command":"c:\\xampp\\htdocs\\mosquitto\\cmdmp3","addpay":false,"append":"c:\\xampp\\htdocs\\mosquitto\\sounds\\ready.mp3","useSpawn":"true","timer":"","oldrc":false,"name":"","x":810,"y":120,"wires":[[],[],[]]},{"id":"ba7384d7.b525a8","type":"exec","z":"3627a10e.7a9c8e","command":"c:\\xampp\\htdocs\\mosquitto\\cmdmp3","addpay":false,"append":"c:\\xampp\\htdocs\\mosquitto\\sounds\\go.mp3","useSpawn":"false","timer":"","oldrc":false,"name":"","x":810,"y":420,"wires":[[],[],[]]},{"id":"3427f3c8.fbe97c","type":"exec","z":"3627a10e.7a9c8e","command":"c:\\xampp\\htdocs\\mosquitto\\cmdmp3","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":2330,"y":460,"wires":[[],[],[]]},{"id":"76747054.d0178","type":"function","z":"3627a10e.7a9c8e","name":"Play hit sound","func":"var hit = parseInt(msg.payload);\nvar gameData = global.get('gameData');\nvar mp3 = gameData[hit][2];\nmsg.payload = 'c:\\\\xampp\\\\htdocs\\\\mosquitto\\\\sounds\\\\'+mp3;\nreturn msg;","outputs":1,"noerr":0,"x":1930,"y":360,"wires":[["625171e5.a225f","3427f3c8.fbe97c"]]},{"id":"aa11cceb.ef1c9","type":"function","z":"3627a10e.7a9c8e","name":"Play show sound","func":"var grab = msg.target;\nvar gameData = global.get('gameData');\nvar mp3 = gameData[grab][1];\nmsg.payload = 'c:\\\\xampp\\\\htdocs\\\\mosquitto\\\\sounds\\\\'+mp3;\nreturn msg;","outputs":1,"noerr":0,"x":1990,"y":900,"wires":[["5857cc82.f8f404"]]},{"id":"a3aef5a4.0b2b88","type":"delay","z":"3627a10e.7a9c8e","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"1","randomUnits":"seconds","drop":false,"x":1600,"y":660,"wires":[["d969955b.7f5748"]]},{"id":"5857cc82.f8f404","type":"exec","z":"3627a10e.7a9c8e","command":"c:\\xampp\\htdocs\\mosquitto\\cmdmp3","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":2370,"y":860,"wires":[[],[],[]]},{"id":"4550176c.537658","type":"mqtt in","z":"3627a10e.7a9c8e","name":"Units Check In","topic":"shooting/pew","qos":"0","datatype":"auto","broker":"e36485ee.59f3d8","x":300,"y":1040,"wires":[["6b5c9a1b.9ad894","9cfb23af.567d"]]},{"id":"6b5c9a1b.9ad894","type":"exec","z":"3627a10e.7a9c8e","command":"c:\\xampp\\htdocs\\mosquitto\\cmdmp3","addpay":false,"append":"c:\\xampp\\htdocs\\mosquitto\\sounds\\laser.mp3","useSpawn":"false","timer":"","oldrc":false,"name":"","x":670,"y":1040,"wires":[[],[],[]]},{"id":"9cfb23af.567d","type":"debug","z":"3627a10e.7a9c8e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":600,"y":1120,"wires":[]},{"id":"d5ec75c.fdb1488","type":"ui_button","z":"3627a10e.7a9c8e","name":"","group":"d9d089df.9ddee8","order":7,"width":0,"height":0,"passthru":false,"label":"Reset","tooltip":"","color":"","bgcolor":"","icon":"","payload":"reset","payloadType":"str","topic":"","x":110,"y":1020,"wires":[["5d1d3556.07aa1c","aef0b95e.ee0df8","5c2cd856.9729a8"]]},{"id":"e21be815.8f0ea8","type":"ui_button","z":"3627a10e.7a9c8e","name":"","group":"d9d089df.9ddee8","order":7,"width":0,"height":0,"passthru":false,"label":"Stop","tooltip":"","color":"","bgcolor":"","icon":"","payload":"stop","payloadType":"str","topic":"","x":70,"y":580,"wires":[["87d8c403.9987e8","ee79749d.3ac228"]]},{"id":"cc0f4c46.c819d","type":"ui_button","z":"3627a10e.7a9c8e","name":"","group":"d9d089df.9ddee8","order":7,"width":0,"height":0,"passthru":false,"label":"Start","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"date","topic":"","x":90,"y":40,"wires":[["f89d093d.090b08","63088a95.a6d624"]]},{"id":"e36485ee.59f3d8","type":"mqtt-broker","z":"","name":"","broker":"127.0.0.1","port":"1883","tls":"69ba6ca6.b34184","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"d9d089df.9ddee8","type":"ui_group","z":"","name":"Timer","tab":"3ae5cf15.e3feb","order":1,"disp":true,"width":"8","collapse":false},{"id":"69ba6ca6.b34184","type":"tls-config","z":"","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":false},{"id":"3ae5cf15.e3feb","type":"ui_tab","z":"","name":"Shooting Gallery","icon":"dashboard","disabled":false,"hidden":false}]