Building an Arduino-based laser game, Part 1

Arduino basics

Jump-start your electronics projects with the open source hardware and software platform Arduino


Content series:

This content is part # of # in the series: Building an Arduino-based laser game, Part 1

Stay tuned for additional content in this series.

This content is part of the series:Building an Arduino-based laser game, Part 1

Stay tuned for additional content in this series.

Before you start

Whether you're new to Arduino or a seasoned builder, this project has something for you. There's nothing quite as satisfying as creating an interactive physical object, knowing that if it breaks or needs modification, you know where all the parts go and how everything works. The 'Duino tag gun is a great project to work on by yourself or with friends. To complete this project, you should at least have a basic understanding of electronics (you should know what a resistor is, but you don't need to know the science behind one) and have an understanding of programming (you should know what loops and variables are, but you don't need to be able to parse Big O Notation). Don't be afraid to jump right in.

About this series

In this series, we use Arduino technology to create a basic interactive laser game called 'Duino tag:

  • Part 1: Learn some Arduino basics, lay out the project, and do an experiment that will help you understand how Infrared works.
  • Part 2: Build and test the receiver part of the 'Duino Tag gun, including the testing.
  • Part 3: Build the transmitter and complete the 'Duino Tag gun.

About this tutorial

To follow along, you don't need any electronics work experience, although experience working with electronic components can certainly serve you well. The same can be said about working with a microcontroller. If you've worked with microcontrollers, you'll have an edge, but keep in mind that the Arduino platform is well suited for people without that experience. Above all, you should be willing to stretch your skills. Working with electronics and microcontrollers can be a rewarding experience. Most software engineers don't get a chance to write code for devices that interface with the physical world, and Arduino provides a low-cost entry point into working with interactive devices.

This tutorial, Part 1 in a three-part "Building an Arduino-based laser game" series, focuses on Arduino basics. We jump into using Arduino, look at the language basics and API. We prepare for the 'Duino tag project, including design basics and putting together a parts list. We learn about ordering parts online, where to go, and parts we need. Finally, using some stock components and some basic test code, we demonstrate basic principles governing how the gun works.

System requirements

For this tutorial, we need few tools and supplies:

Computer with USB port
While technically not true (many kinds of Arduino hardware interface over old-style serial ports), this series is written assuming you are using a model that communicates over USB. There is Arduino software available for Microsoft® Windows®, Mac OS X, and Linux® (32-bit and AMD-64 bit).
Arduino Diecimila
This is the specific model of Arduino hardware used in this tutorial. You may substitute an Arduino Duemilanove. Order one from a reputable online dealer. Check the Related topics for links.
USB A-B cable
This is like the one you probably have attached to a printer.
Basic 5mm red Light-Emitting Diode (LED)
You might have one already, or you can find one at Radio Shack or an online dealer.
The brighter the better.
Arudino software
See Related topics to download Arduino software.
Installation and setup guides for Arduino
See Related topics to download the Arduino installation guide.

Introduction to Arduino

In this section, we present Arduino hardware basics, how to get set up, and how to program the software with a brief language primer.

What is Arduino?

In overly simplified terms, an Arduino board is a microcontroller — a tiny computer with various input and output pins. Using the these pins, you can create myriad interactive devices ranging from something as simple as a blinking light to complex devices that use a wide range of input to create complex behaviors using servos and motors. The first Arduino was produced in January 2005 by two teachers — David Cuartielles and Massimo Banzi — at the Interaction Design Institute in Milan. See Related topics for a Wired magazine article profiling Arduino's developers.

The Arduino platform is made up of two parts: the hardware (including the microcontroller, circuit board, etc.) and the software (the programming interface and language). Both parts of the platform are open source. If you wish, you can download the schematics for Arduino, buy all of the individual parts needed, cut a circuit board, and make one from scratch. There are a number of different projects, like the Freeduino, that have done just that. The schematics and CAD files have been released under the Creative Commons Share-Alike license. The software used to program Arduino is also open source. It was written in the Java™ programming language and released under the GPL (there are some C/C++ microcontroller libraries that have been released under the LGPL).

There are several microcontroller platforms available, and many of them focus on the same goals: make it easy to program and interface with the microcontroller, wrap up everything in one package, etc. Similarly, Arduino aims for a simple interface and an all-in-one package, while trying to offer additional benefits:

Low cost
One can build an Arduino board from scratch for little money, and pre-assembled units are inexpensive. An Arduino Diecimila costs about $35.
Cross-platform software
Get Arduino software for Microsoft Windows, Mac OS X, and Linux.
Simple language
Arduino developers try to keep the language easy to use for beginners, but flexible enough for advanced users.
Open source
From the top down, Arduino is completely open source. If you want to build your own or modify the software, you're free to do so. Furthermore, the official Arduino Web site contains an extensive wiki where code samples and examples are shared freely.

There is a great deal of Arduino information available. The best place to start is at the official Web site (see Related topics). Take the time to read the excellent introduction on that site.

Getting started

To interface with Arduino hardware, you need to install the software. Download it for your operating system and follow the appropriate step-by-step installation and setup guide (see System requirements). They follow the same steps:

  1. Unpack the software
  2. Install the USB driver for Arduino
  3. Connect the board
  4. Launch the software
  5. Upload an example

We won't cover each step in detail, as they differ from environment to environment. Let's discuss the software and the Blink example.

Note: In Arduino parlance, individual scripts and programs are referred to as "sketches."

Once we launch the software and load the Blink example (per the instructions in the Getting Started Guide), you should see something that looks like Figure 1.

Figure 1. The Arduino software interface
The Arduino software interface
The Arduino software interface

Touching on the interface briefly, the top row of buttons control basic tasks like compiling, creating and saving files, uploading code to the Arduino board, and turning on or off the Serial Monitor (more on that later). The middle pane contains all of the code for the Blink example, and the bottom pane displays console output, compile errors, and serial messages (when the Serial Monitor is turned on). For now, let's focus on that middle pane and discuss the Arduino language.

Arduino language basics

The Arduino language is based on C/C++, and if you've used this language before, the constructs and features will be familiar. Although a full review of the language is outside the scope of this tutorial, let's take apart the Blink example and learn a little about the language. Some of this may be a little basic if you're accustomed to working with code, so if you'd rather grab a manual and dive in, feel free to jump into the extended language reference (see Related topics for the extended language reference).

First, see the big block of comments. Comments in the Arduino language are written in two styles.

Listing 1. Block style
 * Block Style like this

Or they can be written in inline style.

Listing 2. Inline style
// inline like this

Next, notice that we declare a variable: int ledPin = 13;.

This line tells you immediately that lines in the Arduino language end with semicolons. Additionally, this tells us almost everything we need to know about declaring variables in the Arduino language. The syntax: State the variable type, state the variable name, set the variable's initial value. In addition to the int type, the Arduino language supports unsigned int, Boolean, char, unsigned char, byte, long, unsigned long, float, double, string, and array. Find details about each data type in the Arduino Language Reference, but take a moment to look at the array type. Each method shown in Listing 3 is acceptable when declaring an array.

Listing 3. Methods for declaring an array
int fourlong[4];  // creates an empty array, 4 elements long
int nolength[] = {8,18,32,64};  // the compiler will figure out how long this array is
int setboth[4] = {8,18,32,64};  // This creates a 4 element array 
                                // and sets the initial value
char someword[7] = "fizbin";  // You need to add one extra element for a null character

If you have a Web development background, these arrays may look a little weird. Don't worry. They will make more sense as we begin to use them.

Note: Arrays are zero-indexed.

Listing 4 shows the setup function.

Listing 4. setup function
void setup()
  pinMode(ledPin, OUTPUT);

This function will be run once when the Arduino board is reset. Every sketch must have a setup function, even if the function is empty. In this case, the setup function is used to set the mode for one of the pins on Arduino hardware. Ignore the pinMode statement for now and look at the structure of the function. Functions are declared by stating their return type (in this case, void indicates the function will return no value) and the function name. Following the function name, any required parameters are declared within parenthesis. The setup function accepts no parameters, but if we want to create a function that accepts one or more parameters, we declare the parameters just as if we were declaring a variable.

Listing 5. Declaring parameters
void someFunction(int a, int b=2)

Finally, we see that the function code is wrapped in curly braces.

Following the setup function is another function called loop.

Listing 6. loop function
void loop()
  digitalWrite(ledPin, HIGH);
  digitalWrite(ledPin, LOW);

Once the setup function has executed, the loop function is called, indefinitely, ad infinitum, until the Arduino board is powered off or until some cataclysmic event creates a rift in space and time. It is in the loop function that we typically do most of our work, listening for sensor input and triggering some form of output. As with the setup function, every sketch must have a loop function, even if the function is empty.

In addition to what we learned from the Blink example, there are other things to mention briefly about the Arduino language:

  • Most familiar control structures are supported (if, while, for, switch, etc.).
  • Arithmetic, comparison, Boolean, bitwise, and compound operators are all fairly standard.
  • The language natively supports some math, time, trigonometric, random number, and serial communication functionality.
  • We can include external libraries using #include statements at the top of the sketch.

In addition to all of this standard functionality, there are a number of language elements unique to Arduino. These constructs (like the pinMode and digitalWrite functions you saw above) are primarily concerned with dealing with the many input and output pins on your Arduino. There is an extensive language guide on the Arduino site (see Related topics).

OK — Enough introductory material about Arduino. Let's take a look at this project, what you're going to learn from it, and what challenges you will face.

Preparing to make the 'Duino tag gun

If you've never worked with Arduino or any other microcontroller, this might seem like a big project to use as a starting point. It is. This project presents several interesting challenges to overcome. But this project will be equally rewarding — personally and socially. Let's look at these challenges and rewards. In this section, we start making the 'Duino tag gun.

Why build a 'Duino tag gun?

The official Arduino page is loaded with sample projects, most of which would be easier than diving into something like a laser-tag gun. Building a 'Duino tag gun will present some unique challenges, as well as offering some awesome extra benefits.

For one thing, working with infrared is complicated. (Sorry, no actual lasers will be used during the course of this tutorial.) Infrared is more complicated than you may realize (certainly more complicated than I thought when I first set out on this project). For one thing, infrared light is all over the place, and it bounces off everything (if you've ever bounced the signal from a remote control off a wall or picture, you already know this). It's one thing to deal with a complex data algorithm, or to work on code that has to handle millions of requests per second. It's something else completely to try and deal with a real-world source of interference like the sun. The same problem-solving approaches used when writing code can be useful in trying to work with physical-world problems.

Additionally, once you are able to wrap your hands around working with infrared, you open up a huge range of potential projects you might never have considered — from something as simple as interacting with your TV to creating inexpensive interactive devices that communicate with each other over IR to controlling different parts of your computer using a remote control of your own design.

In addition to dealing with the complexities of infrared, you will find that there is a timing issue in play. The goal is to build one device that acts as both a gun that emits infrared and a detector that registers hits from another legitimate infrared source. There will be a bit of a challenge in dealing with this particular issue, and you will find some benefit (and hopefully some pleasure) in working through the various elements of this particular challenge.

Socially speaking, this is a great project to work on with friends. I quite enjoy creating devices in my own workshop, but sometimes it's fun to sit around the table with some friends and work on something together. Because these devices are intended to interact with each other, it's almost impossible to build only one. By involving friends, you make your own work easier. You've got more sensors to shoot and more guns to test your own sensor. That leads to the inevitable conclusion: It's fun. Once your 'Duino tags are up and running, you will be compelled to fire on your friends immediately.

And finally, rather than buying a ready-made, unhackable device from a store, you've collectively created your own thing. If you don't like how it works, you change the device or change the rules. You may end up spending a little more than you would for a cheap off-the-shelf unit, but in the end, you'll have something you can field-strip, reprogram, and bend to your will. That's just not something you can buy from your favorite national chain of toy stores.

Now that you're sold on the project, let's talk about the 'Duino tag gun. What will it do? How will it work? What components will you need? How will you case the electronics?

Designing the 'Duino tag gun

Before we can start designing the gun, we need to talk about how we want the whole thing to work. I've made some statements and assumptions along the way, so let's spell everything out so it's clear. Let's talk about how this gun works:

  1. When the player pulls a trigger, a single shot is fired.
  2. When the gun is a fired, it should make a cool sound like "PEW PEW."
  3. The gun will also be used to detect hits.
  4. When a hit is detected, the gun should make a different cool sound, like "KZZKH KZZKH."
  5. Each gun has a certain amount of shots that can be fired.
  6. When the gun is out of ammo, and the player pulls the trigger, the gun should play a third sound like "EEERK EEERK."
  7. When the player is eliminated, the gun should play one final sound, like "BOOM KAPOW" (OK — that's two sounds).

There are more rules variations that could be added here, but this is a great place to start. In the code we will write, we will establish the following ruleset:

  • Each gun has six safe shots. There is no reload. These shots may be fired without danger.
  • Each player can take six hits. Once you have take six 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.

In somewhat more plain English, you can be hit six 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.

Based upon these simple rules and some statements from earlier in the tutorial, we can establish some basics about the hardware:

  1. 'Duino tag is based on infrared.
  2. The gun acts as an emitter and a sensor.
  3. The gun needs some kind of trigger.
  4. The gun has sounds.
  5. The gun should be durable

This tutorial will not spend too much time talking about how to case your 'Duino tag gun. Once we have the electronics worked out, we cover options for creating or appropriating different cases for the project. Now that we have the behavior laid out, it is time to spec the hardware. But we won't get very far without a bit of a discussion about how infrared sensors work.

Dealing with infrared

As mentioned, infrared radiation surrounds us. The sun emits it, as do lamps, TVs, and animals (the "pit" in pit viper refers to the shape of the sensor this family of snakes has that they use for finding prey). If we 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 require a particular type of IR sensor. We discuss that now as we cover the parts needed and where to get them.


As mentioned, we need an Arduino board. Let's look at what else is required.

Infrared LED
There's nothing special about the LED. I used a T1 three-quarter IR LED from All Electronics.
Infrared sensor
This series was written using a TSOP2138YA Infrared Sensor (also from All Electronics).
Single-pole momentary switch
This is the trigger, so we want something that's not too small and not too big.
Piezo element
We use this to make sounds. I suggest using a small, encased one.
22-gauge solid or stranded wire
We need two colors. We don't need much — a meter at most.
We need a couple different resistors. One 100Ω resistor (that's 100 ohm, or Brown-Black-Brown), one 10kΩ resistor (that's 10000 ohm, or Brown-Black-Orange), and one 82Ω resistor (that's 82 ohm, or Grey-Red-Black).
We will need one 0.1uF capacitor.
A small magnifying lens (three-quarters to 1 inch in diameter) — for this first time through, you can use a cheap plastic one given as a party favor.
A short length of PVC or other rigid tubing.

These parts cost $5 or less, depending on where you shop.

Where to find parts

You should be able to walk into Radio Shack and find what you need to complete this series. If you'd rather order from an online dealer, here are three recommendations:

Offers a variety of electronic components and reasonable prices
Another excellent source of electronic components online
All Electronics Corp.
Selection is a little more narrow than the other two, but I have been a happy customer

See Related topics for these online retailers. Alternately, a simple Web search will turn up many options. If you decide to order elsewhere, keep these four points in mind:

  1. Check the delivery time, especially when ordering from eBay sellers. You can find many electronic components from eBay sellers, but frequently the items are shipped directly from China, which can take a week or two.
  2. Don't order anything that doesn't have a spec sheet. All electronic components have what's known as a spec sheet that lists a lot of vital information about voltage and wiring and so forth. If you don't have this information on hand, you may find working with your components challenging.
  3. Shop around. Component prices vary widely. Don't be afraid to cross-reference the prices offered on different sites. Unless you are placing large orders, it won't make much sense to order sensors from one site and LEDs from another. But you should still verify that you're getting a competitive price.
  4. Be precise with model numbers, especially with the IR sensor. That may seem really obvious if you have worked with electronics before, but it may be less obvious if you are new to this. IR sensors have many makes and models, and are similar in appearance but dissimilar in frequency. Frequency is important.

While waiting for parts to arrive, let's do something neat with your Arduino. This will help whet your appetite for the project, as well as introduce a little-known capability of the LED. This experiment won't end up being part of the finished project, but it should help you come to a better understanding of how frequency works. Plus, it lets you get your hands dirty working with Arduino software and hardware.

Experimenting with Arduino

Let's conduct a little experiment that teaches us something new about LED, and helps us understand this whole frequency thing.

A neat trick to whet your appetite

Earlier, we said we need an LED and a flashlight to complete this tutorial. We've already used the LED during the Blink example. Let's use that same LED to detect light. Yes, to detect light. In addition to blinking, shining, and blinding, LED can be used to detect light. For best results, use a colored LED (such as red) and a normal white flashlight (the brighter the better).

Start by taking an LED and plugging the anode (the positive side — typically, the long end) into the 0 Analog In pin at the bottom of the board. Plug the cathode (the negative side — typically, the short end) into one of the two Ground pins (marked "GND") at the bottom of the board.

Next, we're going to write just a tiny bit of code to listen to the 0 Analog pin and output the reading to the serial monitor (I did say we'd come back to this).

Listing 7. Listening to the 0 Analog pin and outputting the reading to the serial monitors
/* 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

  void loop()
    // Take a reading from the Analog Pin
    val = analogRead(recvPin);
    // Output the detected value
    Serial.print("DETECT : ");
    // Wait to take the next reading.

You can see there's not much to this code. We set up a couple variables, initialize the serial interface, then take readings from the analog input once a second. It's a simple script, but it's a really cool effect. Save the script and upload it to the Arduino hardware. Once the upload is complete, click the Serial Monitor button at the top of the Arduino window. This will reset the Arduino board, after which you should start to see some readings appear in the bottom pane. Darken light sources and look at the readings. They should look something like Figure 2.

Figure 2. Light sensor readings in the dark
Light sensor readings in the dark
Light sensor readings in the dark

The actual number reported may vary widely depending on how much ambient light there is, what kind of LED you use, etc. Next, turn on a flashlight and shine it on the LED. You should notice a marked increase in the detected value. In the first screenshot, the readings came in at about 167-168. But look at the readings in Figure 3.

Figure 3. Light sensor readings in the dark with direct light from the flashlight
Light sensor readings in the dark with direct light from the flashlight
Light sensor readings in the dark with direct light from the flashlight

You can see that the analog input, which runs on a scale of 0-1,023, jumped by almost 90 when the flashlight was shining on the LED. Again, the numbers may vary widely, depending on ambient light, LED choice, and strength of the flashlight. But this is light sensing at its most basic.

Now, for comparison, turn on several lights around the Arduino hardware, so there is a lot of ambient light and notice how the baseline goes up.

Figure 4. Light-sensor readings with the lights on
Light-sensor readings with lights on
Light-sensor readings with lights on

You can see the baseline numbers have gone up by about 40, making a somewhat less-distinct jump when the LED comes into contact with other light sources. In this example, we can still tell when the flashlight is directly shining on the LED.

Figure 5. Light-sensor readings with the light on and direct light from the flashlight
Light-sensor readings with the light on and direct light from the flashlight
Light-sensor readings with the light on and direct light from the flashlight

But if you had to deal with much more ambient light, or if you had to deal with something that would diffuse the light source (such as the light being further away from the LED), the numeric differences would become more and more subtle. To illustrate this, set up Arduino in such a way that you shine the flashlight on the LED from across the room, then examine the results.

In addition to showing a cool new way to use a basic LED, this example helps illustrate the difficulty inherent with dealing with ambient visible light and light detection. You can imagine how much more complicated this problem becomes when dealing with something like infrared, which is both nearly omnipresent and invisible to the naked eye.

A simple demonstration of frequency

Now that the light sensor working, modify the code and use it as an opportunity to learn a little bit about frequency. As we learned earlier, infrared is everywhere, so sensors need to filter out anything not being transmitted at a specific frequency. Let's demonstrate in this section, 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.

Modifying the code

We will 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. First, we declare some additional variables. We need 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 we are expecting, an iterator, an array to hold the different codes, and a tracking int to tell where we are in a cycle.

Listing 8. Declaring variables
  int recvPin = 0;
  int wait = 1000;
  int val = 0;
  int readings = 5;
  int jump = 0;
  int i = 0;
  int code[2];
  int incycle = 0;

Next, we need to take a set of readings during setup, average them, and determine what 5 percent means. In my experience, the first reading is always abnormally high, so we throw that one out right away.

Listing 9. Taking a series of readings
  void setup()
    // Initialize the Serial Interface
    Serial.print("establishing baseline... ");
    val = analogRead(recvPin); // throw out the first one, it's usually high.
    for (i = 0; i < readings;i++)
      jump += analogRead(recvPin);
    jump = (jump / readings)*1.05;
    // Output the detected value

Finally, during the 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.

Listing 10. Reading the pin
  void loop()
    // 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");
      case 1:
         if (val > jump)
           code[0] = 1;
         } else {
           code[0] = 0;
         incycle = 2;
         Serial.println("Read One");
      case 2:
        if (val > jump)
          code[1] = 1;
        } else {
          code[1] = 0;
        incycle = 3;
        Serial.println("Read Two");
      case 3:
        if (code[0] == 0 && code[1] == 0) 
        } 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) 
        code[0] = 0;
        code[1] = 0;
        incycle = 0;

If you save and upload this code (you need to turn on the serial monitor after every upload), you should see when the readings are being done. By shining a flashlight on the LED, you can trigger a cycle. The next two readings (one second apart) determine what final code is output. You can trigger the different outputs by alternately turning the flashlight on and off at a frequency of once per second. For example, if you just shine your flashlight on the LED for three seconds, you should trigger the "Explode" message. If you turn your flashlight on for one second, off for one second, and one for one second, you should trigger the "Turn Off" code. Here's a sample of the output.

Figure 6. Basic frequency example
Basic frequency example
Basic frequency example

What you're doing here is signaling a binary message at a very low frequency. This is similar to what the 'Duino tag guns will do, though they will do it at a much higher frequency.

You should now be prepared to dive into creating and testing the 'Duino tag gun, which is covered in the remainder of the series.


Before you jump into Part 2, you should assemble some supplies:

  • A soldering iron and some solder. You need nothing fancy here since you will not do any fine or complex soldering.
  • A pair of wire cutters/strippers. Advice: Don't use your teeth to strip the wire.
  • The electronic components outlined earlier.

Spend time exploring the Arduino site and working through some of the tutorials. Take the LED light-sensor code and see what else you can do with it. Perhaps most importantly, recruit friends to complete this project with you. It will be more rewarding (and easier for you) if there are other people involved.

Downloadable resources

Related topics


Sign in or register to add and subscribe to comments.

Zone=Open source
ArticleTitle=Building an Arduino-based laser game, Part 1: Arduino basics