Introduction: DIY Gamer Kit - Infrared Tutorial

About: Technology Will Save Us is a haberdashery for making technology in everyday life. We design, manufacture and sell DIY technology Kits and run workshops to help people become makers and creators of technology, …

This simple tutorial will show you how to use the DIY Gamer Kit's infrared transmitter and receiver. Once you've harnessed its power, you'll be able to make your own multiplayer game in no time!

When the start button is pressed, we'll send a message to the other Gamer and get it to play an animation once it's received it.

Remember that you need two Gamers to go through this tutorial! Otherwise, you won't be able to test your code.

Make sure you've installed the Gamer library - instructions here.

Make sure you've also installed the GamerIR library, which allows you to use the infrared functions - instructions here.

Step 1: Set Up Your Arduino Sketch

The first thing we need to do is open up a new Arduino window.

Once we have it open, we're going to set up our bare-minimum program.

Firstly, we need to include the Gamer library. We also need to include the GamerIR library, which is responsible for sending and receiving data between Gamers.

Next, we need to include the SoftwareSerial library, which is required by the GamerIR library.

After we include all the necessary libraries, we need to make a copy of them (otherwise known as an instance). Let's name the Gamer library gamer, and the IR library infrared.

Finally, in our setup, we tell the Gamer to begin. This will start up the Gamer and get it ready to accept our commands!

Hit the compile button (the tick on the top left of the Arduino window) and make sure you don't get compiler errors! If you do, double check that you haven't mistyped or misspelled any part of your code.

#include <Gamer.h>
#include <GamerIR.h>
#include <SoftwareSerial.h>

Gamer gamer;
GamerIR infrared;

void setup() {
  gamer.begin();
}

void loop() {

}

Step 2: Make Animations

We need to make two animations: a "send" animation, and a "receive" animation. When we press a Gamer's start button, the send animation is played. When a Gamer receives an infrared signal from another Gamer, the receive animation is played. It looks really cool when you do something like a wave that flows from one screen to the other. So have a play and find out what works best for you!

Here's the link to our online animator tool:

Once you're ready, copy the animation from the animator, and paste it into your code. The best place to put it is just after the point at which we include the libraries.

Very importantly, remember to change the name of the animations so that they have unique games. We named ours sendAnimation, and receiveAnimation. Be sure to also change the NUMFRAMES definition to something like NUMFRAMESSENDANIMATION and NUMFRAMESRECEIVEANIMATION. A little bit long winded, we know, but this will enable us to keep both animations in our code. This is our result.

#include <Gamer.h>
#include <GamerIR.h>
#include <SoftwareSerial.h>

#define NUMFRAMESSENDANIMATION 12
byte sendAnimation[NUMFRAMESSENDANIMATION][8] = {
		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000},

		{B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000},

		{B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000},

		{B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000},

		{B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000}};

#define NUMFRAMESRECEIVEANIMATION 12
byte receiveAnimation[NUMFRAMESRECEIVEANIMATION][8] = {
		{B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000}};



Gamer gamer;
GamerIR infrared;

void setup() {
  gamer.begin();
}

void loop() {
  
}

Step 3: If Statements

Now that we have our animations and libraries set up, we have to beef up our main loop. We basically have two conditions. If the start button is pressed, play an animation and send an infrared message to another Gamer. Otherwise, if the Gamer receives an infrared message, we should play the receive animation.

For sensing whether the start button has been pressed, we use the isPressed() function.

For checking if we've received anything, we use the infrared.receive() function. We're checking for "h" because that's the message we'll be sending. You can send pretty much any single letter. We've chosen "h", which stands for "high".

Here's what our code should look like.

#include <Gamer.h>
#include <GamerIR.h>
#include <SoftwareSerial.h>

#define NUMFRAMESSENDANIMATION 12
byte sendAnimation[NUMFRAMESSENDANIMATION][8] = {
		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000},

		{B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000},

		{B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000},

		{B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000},

		{B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000}};

#define NUMFRAMESRECEIVEANIMATION 12
byte receiveAnimation[NUMFRAMESRECEIVEANIMATION][8] = {
		{B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000}};



Gamer gamer;
GamerIR infrared;

void setup() {
  gamer.begin();
}

void loop() {

  if(gamer.isPressed(START)) {

  }

  if(infrared.receive() == "h") {

  }
}

Step 4: Sending IR and Playing Animations

Our final step in our code is what happens within the if statements we've just written. When the start button is pressed, we play the send animation and send the "h" character to the other Gamer. When the h character is received through the serial, we play the receive animation.

In order to play our animation, we need to use for loops. If you haven't used them before, have a look at the code that our animator spits out. We're gonna use a pretty similar thing here.

Here's what our code should look like.

#include <Gamer.h>
#include <GamerIR.h>
#include <SoftwareSerial.h>

#define NUMFRAMESSENDANIMATION 12
byte sendAnimation[NUMFRAMESSENDANIMATION][8] = {
		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000},

		{B00000000,
		B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000},

		{B00000000,
		B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000},

		{B00000000,
		B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000},

		{B11111111,
		B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B01111110,
		B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00111100,
		B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00011000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000}};

#define NUMFRAMESRECEIVEANIMATION 12
byte receiveAnimation[NUMFRAMESRECEIVEANIMATION][8] = {
		{B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111,
		B00000000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110,
		B11111111},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100,
		B01111110},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000,
		B00111100},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00011000},

		{B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000,
		B00000000}};



Gamer gamer;
GamerIR infrared;

void setup() {
  gamer.begin();
}

void loop() {
  // Say hi to the other Gamer when the START button is pressed.
  if(gamer.isPressed(START)) {
    for(int i=0; i<NUMFRAMESSENDANIMATION; i++) {
      gamer.printImage(sendAnimation[i]);
      delay(100);
    }
    infrared.send("h");
  }
  // If hi is received, play receive  animation.
  if(infrared.receive() == "h") {
    for(int i=0; i<NUMFRAMESRECEIVEANIMATION; i++) {
      gamer.printImage(receiveAnimation[i]);
      delay(100);
    }
  }
}

Step 5: Test It Out!

Upload your code to two Gamers and try it out!

A few things to experiment with:

  • Try to see how far you can send IR.
  • Can you send it through walls?
  • Infrared bounces around like a crazy bouncy ball. Can you reflect it off of surfaces?
  • Does it work outside? Hint - sunlight has quite a lot of infrared light in it!

Hope you enjoy playing around with your first infrared / multiplayer experiment.

Now try and hack Flappy bird to control it remotely with another Gamer! Or make your own multiplayer game from scratch!