/ /
LED as input
First
Solder together and ArdweenyYou can use an LED to detect light. For best results, use a colored LED (such as red) and a normal white flashlight (the brighter the better).
Connect the anode into the 0 Analog In pin and connect the cathode to Ground.
Here is code to show you that the LED is detecting light:
/* LED Light Sensor
* by Duane O'Brien
* for IBM Developer Works
*/
int recvPin = 0;
int wait = 1000;
int val = 0;
void setup() {
// Initialize the Serial Interface
Serial.begin(9600);
}
void loop() {
// Take a reading from the Analog Pin
val = analogRead(recvPin);
// Output the detected value
Serial.print("DETECT : ");
Serial.println(val);
// Wait to take the next reading.
delay(wait);
}
Now you are going to modify the code to learn a little bit about frequency.
Infrared is everywhere, so sensors need to filter out anything not being transmitted at a specific frequency. The code below will show you, in a rudimentary way, how transmitting frequency works. This isn't intended to be a comprehensive scientific experiment, but it may help illustrate the concept.
You are going to change the code so that when the light reading jumps by more than 5 percent of the baseline, a cycle is started that looks at the next two readings, outputting a specific code based on the codes detected. You'll need some additional variables:
- a variable to determine how many readings should be taken to establish the baseline number for ambient light
- a variable to hold the minimum reading jump you are expecting
- an iterator
- an array to hold the different codes
- and a tracking int to tell where you are in a cycle.
int recvPin = 0;
int wait = 1000;
int val = 0;
int readings = 5;
int jump = 0;
int i = 0;
int code[2];
int incycle = 0;
void setup() {
/*Next, you need to take a set of readings during setup, average them, and determine
what 5 percent means. Generally, the first reading is always abnormally high,
so throw that one out right away. */
// Initialize the Serial Interface
Serial.begin(9600);
Serial.print("establishing baseline... ");
val = analogRead(recvPin); // throw out the first one, it's usually high.
delay(wait);
for (i = 0; i < readings;i++) {
jump += analogRead(recvPin);
delay(wait);
}
jump = (jump / readings)*1.05;
Serial.println(jump);
// Output the detected value
delay(wait);
}
void loop() {
/*you read the pin. If you're in a cycle, you need to save the
code, and if you have received all the code, output a result. If you're not in a cycle,
and the reading is 5 percent above the baseline, you start a cycle. Listing 10 could
be more compact, but it's spelled out a little more clearly so you can see what's
going on. */
// Take a reading from the Analog Pin
val = analogRead(recvPin);
switch (incycle) {
case 0:
if (val > jump) {
Serial.println("In Cycle");
incycle = 1;
} else {
Serial.println("Out Of Cycle");
}
break;
case 1:
if (val > jump) {
code[0] = 1;
} else {
code[0] = 0;
}
incycle = 2;
Serial.println("Read One");
break;
case 2:
if (val > jump) {
code[1] = 1;
} else {
code[1] = 0;
}
incycle = 3;
Serial.println("Read Two");
break;
case 3:
if (code[0] == 0 && code[1] == 0) {
Serial.println("Reset");
} else if (code[0] == 1 && code[1] == 0) {
Serial.println("Turn On");
} else if (code[0] == 0 && code[1] == 1) {
Serial.println("Turn Off");
} else if (code[0] == 1 && code[1] == 1) {
Serial.println("Explode");
}
code[0] = 0;
code[1] = 0;
incycle = 0;
break;
}
delay(wait);
}
What you're doing here is signaling a binary message at a very low frequency.
/ / Duino Tag
Characteristics
- When the player triggers the input, a single "shot" is fired.
- When the gun is a fired, it should make a cool sound like "PEW PEW."
- The gun will also be used to detect hits.
- When a hit is detected, the gun should make a different sound, like
"KZZKH KZZKH."
- Each gun has a certain amount of shots that can be fired.
- When the gun is out of ammo, and the player pulls triggers the input, the gun
should play a third sound like "EEERK EEERK."
- When the player is eliminated, the gun should play one final sound, like
"BOOM KAPOW"
Rules
- Each gun has six safe shots. There is no reload. These shots may be
fired without danger.
- Each player can take three hits. Once you have taken three hits, you are
eliminated.
- Each shot a player fires past the sixth increases the possibility of
catastrophic gun failure. In the event of catastrophic gun failure, the
player is eliminated.
Basically, you can be hit three times, and you can fire six times. After you have used your six safe shots, each time you fire a shot, the odds of your gun failing increase. If your gun fails, you are eliminated.
In General
- 'Duino tag is based on infrared.
- The gun acts as an emitter and a sensor.
- The gun needs some kind of trigger.
- The gun has sounds.
- The gun must be embedded. You could encase it in a hat or a sleeve or some other item on your person.
IR
IR is infrared light or light that is outside the visible light spectrum, in other words the naked eye cannot see it. IR light does not obey all the same properties as visible light. IR can pass through certain types/colors of plastic and some other materials, it is VERY easily reflected off most objects, and it is very prevalent in today's electronics.Infrared radiation surrounds us. The sun emits it, as do lamps and TVs,etc.
If you set up a sensor triggered whenever any infrared was detected, it would be triggered constantly, and, hence, be virtually useless.
So, if this is the case, how do infrared remote controls work? The remote control for your TV contains a specifically designed sensor built to detect infrared being emitted at a certain frequency. Sony, for example, standardizes its infrared interfaces at 40 KHz. In other words, the infrared LED is turned on and off 40,000 times per second. By only sensing input within a given frequency, the TV can ignore infrared that is not coming from the remote. The remote transmits different codes to the TV by pulsing the IR signal.
This is essentially how the 'Duino tag' gun works. This means the gun requires a particular type of IR sensor.
Parts
- Infrared LED-a T1 three-quarter IR LED
- Infrared sensor-a TSOP2138YA Infrared Sensor
- Single-pole momentary switch- the trigger
- Piezo element
- 22-gauge solid wire-two colors
- Resistors-100 ohm,10k and a 82 ohm
- Capacitors-one 0.1uF capacitor.
- Lens- A small magnifying lens (three-quarters to 1 inch in diameter)
- universal remote
The sensor
The sensor combines a photo sensor and a preamp. Most IR sensors of this type combine these two features into one component for convenience. The housing acts as an IR filter. The housing of this sensor and other sensors of this type serve to filter out background IR. The sensor uses a carrier frequency of 38 kHz. This is a commonly used IR frequency and means that your guns will need to transmit at 38 kHz, as well. This sensor has a simple 3-pin interface:
- Pin 1 provides a signal when a 38-kHz IR signal is sensed.
- Pin 2 connects to a supply voltage.
- Pin 3 connects to a ground.
Wiring
- Use the Ardweeny instead of an Arduino
- For wiring the IR sensor, you need the 100 ohm resistor and the capacitor. The spec sheet for
the sensor suggests adding a capacitor and a resistor to "suppress power supply
disturbances." When you finalize your gun configuration, you will want these
additional components wired as close to the sensor as possible.
The output from the sensor comes from pin 1, which should be wired to pin 2 on the Arduino board. -
The supply voltage, which comes into the sensor on pin 2, should come through the
100-ohm resistor. Run a line from the +5v pin on the Arduino board to the resistor,
and connect the resistor to pin 2 on the IR sensor.
-
The IR sensor is grounded through pin 3. The 0.1uF capacitor should be connected
between pins 2 and 3 on the sensor
- Wire the positive leg of the LED to pin 13 on the Arduino board and the negative leg
of the LED to the ground.
You'll use this LED to indicate that a signal is being received. - Use the piezo element to produce a sound when a signal is
received. Wire the positive lead from the piezo to pin 12 on the Arduino and wire the
negative lead to a ground pin.
- Connect pin 3 of the Arduino to 1 end of the 82-ohm resistor. Connect the other side of the resistor to the anode of the IR led. Connect the cathode side of the LED to one lead of the button.
The important thing here is that the infrared LED and the infrared sensor face the same direction. - Connect Arduino pin 4 to the other lead of the
button( not the one that the LED is connected to). Wire one end of the 10k-ohm resistor the same lead of the button and the other end to 5v.

- When you coded the receiver, you told it to recognize a start bit, then read nine more
pulses. The first four pulses are used to represent the player who fired (your Who).
The second four pulses are used to represent what is being fired (either the player's
level or the referee's command code — your What). The final pulse is used to help eliminate bad signal reads from any remote
controls that might be in the area.
You know some things about how the gun should behave in firing mode. When the rules of 'Duino tag were established, there were several statements that affect how the gun will work:- When the player pulls a trigger, a single shot is fired.
- When the gun is fired, it should make a cool sound like "PEW PEW."
- Each gun has six "safe" shots. There is no reload.
- Each shot a player fires past the sixth increases the possibility of catastrophic gun failure. In the event of catastrophic gun failure, the player is eliminated.
- Upload your finished code to your Arduino board. In order to test, you'll need two
guns and two computers.
Turn on the serial monitor and start firing the gun until it blows up. You should see messages that indicate the gun is being fired until the self-destruct sequence is fired. - Reset your board, pick up the second gun, and at point-blank range, aim the gun so
the infrared LED is pointed at the infrared radiation sensor on the gun connected to
the serial monitor, and fire a shot. Both guns should make some noise, and you
should see the shot registered in the serial monitor.
Setting up the 'Duino tag protocol
When a shot is fired, the IR LED in the transmitter broadcasts a small piece of encoded data. Before you can really decode this data, you need to know what the data will be. Doing so will require making some assumptions that should be spelled out clearly.-
'Duino Tag is not a game for cheaters.
Meaning that everyone plays by the rules. You could establish a lot of protocol overhead to make sure nobody could cheat. -
Teams are organic in nature, not enforced by the hardware.
This allows for all sorts of behavior, such as making verbal alliances, betraying
your allies, and accidentally shooting your friends.
-
A referee is necessary.
The referee should be able to change a player's level or ammo, reset a gun,
etc.
Using four bits, you could transmit 16 unique codes — more than enough to start. Likewise, 16 actions would be more than enough to start for a player or a referee. You could fire a range of 16 kinds of shots, or perform 16 different administrative actions.
You need eight bits total — the first four will correspond to a player's number, and the last four will correspond to an action of some kind (shot strength, or referee action). Now that you know approximately what to expect, start writing some code for the sensor:
The code for the sensor is written in four parts. First, you need to set up the pins and run a brief test sequence in the setup function. Then you'll put together a function to decode incoming IR signals. After this function is put together, you set up the Loop function to listen for signals. Finally, you'll sort out a function to play some tones.
- Open Arduino and add the following:
/* * Giving Credit where Credit Is Due * * Portions of this code were derived from code posted in the Arduino forums by Paul Malmsten. * You can find the original thread here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434 * * The Audio portion of the code was derived from the Melody tutorial on the Arduino wiki * You can find the original tutorial here: http://arduino.cc/en/Tutorial/Melody */ int sensorPin = 2; // Sensor pin 1 int senderPin = 3; // Infrared LED on Pin 3 int triggerPin = 4; // Pushbutton Trigger on Pin 4 int speakerPin = 12; // Positive Lead on the Piezo int blinkPin = 13; // Positive Leg of the LED we will use to indicate signal is received int startBit = 2000; // This pulse sets the threshold for a transmission start bit int endBit = 3000; // This pulse sets the threshold for a transmission end bit int one = 1000; // This pulse sets the threshold for a transmission that represents a 1 int zero = 400; // This pulse sets the threshold for a transmission that represents a 0 int trigger; // This is used to hold the value of the trigger read; boolean fired = false; // Boolean used to remember if the trigger has already been read. int ret[2]; // Used to hold results from IR sensing. int waitTime = 300; // The amount of time to wait between pulses int playerLine = 17; // Any player ID >= this value is a referee, < this value is a player; int myCode = __; // This is your unique player code; int myLevel = 1; // This is your starting level; int maxShots = 6; // You can fire 6 safe shots; int maxHits = 3; // After 6 hits you are dead; int myShots = 0; // You can fire 6 safe shots; int myHits = 0; // After 6 hits you are dead; int maxLevel = 9; // You cannot be promoted past level 9; int minLevel = 0; // You cannot be demoted past level 0 int refPromote = 0; // The refCode for promotion; int refDemote = 1; // The refCode for demotion; int refReset = 2; // The refCode for ammo reset; int refRevive = 3; // The refCode for revival; int replySucc = 14; // the player code for Success; int replyFail = 15; // the player code for Failed; void setup() { pinMode(blinkPin, OUTPUT); pinMode(speakerPin, OUTPUT); pinMode(senderPin, OUTPUT); pinMode(triggerPin, INPUT); pinMode(sensorPin, INPUT); randomSeed(analogRead(0)); for (int i = 1;i < 4;i++) { digitalWrite(blinkPin, HIGH); playTone(900*i, 200); digitalWrite(blinkPin, LOW); delay(200); } Serial.begin(9600); Serial.println("Ready: "); } void loop() { senseFire(); senseIR(); if (ret[0] != -1) { playTone(1000, 50); Serial.print("Who: "); Serial.print(ret[0]); Serial.print(" What: "); Serial.println(ret[1]); if (ret[0] >= playerLine) { if (ret[1] == refPromote) { // Promote if (myLevel < maxLevel) { Serial.println("PROMOTED!"); myLevel++; playTone(900, 50); playTone(1800, 50); playTone(2700, 50); } } else if (ret[1] == refDemote) { // demote if (myLevel > minLevel) { Serial.println("DEMOTED!"); myLevel--; } playTone(2700, 50); playTone(1800, 50); playTone(900, 50); } else if (ret[1] == refReset) { Serial.println("RESET!"); myShots = maxShots; playTone(900, 50); playTone(450, 50); playTone(900, 50); playTone(450, 50); playTone(900, 50); playTone(450, 50); } else if (ret[1] == refRevive) { Serial.println("REVIVED!"); myShots = 0; myHits = 0; myLevel = 1; playTone(900, 50); playTone(1800, 50); playTone(900, 50); playTone(1800, 50); playTone(900, 50); playTone(800, 50); } } else { if (ret[1] == replySucc) { playTone(9000, 50); playTone(450, 50); playTone(9000, 50); Serial.println("SUCCESS!"); } else if (ret[1] == replyFail) { playTone(450, 50); playTone(9000, 50); playTone(450, 50); Serial.println("FAILED!"); } if (ret[1] <= maxLevel && ret[1] >= myLevel){ if(myHits < maxHits) { Serial.println("HIT!"); myHits++; playTone(9000, 50); playTone(900, 50); playTone(9000, 50); playTone(900, 50); }else{ Serial.println("DEAD!"); playTone(1000, 50); playTone(9000, 50); } } } } void senseIR() { int who[4]; int what[4]; int end; if (pulseIn(sensorPin, LOW, 50) < startBit) { digitalWrite(blinkPin, LOW); ret[0] = -1; return; } digitalWrite(blinkPin, HIGH); who[0] = pulseIn(sensorPin, LOW); who[1] = pulseIn(sensorPin, LOW); who[2] = pulseIn(sensorPin, LOW); who[3] = pulseIn(sensorPin, LOW); what[0] = pulseIn(sensorPin, LOW); what[1] = pulseIn(sensorPin, LOW); what[2] = pulseIn(sensorPin, LOW); what[3] = pulseIn(sensorPin, LOW); end = pulseIn(sensorPin, LOW); if (end <= endBit) { Serial.print(end); Serial.println(" : bad end bit"); ret[0] = -1; return; } Serial.println("---who---"); for(int i=0;i<=3;i++) { Serial.println(who[i]); if(who[i] > one) { who[i] = 1; } else if (who[i] > zero) { who[i] = 0; } else { // Since the data is neither zero or one, we have an error Serial.println("unknown player"); ret[0] = -1; return; } } ret[0]=convert(who); Serial.println(ret[0]); Serial.println("---what---"); for(int i=0;i<=3;i++) { Serial.println(what[i]); if(what[i] > one) { what[i] = 1; } else if (what[i] > zero) { what[i] = 0; } else { // Since the data is neither zero or one, we have an error Serial.println("unknown action"); ret[0] = -1; return; } } ret[1]=convert(what); Serial.println(ret[1]); return; } void playTone(int tone, int duration) { for (long i = 0; i < duration * 1000L; i += tone * 2) { digitalWrite(speakerPin, HIGH); delayMicroseconds(tone); digitalWrite(speakerPin, LOW); delayMicroseconds(tone); } } int convert(int bits[]) { int result = 0; int seed = 1; for(int i=3;i>=0;i--) { if(bits[i] == 1) { result += seed; } seed = seed * 2; } return result; } void senseFire() { trigger = digitalRead(triggerPin); if (trigger == LOW && fired == false) { Serial.println("Button Pressed"); fired = true; myShots++; if (myHits <= maxHits && myShots > maxShots && random(1,20) <= myShots) { Serial.println("SELF DESTRUCT"); selfDestruct(); } else if (myHits <= maxHits) { Serial.print("Firing Shot : "); Serial.println(myShots); fireShot(myCode, myLevel); } } else if (trigger == HIGH) { if (fired == true) { Serial.println("Button Released"); } // reset the fired variable fired = false; } } void fireShot(int player, int level) { int encoded[8]; digitalWrite(blinkPin, HIGH); for (int i=0; i<4; i++) { encoded[i] = player>>i & B1; //encode data as '1' or '0' } for (int i=4; i<8; i++) { encoded[i] = level>>i & B1; } // send startbit oscillationWrite(senderPin, startBit); // send separation bit digitalWrite(senderPin, HIGH); delayMicroseconds(waitTime); // send the whole string of data for (int i=7; i>=0; i--) { if (encoded[i] == 0) { oscillationWrite(senderPin, zero); } else { oscillationWrite(senderPin, one); } // send separation bit digitalWrite(senderPin, HIGH); delayMicroseconds(waitTime); } oscillationWrite(senderPin, endBit); playTone(100, 5); digitalWrite(blinkPin, LOW); } void oscillationWrite(int pin, int time) { for(int i = 0; i <= time/26; i++) { digitalWrite(pin, HIGH); delayMicroseconds(13); digitalWrite(pin, LOW); delayMicroseconds(13); } } void selfDestruct() { myHits = maxHits+1; playTone(1000, 250); playTone(750, 250); playTone(500, 250); playTone(250, 250); } - Change the value of int myCode to a unique number
- Upload the code to your Arduino board. In order to test, you'll need two
guns and two computers.
Turn on the serial monitor and start firing the gun until it blows up. You should see messages that indicate the gun is being fired until the self-destruct sequence is fired. - Reset your board, pick up the second gun, and at point-blank range, aim the gun so
the infrared LED is pointed at the infrared radiation sensor on the gun connected to
the serial monitor, and fire a shot. Both guns should make some noise, and you
should see the shot registered in the serial monitor.
- Take a few steps back and fire again. It won't take long until your shots are no longer
being registered. Your range may only be a few feet. That probably doesn't seem
very useful, but it's a problem that is easily solved.
To increase your range, you'll need to use a lens to focus your infrared signal. This is a pretty simple process that will yield great results. You'll need that magnifying lens, some rigid tube, and something to measure distance, such as a ruler. You need to determine the focal length of your magnifying lens. The focal length is a measurement of how far an object needs to be from your lens in order to appear in focus. Said another way, it is the measurement from the center of the lens to the point at which the light coming through the lens is focused
If you don't know the focal length of your lens, shine a bright light onto a piece of plain white paper and use your magnifying lens to focus the light on the paper. Once you can see the light source clearly in focus, measure the distance from your lens to the paper. This measurement is your focal length and is how far you want your infrared LED from your lens. -
Cut your rigid tube to this length and affix your lens to one end. How you do this will
vary widely depending on your hardware.
- Attach your infrared LED to the other end of the tube,
centered and pointing toward the lens. Solder some
wire leads to your LED before you try to put anything in place.
- Once you have your lens in place, reset both guns and try firing some test shots
again, stepping progressively farther and farther away. The farther apart the guns
are, the more accurately you will need to aim your gun to record a hit.
Lenses that increase your range also require that you be more accurate in your shots; you'll be able to hit people from farther away, but you need to be more accurate, even at close range. Lenses that decrease your range will allow you to be a little less accurate; you won't be able to hit people from very far away, but you won't have to aim so precisely. - However you case your components, there are a few guiding principles to stick to:
- The resistor and capacitor for your infrared radiation sensor need to be
mounted close to the sensor.
- Mount the sensor facing the front of the gun, in a way that's visible and
not blocked by other components.
- Mount your lens tube straight and so you can aim it easily.
- You'll need to include some battery power for your Arduino board.
- Easy access to your Arduino board, at least to upload new software
- The resistor and capacitor for your infrared radiation sensor need to be
mounted close to the sensor.
The Referee gun
Built into the protocol is the ability for a referee to promote, demote, reset, and revive players. A Referee's gun would have different software and would need more buttons. The simplest way to implement what was written into the protocol would be to build a gun with four buttons, one for each function (promote, demote, reset and revive).
Targets
You could easily put together a set of targets that could be installed around the play area. The targets could be used to get points, fire random shots, or act as automated referees
/ /
http://aterribleidea.com/2009/02/25/building-an-arduino-based-laser-tag-game/
/*
* Giving Credit where Credit Is Due
*
* Portions of this code were derived from code posted in the Arduino forums by Paul Malmsten.
* You can find the original thread here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434
*
* The Audio portion of the code was derived from the Melody tutorial on the Arduino wiki
* You can find the original tutorial here: http://arduino.cc/en/Tutorial/Melody
*/
int sensorPin = 2; // Sensor pin 1
int senderPin = 3; // Infrared LED on Pin 3
int triggerPin = 4; // Pushbutton Trigger on Pin 4
int speakerPin = 12; // Positive Lead on the Piezo
int blinkPin = 13; // Positive Leg of the LED we will use to indicate signal is received
int startBit = 2000; // This pulse sets the threshold for a transmission start bit
int endBit = 3000; // This pulse sets the threshold for a transmission end bit
int one = 1000; // This pulse sets the threshold for a transmission that represents a 1
int zero = 400; // This pulse sets the threshold for a transmission that represents a 0
int trigger; // This is used to hold the value of the trigger read;
boolean fired = false; // Boolean used to remember if the trigger has already been read.
int ret[2]; // Used to hold results from IR sensing.
int waitTime = 300; // The amount of time to wait between pulses
int playerLine = 14; // Any player ID >= this value is a referee, < this value is a player;
int myCode = 1; // This is your unique player code;
int myLevel = 1; // This is your starting level;
int maxShots = 6; // You can fire 6 safe shots;
int maxHits = 3; // After 6 hits you are dead;
int myShots = 0; // You can fire 6 safe shots;
int myHits = 0; // After 6 hits you are dead;
int maxLevel = 9; // You cannot be promoted past level 9;
int minLevel = 0; // You cannot be demoted past level 0
int refPromote = 0; // The refCode for promotion;
int refDemote = 1; // The refCode for demotion;
int refReset = 2; // The refCode for ammo reset;
int refRevive = 3; // The refCode for revival;
int replySucc = 14; // the player code for Success;
int replyFail = 15; // the player code for Failed;
void setup() {
pinMode(blinkPin, OUTPUT);
pinMode(speakerPin, OUTPUT);
pinMode(senderPin, OUTPUT);
pinMode(triggerPin, INPUT);
pinMode(sensorPin, INPUT);
randomSeed(analogRead(0));
for (int i = 1;i < 4;i++) {
digitalWrite(blinkPin, HIGH);
playTone(900*i, 200);
digitalWrite(blinkPin, LOW);
delay(200);
}
Serial.begin(9600);
Serial.println("Ready: ");
}
void loop() {
senseFire();
senseIR();
if (ret[0] != -1) {
playTone(1000, 50);
Serial.print("Who: ");
Serial.print(ret[0]);
Serial.print(" What: ");
Serial.println(ret[1]);
if (ret[0] >= playerLine) {
if (ret[1] == refPromote) {
// Promote
if (myLevel < maxLevel) {
Serial.println("PROMOTED!");
myLevel++;
playTone(900, 50);
playTone(1800, 50);
playTone(2700, 50);
}
} else if (ret[1] == refDemote) {
// demote
if (myLevel > minLevel) {
Serial.println("DEMOTED!");
myLevel--;
}
playTone(2700, 50);
playTone(1800, 50);
playTone(900, 50);
} else if (ret[1] == refReset) {
Serial.println("RESET!");
myShots = maxShots;
playTone(900, 50);
playTone(450, 50);
playTone(900, 50);
playTone(450, 50);
playTone(900, 50);
playTone(450, 50);
} else if (ret[1] == refRevive) {
Serial.println("REVIVED!");
myShots = 0;
myHits = 0;
myLevel = 1;
playTone(900, 50);
playTone(1800, 50);
playTone(900, 50);
playTone(1800, 50);
playTone(900, 50);
playTone(800, 50);
}
} else {
if (ret[1] == replySucc) {
playTone(9000, 50);
playTone(450, 50);
playTone(9000, 50);
Serial.println("SUCCESS!");
} else if (ret[1] == replyFail) {
playTone(450, 50);
playTone(9000, 50);
playTone(450, 50);
Serial.println("FAILED!");
}
if (ret[1] <= maxLevel && ret[1] >= myLevel){
if(myHits < maxHits) {
Serial.println("HIT!");
myHits++;
playTone(9000, 50);
playTone(900, 50);
playTone(9000, 50);
playTone(900, 50);
}else{
Serial.println("DEAD!");
playTone(1000, 50);
playTone(9000, 50);
}
}
}
}
void senseIR() {
int who[4];
int what[4];
int end;
if (pulseIn(sensorPin, LOW, 50) < startBit) {
digitalWrite(blinkPin, LOW);
ret[0] = -1;
return;
}
digitalWrite(blinkPin, HIGH);
who[0] = pulseIn(sensorPin, LOW);
who[1] = pulseIn(sensorPin, LOW);
who[2] = pulseIn(sensorPin, LOW);
who[3] = pulseIn(sensorPin, LOW);
what[0] = pulseIn(sensorPin, LOW);
what[1] = pulseIn(sensorPin, LOW);
what[2] = pulseIn(sensorPin, LOW);
what[3] = pulseIn(sensorPin, LOW);
end = pulseIn(sensorPin, LOW);
if (end <= endBit) {
Serial.print(end);
Serial.println(" : bad end bit");
ret[0] = -1;
return;
}
Serial.println("---who---");
for(int i=0;i<=3;i++) {
Serial.println(who[i]);
if(who[i] > one) {
who[i] = 1;
} else if (who[i] > zero) {
who[i] = 0;
} else {
// Since the data is neither zero or one, we have an error
Serial.println("unknown player");
ret[0] = -1;
return;
}
}
ret[0]=convert(who);
Serial.println(ret[0]);
Serial.println("---what---");
for(int i=0;i<=3;i++) {
Serial.println(what[i]);
if(what[i] > one) {
what[i] = 1;
} else if (what[i] > zero) {
what[i] = 0;
} else {
// Since the data is neither zero or one, we have an error
Serial.println("unknown action");
ret[0] = -1;
return;
}
}
ret[1]=convert(what);
Serial.println(ret[1]);
return;
}
void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
int convert(int bits[]) {
int result = 0;
int seed = 1;
for(int i=3;i>=0;i--) {
if(bits[i] == 1) {
result += seed;
}
seed = seed * 2;
}
return result;
}
void senseFire() {
trigger = digitalRead(triggerPin);
if (trigger == LOW && fired == false) {
Serial.println("Button Pressed");
fired = true;
myShots++;
if (myHits <= maxHits && myShots > maxShots && random(1,20) <= myShots) {
Serial.println("SELF DESTRUCT");
selfDestruct();
} else if (myHits <= maxHits) {
Serial.print("Firing Shot : ");
Serial.println(myShots);
fireShot(myCode, myLevel);
}
} else if (trigger == HIGH) {
if (fired == true) {
Serial.println("Button Released");
}
// reset the fired variable
fired = false;
}
}
void fireShot(int player, int level) {
int encoded[8];
digitalWrite(blinkPin, HIGH);
for (int i=0; i<4; i++) {
encoded[i] = player>>i & B1; //encode data as '1' or '0'
}
for (int i=4; i<8; i++) {
encoded[i] = level>>i & B1;
}
// send startbit
oscillationWrite(senderPin, startBit);
// send separation bit
digitalWrite(senderPin, HIGH);
delayMicroseconds(waitTime);
// send the whole string of data
for (int i=7; i>=0; i--) {
if (encoded[i] == 0) {
oscillationWrite(senderPin, zero);
} else {
oscillationWrite(senderPin, one);
}
// send separation bit
digitalWrite(senderPin, HIGH);
delayMicroseconds(waitTime);
}
oscillationWrite(senderPin, endBit);
playTone(100, 5);
digitalWrite(blinkPin, LOW);
}
void oscillationWrite(int pin, int time) {
for(int i = 0; i <= time/26; i++) {
digitalWrite(pin, HIGH);
delayMicroseconds(13);
digitalWrite(pin, LOW);
delayMicroseconds(13);
}
}
void selfDestruct() {
myHits = maxHits+1;
playTone(1000, 250);
playTone(750, 250);
playTone(500, 250);
playTone(250, 250);
}