loading

Step 8: The Code

The Code


Code Notes:
I am not going to go into much detail about how the code works hopefully the fairly extensive comments provided in the code will be enough to explain it, if not the there are already good tutorials out there.

Limitations:
The code only works is set up in a way that it can only do one thing at a time and until the dual core arduino is easiest just to cope with that.
This means when one tagger is shooting it will not notice if it gets shot/tagged.  You could complicate the code by using interrupts , but in the real world it is not really a big problem, the shooting or getting shot happen so quickly that they very rarely interfere with each other.
In future iterations of the code I will probably make it so that the tagger checks to see if it has been tagged in-between each bit it transmits, making it very very unlikely that it would miss an incoming message (hit / tag). I have played a few games using this code and similar code and it seems to work well.

------------------------------------------------------------------------------------------------------------------


//      Start of code (copy and paste into arduino sketch)
//
//                       Duino Tag release V1.01
//          Laser Tag for the arduino based on the Miles Tag Protocol.
//           By J44industries:     www.J44industries.blogspot.com
// For information on building your own Duino Tagger go to: http://www.instructables.com/member/j44/
//
// Much credit deserves to go to Duane O'Brien if it had not been for the excellent Duino Tag tutorials he wrote I would have never been able to write this code.
// Duane's tutorials are highly recommended reading in order to gain a better understanding of the arduino and IR communication. See his site http://aterribleidea.com/duino-tag-resources/
//
// This code sets out the basics for arduino based laser tag system and tries to stick to the miles tag protocol where possible.
// Miles Tag details: http://www.lasertagparts.com/mtdesign.htm
// There is much scope for expanding the capabilities of this system, and hopefully the game will continue to evolve for some time to come.
// Licence: Attribution Share Alike: Give credit where credit is due, but you can do what you like with the code.
// If you have code improvements or additions please go to http://duinotag.blogspot.com
//



// Digital IO's
int triggerPin             = 3;      // Push button for primary fire. Low = pressed
int trigger2Pin            = 13;     // Push button for secondary fire. Low = pressed
int speakerPin             = 4;      // Direct output to piezo sounder/speaker
int audioPin               = 9;      // Audio Trigger. Can be used to set off sounds recorded in the kind of electronics you can get in greetings card that play a custom message.
int lifePin                = 6;      // An analogue output (PWM) level corresponds to remaining life. Use PWM pin: 3,5,6,9,10 or 11. Can be used to drive LED bar graphs. eg LM3914N
int ammoPin                = 5;      // An analogue output (PWM) level corresponds to remaining ammunition. Use PWM pin: 3,5,6,9,10 or 11.
int hitPin                 = 7;      // LED output pin used to indicate when the player has been hit.
int IRtransmitPin          = 2;      // Primary fire mode IR transmitter pin: Use pins 2,4,7,8,12 or 13. DO NOT USE PWM pins!! More info: http://j44industries.blogspot.com/2009/09/arduino-frequency-generation.html#more
int IRtransmit2Pin         = 8;      // Secondary fire mode IR transmitter pin:  Use pins 2,4,7,8,12 or 13. DO NOT USE PWM pins!!
int IRreceivePin           = 12;     // The pin that incoming IR signals are read from
int IRreceive2Pin          = 11;     // Allows for checking external sensors are attached as well as distinguishing between sensor locations (eg spotting head shots)
// Minimum gun requirements: trigger, receiver, IR led, hit LED.

// Player and Game details
int myTeamID               = 1;      // 1-7 (0 = system message)
int myPlayerID             = 5;      // Player ID
int myGameID               = 0;      // Interprited by configureGane subroutine; allows for quick change of game types.
int myWeaponID             = 0;      // Deffined by gameType and configureGame subroutine.
int myWeaponHP             = 0;      // Deffined by gameType and configureGame subroutine.
int maxAmmo                = 0;      // Deffined by gameType and configureGame subroutine.
int maxLife                = 0;      // Deffined by gameType and configureGame subroutine.
int automatic              = 0;      // Deffined by gameType and configureGame subroutine. Automatic fire 0 = Semi Auto, 1 = Fully Auto.
int automatic2             = 0;      // Deffined by gameType and configureGame subroutine. Secondary fire auto?

//Incoming signal Details
int received[18];                    // Received data: received[0] = which sensor, received[1] - [17] byte1 byte2 parity (Miles Tag structure)
int check                  = 0;      // Variable used in parity checking

// Stats
int ammo                   = 0;      // Current ammunition
int life                   = 0;      // Current life

// Code Variables
int timeOut                = 0;      // Deffined in frequencyCalculations (IRpulse + 50)
int FIRE                   = 0;      // 0 = don't fire, 1 = Primary Fire, 2 = Secondary Fire
int TR                     = 0;      // Trigger Reading
int LTR                    = 0;      // Last Trigger Reading
int T2R                    = 0;      // Trigger 2 Reading (For secondary fire)
int LT2R                   = 0;      // Last Trigger 2 Reading (For secondary fire)

// Signal Properties
int IRpulse                = 600;    // Basic pulse duration of 600uS MilesTag standard 4*IRpulse for header bit, 2*IRpulse for 1, 1*IRpulse for 0.
int IRfrequency            = 38;     // Frequency in kHz Standard values are: 38kHz, 40kHz. Choose dependant on your receiver characteristics
int IRt                    = 0;      // LED on time to give correct transmission frequency, calculated in setup.
int IRpulses               = 0;      // Number of oscillations needed to make a full IRpulse, calculated in setup.
int header                 = 4;      // Header lenght in pulses. 4 = Miles tag standard
int maxSPS                 = 10;     // Maximum Shots Per Seconds. Not yet used.
int TBS                    = 0;      // Time between shots. Not yet used.

// Transmission data
int byte1[8];                        // String for storing byte1 of the data which gets transmitted when the player fires.
int byte2[8];                        // String for storing byte1 of the data which gets transmitted when the player fires.
int myParity               = 0;      // String for storing parity of the data which gets transmitted when the player fires.

// Received data
int memory                 = 10;     // Number of signals to be recorded: Allows for the game data to be reviewed after the game, no provision for transmitting / accessing it yet though.
int hitNo                  = 0;      // Hit number
// Byte1
int player[10];                      // Array must be as large as memory
int team[10];                        // Array must be as large as memory
// Byte2
int weapon[10];                      // Array must be as large as memory
int hp[10];                          // Array must be as large as memory
int parity[10];                      // Array must be as large as memory


void setup() {
  // Serial coms set up to help with debugging.
  Serial.begin(9600);              
  Serial.println("Startup...");
  // Pin declarations
  pinMode(triggerPin, INPUT);
  pinMode(trigger2Pin, INPUT);
  pinMode(speakerPin, OUTPUT);
  pinMode(audioPin, OUTPUT);
  pinMode(lifePin, OUTPUT);
  pinMode(ammoPin, OUTPUT);
  pinMode(hitPin, OUTPUT);
  pinMode(IRtransmitPin, OUTPUT);
  pinMode(IRtransmit2Pin, OUTPUT);
  pinMode(IRreceivePin, INPUT);
  pinMode(IRreceive2Pin, INPUT);
 
  frequencyCalculations();   // Calculates pulse lengths etc for desired frequency
  configureGame();           // Look up and configure game details
  tagCode();                 // Based on game details etc works out the data that will be transmitted when a shot is fired
 
 
  digitalWrite(triggerPin, HIGH);      // Not really needed if your circuit has the correct pull up resistors already but doesn't harm
  digitalWrite(trigger2Pin, HIGH);     // Not really needed if your circuit has the correct pull up resistors already but doesn't harm
 
  for (int i = 1;i < 254;i++) { // Loop plays start up noise
    analogWrite(ammoPin, i);
    playTone((3000-9*i), 2);
  } 
 
  // Next 4 lines initialise the display LEDs
  analogWrite(ammoPin, ((int) ammo));
  analogWrite(lifePin, ((int) life));
  lifeDisplay();
  ammoDisplay();

  Serial.println("Ready....");
}


// Main loop most of the code is in the sub routines
void loop(){
  receiveIR();
  if(FIRE != 0){
    shoot();
    ammoDisplay();
  }
  triggers();
}


// SUB ROUTINES


void ammoDisplay() { // Updates Ammo LED output
  float ammoF;
  ammoF = (260/maxAmmo) * ammo;
  if(ammoF <= 0){ammoF = 0;}
  if(ammoF > 255){ammoF = 255;}
  analogWrite(ammoPin, ((int) ammoF));
}


void lifeDisplay() { // Updates Ammo LED output
  float lifeF;
  lifeF = (260/maxLife) * life;
  if(lifeF <= 0){lifeF = 0;}
  if(lifeF > 255){lifeF = 255;}
  analogWrite(lifePin, ((int) lifeF));



void receiveIR() { // Void checks for an incoming signal and decodes it if it sees one.
  int error = 0;
 
  if(digitalRead(IRreceivePin) == LOW){    // If the receive pin is low a signal is being received.
    digitalWrite(hitPin,HIGH);
    if(digitalRead(IRreceive2Pin) == LOW){ // Is the incoming signal being received by the head sensors?
      received[0] = 1;
    }
    else{
      received[0] = 0;
    }
   
    while(digitalRead(IRreceivePin) == LOW){
    }
    for(int i = 1; i <= 17; i++) {                        // Repeats several times to make sure the whole signal has been received
      received[i] = pulseIn(IRreceivePin, LOW, timeOut);  // pulseIn command waits for a pulse and then records its duration in microseconds.
    }
   
    Serial.print("sensor: ");                            // Prints if it was a head shot or not.
    Serial.print(received[0]); 
    Serial.print("...");
   
    for(int i = 1; i <= 17; i++) {  // Looks at each one of the received pulses
      int receivedTemp[18];
      receivedTemp[i] = 2;
      if(received[i] > (IRpulse - 200) &&  received[i] < (IRpulse + 200)) {receivedTemp[i] = 0;}                      // Works out from the pulse length if it was a data 1 or 0 that was received writes result to receivedTemp string
      if(received[i] > (IRpulse + IRpulse - 200) &&  received[i] < (IRpulse + IRpulse + 200)) {receivedTemp[i] = 1;}  // Works out from the pulse length if it was a data 1 or 0 that was received  
      received[i] = 3;                   // Wipes raw received data
      received[i] = receivedTemp[i];     // Inputs interpreted data
     
      Serial.print(" ");
      Serial.print(received[i]);         // Print interpreted data results
    }
    Serial.println("");                  // New line to tidy up printed results
   
    // Parity Check. Was the data received a valid signal?
    check = 0;
    for(int i = 1; i <= 16; i++) {
      if(received[i] == 1){check = check + 1;}
      if(received[i] == 2){error = 1;}
    }
    // Serial.println(check);
    check = check >> 0 & B1;
    // Serial.println(check);
    if(check != received[17]){error = 1;}
    if(error == 0){Serial.println("Valid Signal");}
    else{Serial.println("ERROR");}
    if(error == 0){interpritReceived();}
    digitalWrite(hitPin,LOW);
  }
}


void interpritReceived(){  // After a message has been received by the ReceiveIR subroutine this subroutine decidedes how it should react to the data
  if(hitNo == memory){hitNo = 0;} // hitNo sorts out where the data should be stored if statement means old data gets overwritten if too much is received
  team[hitNo] = 0;
  player[hitNo] = 0;
  weapon[hitNo] = 0;
  hp[hitNo] = 0;
  // Next few lines Effectivly converts the binary data into decimal
  // Im sure there must be a much more efficient way of doing this
  if(received[1] == 1){team[hitNo] = team[hitNo] + 4;}
  if(received[2] == 1){team[hitNo] = team[hitNo] + 2;}
  if(received[3] == 1){team[hitNo] = team[hitNo] + 1;} 

  if(received[4] == 1){player[hitNo] = player[hitNo] + 16;}
  if(received[5] == 1){player[hitNo] = player[hitNo] + 8;}
  if(received[6] == 1){player[hitNo] = player[hitNo] + 4;}
  if(received[7] == 1){player[hitNo] = player[hitNo] + 2;}
  if(received[8] == 1){player[hitNo] = player[hitNo] + 1;}
   
  if(received[9] == 1){weapon[hitNo] = weapon[hitNo] + 4;}
  if(received[10] == 1){weapon[hitNo] = weapon[hitNo] + 2;}
  if(received[11] == 1){weapon[hitNo] = weapon[hitNo] + 1;} 

  if(received[12] == 1){hp[hitNo] = hp[hitNo] + 16;}
  if(received[13] == 1){hp[hitNo] = hp[hitNo] + 8;}
  if(received[14] == 1){hp[hitNo] = hp[hitNo] + 4;}
  if(received[15] == 1){hp[hitNo] = hp[hitNo] + 2;}
  if(received[16] == 1){hp[hitNo] = hp[hitNo] + 1;}
   
  parity[hitNo] = received[17];

  Serial.print("Hit No: ");
  Serial.print(hitNo);
  Serial.print("  Player: ");
  Serial.print(player[hitNo]);
  Serial.print("  Team: ");
  Serial.print(team[hitNo]);
  Serial.print("  Weapon: ");
  Serial.print(weapon[hitNo]);
  Serial.print("  HP: ");
  Serial.print(hp[hitNo]);
  Serial.print("  Parity: ");
  Serial.println(parity[hitNo]);
 
 
  //This is probably where more code should be added to expand the game capabilities at the moment the code just checks that the received data was not a system message and deducts a life if it wasn't.
  if (player[hitNo] != 0){hit();}
  hitNo++ ;
}


void shoot() {
  if(FIRE == 1){ // Has the trigger been pressed?
    Serial.println("FIRE 1");
    sendPulse(IRtransmitPin, 4); // Transmit Header pulse, send pulse subroutine deals with the details
    delayMicroseconds(IRpulse);
 
    for(int i = 0; i < 8; i++) { // Transmit Byte1
      if(byte1[i] == 1){
        sendPulse(IRtransmitPin, 1);
        //Serial.print("1 ");
      }
      //else{Serial.print("0 ");}
      sendPulse(IRtransmitPin, 1);
      delayMicroseconds(IRpulse);
    }

    for(int i = 0; i < 8; i++) { // Transmit Byte2
      if(byte2[i] == 1){
        sendPulse(IRtransmitPin, 1);
       // Serial.print("1 ");
      }
      //else{Serial.print("0 ");}
      sendPulse(IRtransmitPin, 1);
      delayMicroseconds(IRpulse);
    }
    
    if(myParity == 1){ // Parity
      sendPulse(IRtransmitPin, 1);
    }
    sendPulse(IRtransmitPin, 1);
    delayMicroseconds(IRpulse);
    Serial.println("");
    Serial.println("DONE 1");
  }


  if(FIRE == 2){ // Where a secondary fire mode would be added
    Serial.println("FIRE 2");
    sendPulse(IRtransmitPin, 4); // Header
    Serial.println("DONE 2");
  }
FIRE = 0;
ammo = ammo - 1;
}


void sendPulse(int pin, int length){ // importing variables like this allows for secondary fire modes etc.
// This void genertates the carrier frequency for the information to be transmitted
  int i = 0;
  int o = 0;
  while( i < length ){
    i++;
    while( o < IRpulses ){
      o++;
      digitalWrite(pin, HIGH);
      delayMicroseconds(IRt);
      digitalWrite(pin, LOW);
      delayMicroseconds(IRt);
    }
  }
}


void triggers() { // Checks to see if the triggers have been presses
  LTR = TR;       // Records previous state. Primary fire
  LT2R = T2R;     // Records previous state. Secondary fire
  TR = digitalRead(triggerPin);      // Looks up current trigger button state
  T2R = digitalRead(trigger2Pin);    // Looks up current trigger button state
  // Code looks for changes in trigger state to give it a semi automatic shooting behaviour
  if(TR != LTR && TR == LOW){
    FIRE = 1;
  }
  if(T2R != LT2R && T2R == LOW){
    FIRE = 2;
  }
  if(TR == LOW && automatic == 1){
    FIRE = 1;
  }
  if(T2R == LOW && automatic2 == 1){
    FIRE = 2;
  }
  if(FIRE == 1 || FIRE == 2){
    if(ammo < 1){FIRE = 0; noAmmo();}
    if(life < 1){FIRE = 0; dead();}
    // Fire rate code to be added here  
  }
 
}


void configureGame() { // Where the game characteristics are stored, allows several game types to be recorded and you only have to change one variable (myGameID) to pick the game.
  if(myGameID == 0){
    myWeaponID = 1;
    maxAmmo = 30;
    ammo = 30;
    maxLife = 3;
    life = 3;
    myWeaponHP = 1;
  }
  if(myGameID == 1){
    myWeaponID = 1;
    maxAmmo = 100;
    ammo = 100;
    maxLife = 10;
    life = 10;
    myWeaponHP = 2;
  }
}


void frequencyCalculations() { // Works out all the timings needed to give the correct carrier frequency for the IR signal
  IRt = (int) (500/IRfrequency);  
  IRpulses = (int) (IRpulse / (2*IRt));
  IRt = IRt - 4;
  // Why -4 I hear you cry. It allows for the time taken for commands to be executed.
  // More info: http://j44industries.blogspot.com/2009/09/arduino-frequency-generation.html#more

  Serial.print("Oscilation time period /2: ");
  Serial.println(IRt);
  Serial.print("Pulses: ");
  Serial.println(IRpulses);
  timeOut = IRpulse + 50; // Adding 50 to the expected pulse time gives a little margin for error on the pulse read time out value
}


void tagCode() { // Works out what the players tagger code (the code that is transmitted when they shoot) is
  byte1[0] = myTeamID >> 2 & B1;
  byte1[1] = myTeamID >> 1 & B1;
  byte1[2] = myTeamID >> 0 & B1;

  byte1[3] = myPlayerID >> 4 & B1;
  byte1[4] = myPlayerID >> 3 & B1;
  byte1[5] = myPlayerID >> 2 & B1;
  byte1[6] = myPlayerID >> 1 & B1;
  byte1[7] = myPlayerID >> 0 & B1;


  byte2[0] = myWeaponID >> 2 & B1;
  byte2[1] = myWeaponID >> 1 & B1;
  byte2[2] = myWeaponID >> 0 & B1;

  byte2[3] = myWeaponHP >> 4 & B1;
  byte2[4] = myWeaponHP >> 3 & B1;
  byte2[5] = myWeaponHP >> 2 & B1;
  byte2[6] = myWeaponHP >> 1 & B1;
  byte2[7] = myWeaponHP >> 0 & B1;

  myParity = 0;
  for (int i=0; i<8; i++) {
   if(byte1[i] == 1){myParity = myParity + 1;}
   if(byte2[i] == 1){myParity = myParity + 1;}
   myParity = myParity >> 0 & B1;
  }

  // Next few lines print the full tagger code.
  Serial.print("Byte1: ");
  Serial.print(byte1[0]);
  Serial.print(byte1[1]);
  Serial.print(byte1[2]);
  Serial.print(byte1[3]);
  Serial.print(byte1[4]);
  Serial.print(byte1[5]);
  Serial.print(byte1[6]);
  Serial.print(byte1[7]);
  Serial.println();

  Serial.print("Byte2: ");
  Serial.print(byte2[0]);
  Serial.print(byte2[1]);
  Serial.print(byte2[2]);
  Serial.print(byte2[3]);
  Serial.print(byte2[4]);
  Serial.print(byte2[5]);
  Serial.print(byte2[6]);
  Serial.print(byte2[7]);
  Serial.println();

  Serial.print("Parity: ");
  Serial.print(myParity);
  Serial.println();
}


void playTone(int tone, int duration) { // A sub routine for playing tones like the standard arduino melody example
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}


void dead() { // void determines what the tagger does when it is out of lives
  // Makes a few noises and flashes some lights
  for (int i = 1;i < 254;i++) {
    analogWrite(ammoPin, i);
    playTone((1000+9*i), 2);
  } 
  analogWrite(ammoPin, ((int) ammo));
  analogWrite(lifePin, ((int) life));
  Serial.println("DEAD");
 
  for (int i=0; i<10; i++) {
   analogWrite(ammoPin, 255);
   digitalWrite(hitPin,HIGH);
   delay (500);
   analogWrite(ammoPin, 0);
   digitalWrite(hitPin,LOW);
   delay (500);
  }
}


void noAmmo() { // Make some noise and flash some lights when out of ammo
  digitalWrite(hitPin,HIGH);
  playTone(500, 100);
  playTone(1000, 100);
  digitalWrite(hitPin,LOW);
}


void hit() { // Make some noise and flash some lights when you get shot
  digitalWrite(hitPin,HIGH);
  life = life - hp[hitNo];
  Serial.print("Life: ");
  Serial.println(life);
  playTone(500, 500);
  if(life <= 0){dead();}
  digitalWrite(hitPin,LOW);
  lifeDisplay();
}


<p>Won't those 100mA IR lasers cut and burn anything? I am picking up a project of my own on this thing and nowhere can I find a good awnser to that question.</p>
<p>they aren't lasers, just regular ole led's with a lens to focus the light forward. they wont burn anything.</p>
<p>Aaaah well that helps so much! Thank you now I can finally continue my project. Just one question though could I make them as acurate as a laser?</p>
<p>You can use lenses to focus the light, or you could use a tube that is non reflective on the inside to &quot;cut&quot; the light to go straight out the end. Other than that, there are IR emitter LED's that have a very low viewing angle, so the light goes forwards.</p>
<p>Hello mate, I came upon your project very interesting, although i am 6 years too late and not sure if you still active on this account. Could you please share the Arduino code for servo activation when the IR is being fired upon ( Jdog Arduino). I would like to continue your project. I dont know a thing about coding so if you could help would be greatly appreciated. <br></p>
<p>what pin dose the ir LED go to ??</p>
<p>I'm looking to purchase a lazertag system to start a lazertag business, <br>would you be able to produce or lead me to the guns and equipment I need <br> that would be safe and certifiable, that would be a cheaper option than <br> the $600/gun price range that I've seen advertised by the lazertag <br>manufacturers? email if so at ulrichinvesting@gmail.com</p>
<p>Sorry im not really familiar with the commercial systems, and dont know of any cheaper alternatives. </p>
I uploaded the project in the Arduino 2560. <br>first problem: <br>ERROR <br>sensor: 1 ... 2 2 2 2 0 2 2 0 2 2 0 2 2 2 2 2 2 <br> <br>as Keanan, <br> <br>I followed the advice: <br> <br>Try removing timeOut paramter in le seguenti line of the code: <br> <br>received [i] = pulseIn (IRreceivePin, LOW, timeOut); <br> <br>and did not work, <br> <br>I changed the output pin of the IR, I put A2, and began to see the signal, <br>but sees alternately: <br>Ready .... <br>sensor: 0 ... 0 0 2 0 0 1 0 1 0 0 1 0 0 0 0 1 1 <br>ERROR <br>sensor: 0 ... 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 1 <br>Valid Signal <br>Hit No: 0 Player: 5 Team: 1 Weapon: 1 HP: 1 Parity: 1 <br>Life: 2 <br>sensor: 0 ... 0 0 2 0 0 2 0 2 0 0 2 0 0 0 0 1 1 <br>ERROR <br>sensor: 0 ... 0 0 2 0 0 2 0 2 0 0 1 0 0 0 0 1 1 <br>ERROR <br>sensor: 0 ... 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 1 <br>Valid Signal <br>Hit No: 1 Player: 5 Team: 1 Weapon: 1 HP: 1 Parity: 1 <br>Life: 1 <br>sensor: 0 ... 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 1 <br>Valid Signal <br>Hit No: 2 Player: 5 Team: 1 Weapon: 1 HP: 1 Parity: 1 <br>Life: 0 <br>DEAD <br> <br>What solution do you recommend?
I wrote this code for arduino 14 and quite a few of the functions seem to have changed since then. <br>I don't really have the time now to sit down and rewrite it but if you look through some of the comments below I have made a few suggestions as to what the problems might be.
Can I use Arduino Uno for this?
How compatible is this code with the Miles Tag Protocol? <br>I have loaded it onto an Arduino but when I shoot it with a device that is using the Miles Tag Protocol I just get &quot;ERROR&quot;. <br>If i use this code to shoot a Miles Tag Protocol based gun it does not register. <br> <br>Comparing the IR signals my shooting a unit running http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html <br>the code above gives a unknown signal type while the Miles Tag gun gives a Sony:17bit
How much will this project cost? I already have two Nerf guns I could gut.
Hi guys, <br> <br>I wanted to start on this project with an arduino nano and so i bought a light gun. Except this gun is rather complicated and has a recoil blowback feature. It looks extremely different to the one you have, and i dont know where to start =\. Im a total arduino noob and ive never done an arduino project before, but i was wondering whether it was possible to use the same IR firing internals without replacing the LED (because as you can see its the little silver box) as well as powering the recoil feature. From the picture you can see the wiring to the bottom, that is an actual laser pointer.
Hi. <br>And a big thank YOU for this instruction. Real good. <br>Gota try and make this myself and mabe add things.. Have done some Arduino codeing in past. <br>Thanks Again. <br>Hargard
I have tried these recommendations and the arduino receiving the IR code still can't see all of the IR code or not at all. Is there any other code that could work for simple two person tag that uses the same components?
//The following should respond to any IR signal<br><br>// Start of code (copy and paste into arduino sketch)<br>//<br>// Duino Tag release V1.01<br>// Laser Tag for the arduino based on the Miles Tag Protocol.<br>// By J44industries: www.J44industries.blogspot.com<br>// For information on building your own Duino Tagger go to: http://www.instructables.com/member/j44/<br>//<br>// Much credit deserves to go to Duane O'Brien if it had not been for the excellent Duino Tag tutorials he wrote I would have never been able to write this code.<br>// Duane's tutorials are highly recommended reading in order to gain a better understanding of the arduino and IR communication. See his site http://aterribleidea.com/duino-tag-resources/<br>//<br>// This code sets out the basics for arduino based laser tag system and tries to stick to the miles tag protocol where possible.<br>// Miles Tag details: http://www.lasertagparts.com/mtdesign.htm<br>// There is much scope for expanding the capabilities of this system, and hopefully the game will continue to evolve for some time to come.<br>// Licence: Attribution Share Alike: Give credit where credit is due, but you can do what you like with the code.<br>// If you have code improvements or additions please go to http://duinotag.blogspot.com<br>//<br><br>// Digital IO's<br>int triggerPin = 3; // Push button for primary fire. Low = pressed<br>int trigger2Pin = 13; // Push button for secondary fire. Low = pressed<br>int speakerPin = 4; // Direct output to piezo sounder/speaker<br>int audioPin = 9; // Audio Trigger. Can be used to set off sounds recorded in the kind of electronics you can get in greetings card that play a custom message.<br>int lifePin = 6; // An analogue output (PWM) level corresponds to remaining life. Use PWM pin: 3,5,6,9,10 or 11. Can be used to drive LED bar graphs. eg LM3914N<br>int ammoPin = 5; // An analogue output (PWM) level corresponds to remaining ammunition. Use PWM pin: 3,5,6,9,10 or 11.<br>int hitPin = 7; // LED output pin used to indicate when the player has been hit.<br>int IRtransmitPin = 2; // Primary fire mode IR transmitter pin: Use pins 2,4,7,8,12 or 13. DO NOT USE PWM pins!! More info: http://j44industries.blogspot.com/2009/09/arduino-frequency-generation.html#more<br>int IRtransmit2Pin = 8; // Secondary fire mode IR transmitter pin: Use pins 2,4,7,8,12 or 13. DO NOT USE PWM pins!!<br>int IRreceivePin = 12; // The pin that incoming IR signals are read from<br>int IRreceive2Pin = 11; // Allows for checking external sensors are attached as well as distinguishing between sensor locations (eg spotting head shots)<br>// Minimum gun requirements: trigger, receiver, IR led, hit LED.<br><br>// Player and Game details<br>int myTeamID = 1; // 1-7 (0 = system message)<br>int myPlayerID = 5; // Player ID<br>int myGameID = 0; // Interprited by configureGane subroutine; allows for quick change of game types.<br>int myWeaponID = 0; // Deffined by gameType and configureGame subroutine.<br>int myWeaponHP = 0; // Deffined by gameType and configureGame subroutine.<br>int maxAmmo = 0; // Deffined by gameType and configureGame subroutine.<br>int maxLife = 0; // Deffined by gameType and configureGame subroutine.<br>int automatic = 0; // Deffined by gameType and configureGame subroutine. Automatic fire 0 = Semi Auto, 1 = Fully Auto.<br>int automatic2 = 0; // Deffined by gameType and configureGame subroutine. Secondary fire auto?<br><br>//Incoming signal Details<br>int received[18]; // Received data: received[0] = which sensor, received[1] - [17] byte1 byte2 parity (Miles Tag structure)<br>int check = 0; // Variable used in parity checking<br><br>// Stats<br>int ammo = 0; // Current ammunition<br>int life = 0; // Current life<br><br>// Code Variables<br>int timeOut = 0; // Deffined in frequencyCalculations (IRpulse + 50)<br>int FIRE = 0; // 0 = don't fire, 1 = Primary Fire, 2 = Secondary Fire<br>int TR = 0; // Trigger Reading<br>int LTR = 0; // Last Trigger Reading<br>int T2R = 0; // Trigger 2 Reading (For secondary fire)<br>int LT2R = 0; // Last Trigger 2 Reading (For secondary fire)<br><br>// Signal Properties<br>int IRpulse = 600; // Basic pulse duration of 600uS MilesTag standard 4*IRpulse for header bit, 2*IRpulse for 1, 1*IRpulse for 0.<br>int IRfrequency = 38; // Frequency in kHz Standard values are: 38kHz, 40kHz. Choose dependant on your receiver characteristics<br>int IRt = 0; // LED on time to give correct transmission frequency, calculated in setup.<br>int IRpulses = 0; // Number of oscillations needed to make a full IRpulse, calculated in setup.<br>int header = 4; // Header lenght in pulses. 4 = Miles tag standard<br>int maxSPS = 10; // Maximum Shots Per Seconds. Not yet used.<br>int TBS = 0; // Time between shots. Not yet used.<br><br>// Transmission data<br>int byte1[8]; // String for storing byte1 of the data which gets transmitted when the player fires.<br>int byte2[8]; // String for storing byte1 of the data which gets transmitted when the player fires.<br>int myParity = 0; // String for storing parity of the data which gets transmitted when the player fires.<br><br>// Received data<br>int memory = 10; // Number of signals to be recorded: Allows for the game data to be reviewed after the game, no provision for transmitting / accessing it yet though.<br>int hitNo = 0; // Hit number<br>// Byte1<br>int player[10]; // Array must be as large as memory<br>int team[10]; // Array must be as large as memory<br>// Byte2<br>int weapon[10]; // Array must be as large as memory<br>int hp[10]; // Array must be as large as memory<br>int parity[10]; // Array must be as large as memory<br><br><br>void setup() {<br> // Serial coms set up to help with debugging.<br> Serial.begin(9600); <br> Serial.println(&quot;Startup...&quot;);<br> // Pin declarations<br> pinMode(triggerPin, INPUT);<br> pinMode(trigger2Pin, INPUT);<br> pinMode(speakerPin, OUTPUT);<br> pinMode(audioPin, OUTPUT);<br> pinMode(lifePin, OUTPUT);<br> pinMode(ammoPin, OUTPUT);<br> pinMode(hitPin, OUTPUT);<br> pinMode(IRtransmitPin, OUTPUT);<br> pinMode(IRtransmit2Pin, OUTPUT);<br> pinMode(IRreceivePin, INPUT);<br> pinMode(IRreceive2Pin, INPUT);<br> <br> frequencyCalculations(); // Calculates pulse lengths etc for desired frequency<br> configureGame(); // Look up and configure game details<br> tagCode(); // Based on game details etc works out the data that will be transmitted when a shot is fired<br> <br> <br> digitalWrite(triggerPin, HIGH); // Not really needed if your circuit has the correct pull up resistors already but doesn't harm<br> digitalWrite(trigger2Pin, HIGH); // Not really needed if your circuit has the correct pull up resistors already but doesn't harm<br> <br> for (int i = 1;i &lt; 254;i++) { // Loop plays start up noise<br> analogWrite(ammoPin, i);<br> playTone((3000-9*i), 2);<br> } <br> <br> // Next 4 lines initialise the display LEDs<br> analogWrite(ammoPin, ((int) ammo));<br> analogWrite(lifePin, ((int) life));<br> lifeDisplay();<br> ammoDisplay();<br><br> Serial.println(&quot;Ready....&quot;);<br>}<br><br><br>// Main loop most of the code is in the sub routines<br>void loop(){<br> receiveIR();<br> if(FIRE != 0){<br> shoot();<br> ammoDisplay();<br> }<br> triggers();<br>}<br><br><br>// SUB ROUTINES<br><br><br>void ammoDisplay() { // Updates Ammo LED output<br> float ammoF;<br> ammoF = (260/maxAmmo) * ammo;<br> if(ammoF &lt;= 0){ammoF = 0;}<br> if(ammoF &gt; 255){ammoF = 255;}<br> analogWrite(ammoPin, ((int) ammoF));<br>}<br><br><br>void lifeDisplay() { // Updates Ammo LED output<br> float lifeF;<br> lifeF = (260/maxLife) * life;<br> if(lifeF &lt;= 0){lifeF = 0;}<br> if(lifeF &gt; 255){lifeF = 255;}<br> analogWrite(lifePin, ((int) lifeF));<br>} <br><br><br>void receiveIR() { // Void checks for an incoming signal and decodes it if it sees one.<br><br> if(digitalRead(IRreceivePin) == LOW){ // If the receive pin is low a signal is being received.<br> digitalWrite(hitPin,HIGH);<br> hit();<br> }<br>}<br><br>void shoot() {<br> if(FIRE == 1){ // Has the trigger been pressed?<br> Serial.println(&quot;FIRE 1&quot;);<br> sendPulse(IRtransmitPin, 4); // Transmit Header pulse, send pulse subroutine deals with the details<br> delayMicroseconds(IRpulse);<br> <br> for(int i = 0; i &lt; 8; i++) { // Transmit Byte1<br> if(byte1[i] == 1){<br> sendPulse(IRtransmitPin, 1);<br> //Serial.print(&quot;1 &quot;);<br> }<br> //else{Serial.print(&quot;0 &quot;);}<br> sendPulse(IRtransmitPin, 1);<br> delayMicroseconds(IRpulse);<br> }<br><br> for(int i = 0; i &lt; 8; i++) { // Transmit Byte2<br> if(byte2[i] == 1){<br> sendPulse(IRtransmitPin, 1);<br> // Serial.print(&quot;1 &quot;);<br> }<br> //else{Serial.print(&quot;0 &quot;);}<br> sendPulse(IRtransmitPin, 1);<br> delayMicroseconds(IRpulse);<br> }<br> <br> if(myParity == 1){ // Parity<br> sendPulse(IRtransmitPin, 1);<br> }<br> sendPulse(IRtransmitPin, 1);<br> delayMicroseconds(IRpulse);<br> Serial.println(&quot;&quot;);<br> Serial.println(&quot;DONE 1&quot;);<br> }<br><br><br> if(FIRE == 2){ // Where a secondary fire mode would be added<br> Serial.println(&quot;FIRE 2&quot;);<br> sendPulse(IRtransmitPin, 4); // Header<br> Serial.println(&quot;DONE 2&quot;);<br> }<br>FIRE = 0;<br>ammo = ammo - 1;<br>}<br><br><br>void sendPulse(int pin, int length){ // importing variables like this allows for secondary fire modes etc.<br>// This void genertates the carrier frequency for the information to be transmitted<br> int i = 0;<br> int o = 0;<br> while( i &lt; length ){<br> i++;<br> while( o &lt; IRpulses ){<br> o++;<br> digitalWrite(pin, HIGH);<br> delayMicroseconds(IRt);<br> digitalWrite(pin, LOW);<br> delayMicroseconds(IRt);<br> }<br> }<br>}<br><br><br>void triggers() { // Checks to see if the triggers have been presses<br> LTR = TR; // Records previous state. Primary fire<br> LT2R = T2R; // Records previous state. Secondary fire<br> TR = digitalRead(triggerPin); // Looks up current trigger button state<br> T2R = digitalRead(trigger2Pin); // Looks up current trigger button state<br> // Code looks for changes in trigger state to give it a semi automatic shooting behaviour<br> if(TR != LTR &amp;&amp; TR == LOW){<br> FIRE = 1;<br> }<br> if(T2R != LT2R &amp;&amp; T2R == LOW){<br> FIRE = 2;<br> }<br> if(TR == LOW &amp;&amp; automatic == 1){<br> FIRE = 1;<br> }<br> if(T2R == LOW &amp;&amp; automatic2 == 1){<br> FIRE = 2;<br> }<br> if(FIRE == 1 || FIRE == 2){<br> if(ammo &lt; 1){FIRE = 0; noAmmo();}<br> if(life &lt; 1){FIRE = 0; dead();}<br> // Fire rate code to be added here <br> }<br> <br>}<br><br><br>void configureGame() { // Where the game characteristics are stored, allows several game types to be recorded and you only have to change one variable (myGameID) to pick the game.<br> if(myGameID == 0){<br> myWeaponID = 1;<br> maxAmmo = 30;<br> ammo = 30;<br> maxLife = 3;<br> life = 3;<br> myWeaponHP = 1;<br> }<br> if(myGameID == 1){<br> myWeaponID = 1;<br> maxAmmo = 100;<br> ammo = 100;<br> maxLife = 10;<br> life = 10;<br> myWeaponHP = 2;<br> }<br>}<br><br><br>void frequencyCalculations() { // Works out all the timings needed to give the correct carrier frequency for the IR signal<br> IRt = (int) (500/IRfrequency); <br> IRpulses = (int) (IRpulse / (2*IRt));<br> IRt = IRt - 4;<br> // Why -4 I hear you cry. It allows for the time taken for commands to be executed.<br> // More info: http://j44industries.blogspot.com/2009/09/arduino-frequency-generation.html#more<br><br> Serial.print(&quot;Oscilation time period /2: &quot;);<br> Serial.println(IRt);<br> Serial.print(&quot;Pulses: &quot;);<br> Serial.println(IRpulses);<br> timeOut = IRpulse + 50; // Adding 50 to the expected pulse time gives a little margin for error on the pulse read time out value<br>}<br><br><br>void tagCode() { // Works out what the players tagger code (the code that is transmitted when they shoot) is<br> byte1[0] = myTeamID &gt;&gt; 2 &amp; B1;<br> byte1[1] = myTeamID &gt;&gt; 1 &amp; B1;<br> byte1[2] = myTeamID &gt;&gt; 0 &amp; B1;<br><br> byte1[3] = myPlayerID &gt;&gt; 4 &amp; B1;<br> byte1[4] = myPlayerID &gt;&gt; 3 &amp; B1;<br> byte1[5] = myPlayerID &gt;&gt; 2 &amp; B1;<br> byte1[6] = myPlayerID &gt;&gt; 1 &amp; B1;<br> byte1[7] = myPlayerID &gt;&gt; 0 &amp; B1;<br><br><br> byte2[0] = myWeaponID &gt;&gt; 2 &amp; B1;<br> byte2[1] = myWeaponID &gt;&gt; 1 &amp; B1;<br> byte2[2] = myWeaponID &gt;&gt; 0 &amp; B1;<br><br> byte2[3] = myWeaponHP &gt;&gt; 4 &amp; B1;<br> byte2[4] = myWeaponHP &gt;&gt; 3 &amp; B1;<br> byte2[5] = myWeaponHP &gt;&gt; 2 &amp; B1;<br> byte2[6] = myWeaponHP &gt;&gt; 1 &amp; B1;<br> byte2[7] = myWeaponHP &gt;&gt; 0 &amp; B1;<br><br> myParity = 0;<br> for (int i=0; i&lt;8; i++) {<br> if(byte1[i] == 1){myParity = myParity + 1;}<br> if(byte2[i] == 1){myParity = myParity + 1;}<br> myParity = myParity &gt;&gt; 0 &amp; B1;<br> }<br><br> // Next few lines print the full tagger code.<br> Serial.print(&quot;Byte1: &quot;);<br> Serial.print(byte1[0]);<br> Serial.print(byte1[1]);<br> Serial.print(byte1[2]);<br> Serial.print(byte1[3]);<br> Serial.print(byte1[4]);<br> Serial.print(byte1[5]);<br> Serial.print(byte1[6]);<br> Serial.print(byte1[7]);<br> Serial.println();<br><br> Serial.print(&quot;Byte2: &quot;);<br> Serial.print(byte2[0]);<br> Serial.print(byte2[1]);<br> Serial.print(byte2[2]);<br> Serial.print(byte2[3]);<br> Serial.print(byte2[4]);<br> Serial.print(byte2[5]);<br> Serial.print(byte2[6]);<br> Serial.print(byte2[7]);<br> Serial.println();<br><br> Serial.print(&quot;Parity: &quot;);<br> Serial.print(myParity);<br> Serial.println();<br>}<br><br><br>void playTone(int atone, int duration) { // A sub routine for playing tones like the standard arduino melody example<br> for (long i = 0; i &lt; duration * 1000L; i += atone * 2) {<br> digitalWrite(speakerPin, HIGH);<br> delayMicroseconds(atone);<br> digitalWrite(speakerPin, LOW);<br> delayMicroseconds(atone);<br> }<br>}<br><br><br>void dead() { // void determines what the tagger does when it is out of lives<br> // Makes a few noises and flashes some lights<br> for (int i = 1;i &lt; 254;i++) {<br> analogWrite(ammoPin, i);<br> playTone((1000+9*i), 2);<br> } <br> analogWrite(ammoPin, ((int) ammo));<br> analogWrite(lifePin, ((int) life));<br> Serial.println(&quot;DEAD&quot;);<br> <br> for (int i=0; i&lt;10; i++) {<br> analogWrite(ammoPin, 255);<br> digitalWrite(hitPin,HIGH);<br> delay (500);<br> analogWrite(ammoPin, 0);<br> digitalWrite(hitPin,LOW);<br> delay (500);<br> }<br>}<br><br><br>void noAmmo() { // Make some noise and flash some lights when out of ammo<br> digitalWrite(hitPin,HIGH);<br> playTone(500, 100);<br> playTone(1000, 100);<br> digitalWrite(hitPin,LOW);<br>}<br><br><br>void hit() { // Make some noise and flash some lights when you get shot<br> digitalWrite(hitPin,HIGH);<br> life = life - 1;<br> Serial.print(&quot;Life: &quot;);<br> Serial.println(life);<br> playTone(500, 500);<br> if(life &lt;= 0){dead();}<br> digitalWrite(hitPin,LOW);<br> lifeDisplay();<br>}
This code is work for me, other not.
//The following code has a slight modification to the tone function which may have solved a potential problem, so might be worth a try, I will also post some simpler code in a minute<br><br>// Start of code (copy and paste into arduino sketch)<br>//<br>// Duino Tag release V1.01<br>// Laser Tag for the arduino based on the Miles Tag Protocol.<br>// By J44industries: www.J44industries.blogspot.com<br>// For information on building your own Duino Tagger go to: http://www.instructables.com/member/j44/<br>//<br>// Much credit deserves to go to Duane O'Brien if it had not been for the excellent Duino Tag tutorials he wrote I would have never been able to write this code.<br>// Duane's tutorials are highly recommended reading in order to gain a better understanding of the arduino and IR communication. See his site http://aterribleidea.com/duino-tag-resources/<br>//<br>// This code sets out the basics for arduino based laser tag system and tries to stick to the miles tag protocol where possible.<br>// Miles Tag details: http://www.lasertagparts.com/mtdesign.htm<br>// There is much scope for expanding the capabilities of this system, and hopefully the game will continue to evolve for some time to come.<br>// Licence: Attribution Share Alike: Give credit where credit is due, but you can do what you like with the code.<br>// If you have code improvements or additions please go to http://duinotag.blogspot.com<br>//<br><br>// Digital IO's<br>int triggerPin = 3; // Push button for primary fire. Low = pressed<br>int trigger2Pin = 13; // Push button for secondary fire. Low = pressed<br>int speakerPin = 4; // Direct output to piezo sounder/speaker<br>int audioPin = 9; // Audio Trigger. Can be used to set off sounds recorded in the kind of electronics you can get in greetings card that play a custom message.<br>int lifePin = 6; // An analogue output (PWM) level corresponds to remaining life. Use PWM pin: 3,5,6,9,10 or 11. Can be used to drive LED bar graphs. eg LM3914N<br>int ammoPin = 5; // An analogue output (PWM) level corresponds to remaining ammunition. Use PWM pin: 3,5,6,9,10 or 11.<br>int hitPin = 7; // LED output pin used to indicate when the player has been hit.<br>int IRtransmitPin = 2; // Primary fire mode IR transmitter pin: Use pins 2,4,7,8,12 or 13. DO NOT USE PWM pins!! More info: http://j44industries.blogspot.com/2009/09/arduino-frequency-generation.html#more<br>int IRtransmit2Pin = 8; // Secondary fire mode IR transmitter pin: Use pins 2,4,7,8,12 or 13. DO NOT USE PWM pins!!<br>int IRreceivePin = 12; // The pin that incoming IR signals are read from<br>int IRreceive2Pin = 11; // Allows for checking external sensors are attached as well as distinguishing between sensor locations (eg spotting head shots)<br>// Minimum gun requirements: trigger, receiver, IR led, hit LED.<br><br>// Player and Game details<br>int myTeamID = 1; // 1-7 (0 = system message)<br>int myPlayerID = 5; // Player ID<br>int myGameID = 0; // Interprited by configureGane subroutine; allows for quick change of game types.<br>int myWeaponID = 0; // Deffined by gameType and configureGame subroutine.<br>int myWeaponHP = 0; // Deffined by gameType and configureGame subroutine.<br>int maxAmmo = 0; // Deffined by gameType and configureGame subroutine.<br>int maxLife = 0; // Deffined by gameType and configureGame subroutine.<br>int automatic = 0; // Deffined by gameType and configureGame subroutine. Automatic fire 0 = Semi Auto, 1 = Fully Auto.<br>int automatic2 = 0; // Deffined by gameType and configureGame subroutine. Secondary fire auto?<br><br>//Incoming signal Details<br>int received[18]; // Received data: received[0] = which sensor, received[1] - [17] byte1 byte2 parity (Miles Tag structure)<br>int check = 0; // Variable used in parity checking<br><br>// Stats<br>int ammo = 0; // Current ammunition<br>int life = 0; // Current life<br><br>// Code Variables<br>int timeOut = 0; // Deffined in frequencyCalculations (IRpulse + 50)<br>int FIRE = 0; // 0 = don't fire, 1 = Primary Fire, 2 = Secondary Fire<br>int TR = 0; // Trigger Reading<br>int LTR = 0; // Last Trigger Reading<br>int T2R = 0; // Trigger 2 Reading (For secondary fire)<br>int LT2R = 0; // Last Trigger 2 Reading (For secondary fire)<br><br>// Signal Properties<br>int IRpulse = 600; // Basic pulse duration of 600uS MilesTag standard 4*IRpulse for header bit, 2*IRpulse for 1, 1*IRpulse for 0.<br>int IRfrequency = 56; // Frequency in kHz Standard values are: 38kHz, 40kHz. Choose dependant on your receiver characteristics<br>int IRt = 0; // LED on time to give correct transmission frequency, calculated in setup.<br>int IRpulses = 0; // Number of oscillations needed to make a full IRpulse, calculated in setup.<br>int header = 4; // Header lenght in pulses. 4 = Miles tag standard<br>int maxSPS = 10; // Maximum Shots Per Seconds. Not yet used.<br>int TBS = 0; // Time between shots. Not yet used.<br><br>// Transmission data<br>int byte1[8]; // String for storing byte1 of the data which gets transmitted when the player fires.<br>int byte2[8]; // String for storing byte1 of the data which gets transmitted when the player fires.<br>int myParity = 0; // String for storing parity of the data which gets transmitted when the player fires.<br><br>// Received data<br>int memory = 10; // Number of signals to be recorded: Allows for the game data to be reviewed after the game, no provision for transmitting / accessing it yet though.<br>int hitNo = 0; // Hit number<br>// Byte1<br>int player[10]; // Array must be as large as memory<br>int team[10]; // Array must be as large as memory<br>// Byte2<br>int weapon[10]; // Array must be as large as memory<br>int hp[10]; // Array must be as large as memory<br>int parity[10]; // Array must be as large as memory<br><br><br>void setup() {<br> // Serial coms set up to help with debugging.<br> Serial.begin(9600); <br> Serial.println(&quot;Startup...&quot;);<br> // Pin declarations<br> pinMode(triggerPin, INPUT);<br> pinMode(trigger2Pin, INPUT);<br> pinMode(speakerPin, OUTPUT);<br> pinMode(audioPin, OUTPUT);<br> pinMode(lifePin, OUTPUT);<br> pinMode(ammoPin, OUTPUT);<br> pinMode(hitPin, OUTPUT);<br> pinMode(IRtransmitPin, OUTPUT);<br> pinMode(IRtransmit2Pin, OUTPUT);<br> pinMode(IRreceivePin, INPUT);<br> pinMode(IRreceive2Pin, INPUT);<br> <br> frequencyCalculations(); // Calculates pulse lengths etc for desired frequency<br> configureGame(); // Look up and configure game details<br> tagCode(); // Based on game details etc works out the data that will be transmitted when a shot is fired<br> <br> <br> digitalWrite(triggerPin, HIGH); // Not really needed if your circuit has the correct pull up resistors already but doesn't harm<br> digitalWrite(trigger2Pin, HIGH); // Not really needed if your circuit has the correct pull up resistors already but doesn't harm<br> <br> for (int i = 1;i &lt; 254;i++) { // Loop plays start up noise<br> analogWrite(ammoPin, i);<br> playTone((3000-9*i), 2);<br> } <br> <br> // Next 4 lines initialise the display LEDs<br> analogWrite(ammoPin, ((int) ammo));<br> analogWrite(lifePin, ((int) life));<br> lifeDisplay();<br> ammoDisplay();<br><br> Serial.println(&quot;Ready....&quot;);<br>}<br><br><br>// Main loop most of the code is in the sub routines<br>void loop(){<br> receiveIR();<br> if(FIRE != 0){<br> shoot();<br> ammoDisplay();<br> }<br> triggers();<br>}<br><br><br>// SUB ROUTINES<br><br><br>void ammoDisplay() { // Updates Ammo LED output<br> float ammoF;<br> ammoF = (260/maxAmmo) * ammo;<br> if(ammoF &lt;= 0){ammoF = 0;}<br> if(ammoF &gt; 255){ammoF = 255;}<br> analogWrite(ammoPin, ((int) ammoF));<br>}<br><br><br>void lifeDisplay() { // Updates Ammo LED output<br> float lifeF;<br> lifeF = (260/maxLife) * life;<br> if(lifeF &lt;= 0){lifeF = 0;}<br> if(lifeF &gt; 255){lifeF = 255;}<br> analogWrite(lifePin, ((int) lifeF));<br>} <br><br><br>void receiveIR() { // Void checks for an incoming signal and decodes it if it sees one.<br> int error = 0;<br> <br> if(digitalRead(IRreceivePin) == LOW){ // If the receive pin is low a signal is being received.<br> digitalWrite(hitPin,HIGH);<br> if(digitalRead(IRreceive2Pin) == LOW){ // Is the incoming signal being received by the head sensors?<br> received[0] = 1;<br> }<br> else{<br> received[0] = 0;<br> }<br> <br> while(digitalRead(IRreceivePin) == LOW){<br> }<br> for(int i = 1; i &lt;= 17; i++) { // Repeats several times to make sure the whole signal has been received<br> received[i] = pulseIn(IRreceivePin, LOW, timeOut); // pulseIn command waits for a pulse and then records its duration in microseconds.<br> }<br> <br> Serial.print(&quot;sensor: &quot;); // Prints if it was a head shot or not.<br> Serial.print(received[0]); <br> Serial.print(&quot;...&quot;);<br> <br> for(int i = 1; i &lt;= 17; i++) { // Looks at each one of the received pulses<br> int receivedTemp[18];<br> receivedTemp[i] = 2;<br> if(received[i] &gt; (IRpulse - 200) &amp;&amp; received[i] &lt; (IRpulse + 200)) {receivedTemp[i] = 0;} // Works out from the pulse length if it was a data 1 or 0 that was received writes result to receivedTemp string<br> if(received[i] &gt; (IRpulse + IRpulse - 200) &amp;&amp; received[i] &lt; (IRpulse + IRpulse + 200)) {receivedTemp[i] = 1;} // Works out from the pulse length if it was a data 1 or 0 that was received <br> received[i] = 3; // Wipes raw received data<br> received[i] = receivedTemp[i]; // Inputs interpreted data<br> <br> Serial.print(&quot; &quot;);<br> Serial.print(received[i]); // Print interpreted data results<br> }<br> Serial.println(&quot;&quot;); // New line to tidy up printed results<br> <br> // Parity Check. Was the data received a valid signal?<br> check = 0;<br> for(int i = 1; i &lt;= 16; i++) {<br> if(received[i] == 1){check = check + 1;}<br> if(received[i] == 2){error = 1;}<br> }<br> // Serial.println(check);<br> check = check &gt;&gt; 0 &amp; B1;<br> // Serial.println(check);<br> if(check != received[17]){error = 1;}<br> if(error == 0){Serial.println(&quot;Valid Signal&quot;);}<br> else{Serial.println(&quot;ERROR&quot;);}<br> if(error == 0){interpritReceived();}<br> digitalWrite(hitPin,LOW);<br> }<br>}<br><br><br>void interpritReceived(){ // After a message has been received by the ReceiveIR subroutine this subroutine decidedes how it should react to the data<br> if(hitNo == memory){hitNo = 0;} // hitNo sorts out where the data should be stored if statement means old data gets overwritten if too much is received<br> team[hitNo] = 0;<br> player[hitNo] = 0;<br> weapon[hitNo] = 0;<br> hp[hitNo] = 0;<br> // Next few lines Effectivly converts the binary data into decimal<br> // Im sure there must be a much more efficient way of doing this<br> if(received[1] == 1){team[hitNo] = team[hitNo] + 4;}<br> if(received[2] == 1){team[hitNo] = team[hitNo] + 2;}<br> if(received[3] == 1){team[hitNo] = team[hitNo] + 1;} <br><br> if(received[4] == 1){player[hitNo] = player[hitNo] + 16;}<br> if(received[5] == 1){player[hitNo] = player[hitNo] + 8;}<br> if(received[6] == 1){player[hitNo] = player[hitNo] + 4;}<br> if(received[7] == 1){player[hitNo] = player[hitNo] + 2;}<br> if(received[8] == 1){player[hitNo] = player[hitNo] + 1;}<br> <br> if(received[9] == 1){weapon[hitNo] = weapon[hitNo] + 4;}<br> if(received[10] == 1){weapon[hitNo] = weapon[hitNo] + 2;}<br> if(received[11] == 1){weapon[hitNo] = weapon[hitNo] + 1;} <br><br> if(received[12] == 1){hp[hitNo] = hp[hitNo] + 16;}<br> if(received[13] == 1){hp[hitNo] = hp[hitNo] + 8;}<br> if(received[14] == 1){hp[hitNo] = hp[hitNo] + 4;}<br> if(received[15] == 1){hp[hitNo] = hp[hitNo] + 2;}<br> if(received[16] == 1){hp[hitNo] = hp[hitNo] + 1;}<br> <br> parity[hitNo] = received[17];<br><br> Serial.print(&quot;Hit No: &quot;);<br> Serial.print(hitNo);<br> Serial.print(&quot; Player: &quot;);<br> Serial.print(player[hitNo]);<br> Serial.print(&quot; Team: &quot;);<br> Serial.print(team[hitNo]);<br> Serial.print(&quot; Weapon: &quot;);<br> Serial.print(weapon[hitNo]);<br> Serial.print(&quot; HP: &quot;);<br> Serial.print(hp[hitNo]);<br> Serial.print(&quot; Parity: &quot;);<br> Serial.println(parity[hitNo]);<br> <br> <br> //This is probably where more code should be added to expand the game capabilities at the moment the code just checks that the received data was not a system message and deducts a life if it wasn't.<br> if (player[hitNo] != 0){hit();}<br> hitNo++ ;<br>}<br><br><br>void shoot() {<br> if(FIRE == 1){ // Has the trigger been pressed?<br> Serial.println(&quot;FIRE 1&quot;);<br> sendPulse(IRtransmitPin, 4); // Transmit Header pulse, send pulse subroutine deals with the details<br> delayMicroseconds(IRpulse);<br> <br> for(int i = 0; i &lt; 8; i++) { // Transmit Byte1<br> if(byte1[i] == 1){<br> sendPulse(IRtransmitPin, 1);<br> //Serial.print(&quot;1 &quot;);<br> }<br> //else{Serial.print(&quot;0 &quot;);}<br> sendPulse(IRtransmitPin, 1);<br> delayMicroseconds(IRpulse);<br> }<br><br> for(int i = 0; i &lt; 8; i++) { // Transmit Byte2<br> if(byte2[i] == 1){<br> sendPulse(IRtransmitPin, 1);<br> // Serial.print(&quot;1 &quot;);<br> }<br> //else{Serial.print(&quot;0 &quot;);}<br> sendPulse(IRtransmitPin, 1);<br> delayMicroseconds(IRpulse);<br> }<br> <br> if(myParity == 1){ // Parity<br> sendPulse(IRtransmitPin, 1);<br> }<br> sendPulse(IRtransmitPin, 1);<br> delayMicroseconds(IRpulse);<br> Serial.println(&quot;&quot;);<br> Serial.println(&quot;DONE 1&quot;);<br> }<br><br><br> if(FIRE == 2){ // Where a secondary fire mode would be added<br> Serial.println(&quot;FIRE 2&quot;);<br> sendPulse(IRtransmitPin, 4); // Header<br> Serial.println(&quot;DONE 2&quot;);<br> }<br>FIRE = 0;<br>ammo = ammo - 1;<br>}<br><br><br>void sendPulse(int pin, int length){ // importing variables like this allows for secondary fire modes etc.<br>// This void genertates the carrier frequency for the information to be transmitted<br> int i = 0;<br> int o = 0;<br> while( i &lt; length ){<br> i++;<br> while( o &lt; IRpulses ){<br> o++;<br> digitalWrite(pin, HIGH);<br> delayMicroseconds(IRt);<br> digitalWrite(pin, LOW);<br> delayMicroseconds(IRt);<br> }<br> }<br>}<br><br><br>void triggers() { // Checks to see if the triggers have been presses<br> LTR = TR; // Records previous state. Primary fire<br> LT2R = T2R; // Records previous state. Secondary fire<br> TR = digitalRead(triggerPin); // Looks up current trigger button state<br> T2R = digitalRead(trigger2Pin); // Looks up current trigger button state<br> // Code looks for changes in trigger state to give it a semi automatic shooting behaviour<br> if(TR != LTR &amp;&amp; TR == LOW){<br> FIRE = 1;<br> }<br> if(T2R != LT2R &amp;&amp; T2R == LOW){<br> FIRE = 2;<br> }<br> if(TR == LOW &amp;&amp; automatic == 1){<br> FIRE = 1;<br> }<br> if(T2R == LOW &amp;&amp; automatic2 == 1){<br> FIRE = 2;<br> }<br> if(FIRE == 1 || FIRE == 2){<br> if(ammo &lt; 1){FIRE = 0; noAmmo();}<br> if(life &lt; 1){FIRE = 0; dead();}<br> // Fire rate code to be added here <br> }<br> <br>}<br><br><br>void configureGame() { // Where the game characteristics are stored, allows several game types to be recorded and you only have to change one variable (myGameID) to pick the game.<br> if(myGameID == 0){<br> myWeaponID = 1;<br> maxAmmo = 30;<br> ammo = 30;<br> maxLife = 3;<br> life = 3;<br> myWeaponHP = 1;<br> }<br> if(myGameID == 1){<br> myWeaponID = 1;<br> maxAmmo = 100;<br> ammo = 100;<br> maxLife = 10;<br> life = 10;<br> myWeaponHP = 2;<br> }<br>}<br><br><br>void frequencyCalculations() { // Works out all the timings needed to give the correct carrier frequency for the IR signal<br> IRt = (int) (500/IRfrequency); <br> IRpulses = (int) (IRpulse / (2*IRt));<br> IRt = IRt - 4;<br> // Why -4 I hear you cry. It allows for the time taken for commands to be executed.<br> // More info: http://j44industries.blogspot.com/2009/09/arduino-frequency-generation.html#more<br><br> Serial.print(&quot;Oscilation time period /2: &quot;);<br> Serial.println(IRt);<br> Serial.print(&quot;Pulses: &quot;);<br> Serial.println(IRpulses);<br> timeOut = IRpulse + 50; // Adding 50 to the expected pulse time gives a little margin for error on the pulse read time out value<br>}<br><br><br>void tagCode() { // Works out what the players tagger code (the code that is transmitted when they shoot) is<br> byte1[0] = myTeamID &gt;&gt; 2 &amp; B1;<br> byte1[1] = myTeamID &gt;&gt; 1 &amp; B1;<br> byte1[2] = myTeamID &gt;&gt; 0 &amp; B1;<br><br> byte1[3] = myPlayerID &gt;&gt; 4 &amp; B1;<br> byte1[4] = myPlayerID &gt;&gt; 3 &amp; B1;<br> byte1[5] = myPlayerID &gt;&gt; 2 &amp; B1;<br> byte1[6] = myPlayerID &gt;&gt; 1 &amp; B1;<br> byte1[7] = myPlayerID &gt;&gt; 0 &amp; B1;<br><br><br> byte2[0] = myWeaponID &gt;&gt; 2 &amp; B1;<br> byte2[1] = myWeaponID &gt;&gt; 1 &amp; B1;<br> byte2[2] = myWeaponID &gt;&gt; 0 &amp; B1;<br><br> byte2[3] = myWeaponHP &gt;&gt; 4 &amp; B1;<br> byte2[4] = myWeaponHP &gt;&gt; 3 &amp; B1;<br> byte2[5] = myWeaponHP &gt;&gt; 2 &amp; B1;<br> byte2[6] = myWeaponHP &gt;&gt; 1 &amp; B1;<br> byte2[7] = myWeaponHP &gt;&gt; 0 &amp; B1;<br><br> myParity = 0;<br> for (int i=0; i&lt;8; i++) {<br> if(byte1[i] == 1){myParity = myParity + 1;}<br> if(byte2[i] == 1){myParity = myParity + 1;}<br> myParity = myParity &gt;&gt; 0 &amp; B1;<br> }<br><br> // Next few lines print the full tagger code.<br> Serial.print(&quot;Byte1: &quot;);<br> Serial.print(byte1[0]);<br> Serial.print(byte1[1]);<br> Serial.print(byte1[2]);<br> Serial.print(byte1[3]);<br> Serial.print(byte1[4]);<br> Serial.print(byte1[5]);<br> Serial.print(byte1[6]);<br> Serial.print(byte1[7]);<br> Serial.println();<br><br> Serial.print(&quot;Byte2: &quot;);<br> Serial.print(byte2[0]);<br> Serial.print(byte2[1]);<br> Serial.print(byte2[2]);<br> Serial.print(byte2[3]);<br> Serial.print(byte2[4]);<br> Serial.print(byte2[5]);<br> Serial.print(byte2[6]);<br> Serial.print(byte2[7]);<br> Serial.println();<br><br> Serial.print(&quot;Parity: &quot;);<br> Serial.print(myParity);<br> Serial.println();<br>}<br><br><br>void playTone(int atone, int duration) { // A sub routine for playing tones like the standard arduino melody example<br> for (long i = 0; i &lt; duration * 1000L; i += atone * 2) {<br> digitalWrite(speakerPin, HIGH);<br> delayMicroseconds(atone);<br> digitalWrite(speakerPin, LOW);<br> delayMicroseconds(atone);<br> }<br>}<br><br><br>void dead() { // void determines what the tagger does when it is out of lives<br> // Makes a few noises and flashes some lights<br> for (int i = 1;i &lt; 254;i++) {<br> analogWrite(ammoPin, i);<br> playTone((1000+9*i), 2);<br> } <br> analogWrite(ammoPin, ((int) ammo));<br> analogWrite(lifePin, ((int) life));<br> Serial.println(&quot;DEAD&quot;);<br> <br> for (int i=0; i&lt;10; i++) {<br> analogWrite(ammoPin, 255);<br> digitalWrite(hitPin,HIGH);<br> delay (500);<br> analogWrite(ammoPin, 0);<br> digitalWrite(hitPin,LOW);<br> delay (500);<br> }<br>}<br><br><br>void noAmmo() { // Make some noise and flash some lights when out of ammo<br> digitalWrite(hitPin,HIGH);<br> playTone(500, 100);<br> playTone(1000, 100);<br> digitalWrite(hitPin,LOW);<br>}<br><br><br>void hit() { // Make some noise and flash some lights when you get shot<br> digitalWrite(hitPin,HIGH);<br> life = life - hp[hitNo];<br> Serial.print(&quot;Life: &quot;);<br> Serial.println(life);<br> playTone(500, 500);<br> if(life &lt;= 0){dead();}<br> digitalWrite(hitPin,LOW);<br> lifeDisplay();<br>}
This is awesome! I am just about to use the Arduinos for a competition my robotics club is going into. I really want to build a full on laser tag system for my group of friends to mess around with.<br /> <br /> One question though, wouldnt a laser work the same way (i know the hazard might be the problem) but isnt that what is used for most laser tag systems?<br /> <br /> As a suggestion, make a simple voltage regulator for the arduino and add a bigger battery to be able to use the motor, but I am not sure how to signal the motor to move (Im thinking using a PWM system?).<br />
Thanks!<br /> <br /> All laser tag systems that I know of use IR diodes, although some systems have a low power laser as well just to show where you have shot. If you were to just use a laser then you would find the bean would be far too narrow; you would either have to coat the players head to toe in sensors or aim very very accurately at the sensors, I think you would struggle to get a realistic game feel. <br /> <br /> I have got force feedback motors working with the arduino, but I wanted to keep these guns small and relativly simple so didn't want to bother with a bigger battery pack so disabled the feature.<br /> <br /> Let me know how you get on.<br /> <br />
Maybe you can try with an r/c modell accu pack, like this one. <br>http://www.hobbyking.com/hobbyking/store/__11938__Turnigy_nano_tech_6000mah_2S_25_50C_Lipo_Pack.html <br> <br>Cute, little, and strong.
Since you already have sensors mounted on the player wouldn't it be possible to use the same line and put a battery pack say on a persons back? Having a high battery capacity would allow you to use the rumble feature in the gun, and maybe even add more rumble motors. It would be cool say if you get hit on the head sensor to have a small cell phone sized rumble go off on that sensor, and maybe a larger one for the chest sensor and a third on the back sensor. The rumble in the gun could be use as feedback for when you shoot, and then when you are out of ammo it doesn't give feedback, like a gun not firing when out of ammo. Another feature that could be cool is a game start timer, say everyone starts in the middle of the playing field and hits the power on the system at the same time and it gives you like 30-45 seconds to run to your base / starting point and then all the sensors go off to indicate the game has started.
hey i was wondering i dont know if you can do this but heres my idea could you tell me how i could do this? ok so a small screen to tell you where the other people are (10 ft acurate) a umpc built into the gun so at the beginning of the game you choose a gun (machine gun, sniper rifle, etc. each gun has dif. ammo quantities, damage, and &quot;range&quot;) each person gets a pistol with unlimited ammo. get 3 grenades,1 nuke (each has dif radius of how much it kills) 100 health to start with and all the sensors are on the gun (maybe 6?) i was wondering if you could get and program all these things into the gun i dont care about costs so could you just tell me how or if you think it is possible? i am learning how to program this stuff but i have about 6 people who could help me program the arduino Thanks
Different types of guns etc would be quite easy to implement, I started to put support for that in the code. Knowing where other players are would probably need GPS, wireless links and screens etc, to start from scratch would be tricky and expensive. If I were to undertake a build like that I would think about using the arduino with an android phone. The android phone would provide the GPS, screen and wireless communication, in a small convenient easy to program device. For how to use an arduino with an android phone try looking at the amarino tool kit: http://www.amarino-toolkit.net/ Let me know if you build anything, would be interested to see any pics or vids.
for gps couldnt you use an xbee module? they make screens for arduino
Its taken me longer than I am proud of to notice what seems to be going on here.<br><br>Its almost you have a vested interest in advertising SparkFun products :-)<br><br>So I will say the following:<br><br>I have recently used the MP3 Trigger V2 to add sound to a project and it was great (easy to use and worked very well).<br>http://www.sparkfun.com/commerce/product_info.php?products_id=9715<br>Would be a great way of improving the sound effect on a duino tagger.<br><br>I have also had very good experiences with several arduino pro minis recently.<br>http://www.sparkfun.com/commerce/product_info.php?products_id=9218<br>Great for any compact duino tag projects.<br><br>So credit where credit is due I have had good experience with SparkFun products.<br><br>Still think it would be cool to have a duino tagger android app ;-P
http://www.sparkfun.com/commerce/product_info.php?products_id=8977 this is even easier than the other touchscreen this would not be a problem to put on the arduino
here is a screen and a trackball to use as a button so you could select stuff and scroll http://www.sparkfun.com/commerce/product_info.php?products_id=8537 http://www.sparkfun.com/commerce/product_info.php?products_id=9320 then if price is not an option you could use this and substitute it for both or keep the trackball (i love the blackberry trackballs) http://www.sparkfun.com/commerce/product_info.php?products_id=8624 please tell me what you think about this
sure ill let you know what i do!!
In Canberra where I am, we have a laser tag arena that we often to go for birthday parties (not so much now...) where you get a vest with sensors on the shoulders, front, back and on the gun. If you should just off the sensor, then it will not sound it. But if the laser points directly at it then you're good. This does not make it much harder at all.<br /> <br /> This arena also has &quot;bases&quot; which you have to shoot 3 times (with 3 second down time between each shot at the base) and then you capture it and score 10 points in stead of 1.<br /> <br /> Feedback motors are cool, but as a &quot;laser&quot; feel it's alright if they're kept off, to keep with the futuristic feel of just the laser.<br />
Thank you for your help. The code that registers any IR signal code works great for our application. Oh which I forgot to mention what that was. It is a laser tag plane. Their are two planes that have the IR that can shoot at each other. When they are hit I have them make noise along with the flashing to manually keep track of hits. Also, with the simplicity of the code, the planes could be shot at from the ground by TV remotes, adding a new element.<br>Once again Thank you for your tutorial and help.<br><br>&quot;AerospaceSmith&quot; &lt;(^^,)&gt;
Images of our plane
No I am still having issues. However, I have gotten it receive the signal 1 time, out of billions. This was only after using an older version of Arduino IDE (00017) to upload the code and after changing the code to 38kHz. I'm thinking the code can't read the IR pulses fast enough. <br><br>Using a code from Ladyada (https://github.com/adafruit/Raw-IR-decoder-for-Arduino/blob/master/rawirdecode.pde) I was able to read the raw IR code sent from the other arduino(which was sending 56kHz at the time). So it seems to be the lasertag code can't read fast enough. I am in urgent need of help or a new code as soon as possible. I just need a simple laser tag code to use between mainly two people playing against each other that I can have each players score keep track of independently. Any and all help will be greatly appreciated.
I have done some investigation into the latest IDE, it does seem to change a few things, it seems to have slightly slowed the digital write function.<br><br>Yeshi88 advice is good try looking at what length pulses you are receiving.<br><br>If the values don't come out quite right a simple fix could be:<br><br>Add a line in void FrequencyCalculations after line<br><br>IRpulses = (int) (IRpulse / (2*IRt));<br><br>to <br><br>IRpulses = (int) (IRpulse / (2*IRt));<br>IRpulses = IRpulses - 5;<br><br>Where I have put - 5 try a few values between about + 10 and - 10 and see if that sorts things out. <br><br>Failing that in the set up change Serial.begin(9600); to Serial.begin(57600); <br>Note you will also have to change the baud in the Serial Monitor. I dont think it is particularly likely to help but in the latest IDE they do seem to have changed some serial stuff and if it has got slower perhaps that could be a problem. <br><br>Sorry I don't really have the facilities to replicate the fault at the moment but hopefully some of the suggestions might help.<br>
Okay, I am I have copied your code to my Arduinos and have a similar setup as yours, the only main difference being I am using 56kHz receivers and have changed the IRfrequency variable to 56, but when ever I shoot the other arduino, it just reads ERROR<br>sensor: 1... 2 2 2 2 0 2 2 0 2 2 0 2 2 2 2 2 2<br><br>after the sometimes there is all 2s and sometimes zeros randomly in the string. I also set it up to display received[17] specifically and it is always 2. Why is this?<br><br>I also have the Arduinos close to each other, could the short distance be affecting the IR signal?<br><br>Any advise would be greatly appreciated.
Try removing timeOut paramter in the following line of the code:<br><br>received[i] = pulseIn(IRreceivePin, LOW, timeOut); <br><br>If it still does not work , try adding <br><br>Serial.println(received[i]); before the following lines.<br><br>int receivedTemp[18];<br>receivedTemp[i] = 2;<br>if(received[i] &gt; (IRpulse - 200) &amp;&amp; received[i] &lt; (IRpulse + 200)) {receivedTemp[i] = 0;} // Works out from the pulse length if it was a data 1 or 0 that was received writes result to receivedTemp string<br><br>Your output should fall between 400 - 800 for byte 0 and 1000 - 1400 for byte 1<br>
Hi,<br><br>My lasertag used to work and as of today I am getting the above error as well ? <br><br>I have tried J44's suggestions and still nothing? Weird !<br><br>Any other suggestions ?<br><br>Thanks<br>Tag
just had a thought - can this be related to the new Arduino client ?<br><br>Thanks<br>Tag
I suspect what might be happening is that the timings are not quite working out. <br>The code uses rather basic bit bashing to generate the frequencies and may not be making the pulses the right length with the frequency set to 56k, meaning the receive arduino is rejecting the pulses as not valid. <br><br>The best thing to do would be to look at the signal to the transmitter LED on an oscilloscope and make sure the pulses are 600us for 0's and 1200us for 1's, but there are some other simpler fault finding tests you can try.<br><br>If you put IRfrequency variable back to 38 and try it you might find it works (even though a 56k reciever is not designed to recieve that frequency it will be slightly sensitive to it and might just give you short ranges. <br><br>If that works put the frequency back to 56 then try the following:<br>In the frequencyCalculation void there is a line IRt = IRt - 4. Try -3 or -5 instead of the -4 and see if that makes it work. <br>
If I wanted to do this with all hardware could I not just put a PNP transistor on the output of the IR detector and connect lights/sounds etc to power through the PNP transistor? <br><br>Thanks!<br>Will
I am not sure I quite understand the design you are proposing, but if you take your hit signal directly from the sensors you will not be able to check the received signal is a valid tagger shot as opposed to just noise or a TV remote.
Are the receivers interfered with by sunlight? Can it be used on a sunny day with lots of direct sunlight?
The sensors are designed to detect a modulated IR signal, this means the signals can be detected even with significant ambient IR. I have not noticed any reduction in performance in bright light but there may be some.
j44 the first receiver picture is hard to read because of its low quality. Could you upload a better picture? the rest is clear and awesome. the tactapult is also neat
Feedback appreciated.<br><br>Have done what I can within the resolution and compression limits on the web site. Hope its ok now, if not I will have a think about what else I can do (I would probably have to upload the picture as several smaller parts).
I just discovered that I can click on the picture info button and get a high quality picture. I feel dumb. thanks anyways
I think you can try the laser sight for your gun or rifle that provided by http://www.greenlaserpointer.org
Hey, great instructables! Got a question though. I've been looking over the internet for a light gun and I can't seem to find one anywhere. Is there a site that you know of or a link you could send me that has one for sale? Thanks<br /> <div id="refHTML">&nbsp;</div>

About This Instructable

167,438 views

372 favorites

License:

More by j44: LED Color Sensor Ultrasonic Headtracker Mouse Halloween Sugru Lights
Add instructable to: