Introduction: The Twins Electronic Game

About: We love to tinker. There is nothing that we can't do if it involves Arduino. Challenge us: Do you have an idea for something you would like to have but don't know how to make it? Submit us your idea & if you'r…

In one evening, you can easily create this fun & versatile game for 2 users.
NOTE: You will need 2 of everything, that is why it is called "The Twins".

It starts with a PCB you can create yourself or purchase already made from

Add to that a simple Arduino Nano or Pro/Mini, an LCD & an RF24 Wireless Transmitter, an Open Source sketch & voila, you are ready for some fun action!

The principle is simple: You need the button on each twin to be pressed at the same time, to complete the challenge & proceed to the next step. The twins can be any distance apart up to approx. 300 ft and will still be able "to see" each other...

Step 1: Assemble a Twin

This is really an easy project to accomplish whether you only buy the PCB, or the kit.

1. Solder Arduino Pro/Mini (or Nano) pins on back side of PCB (S&T in upper right corner). Don’t forget the 2 little pro/mini pins that go between the 2 rows: A string of 12 pins on one side, a string of 12 with the 5th pin missing on the other side with the 2 isolated pins behind this gap.
2. Solder the 2 groups of 6 pins on front side of PCB for the LCD. DO NOT solder LCD yet.
3. Solder Pro/Mini (or Nano) on back side
4. Solder LCD on front side after applying 2 layers of double sided tape to the back of the LCD.
5. Test assembly by transferring & running the Twin Sketch on the Arduino with power through USB cable connected to laptop. Troubleshoot if Display errors. It is normal for the display to have a little flicker from USB Power. 9-Volt battery will later correct this.
6. Solder RF24 on front side.
7. Solder Push Button
8. Solder On/Off switch interrupting either one of the 9 Volt connectors, as shown below. Solder resulting assembly to board, making sure to respect polarity.
9. After making sure you change the one line in the code depending on which twin you program, download your Twin sketch to the Arduino.
10. Test Assembly (you will need to have both twins powered up for full functionality).

Step 2: Program the Twins

You can implement the functionality in a multiple different ways.
The example below (that we use in Geocaching challenges) uses the same code for both Twins and we change only one line depending on which Twin we program (Thank You Rion for this clever coding!).

// F.D.R. Geo-Project Twin Multi-Stage GeoCache
// This is the Final Twin code
// This requires an RF24L01 Receiver & a Parallel LCD on Nano
// User supplies 9 Volt battery

#include <LiquidCrystal.h>
#include <SPI.h>
#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <nRF24L01.h>

LiquidCrystal lcd(2, 3, A0, A1, A2, A4);
#define pinUnused 0 
#define deviceNumber 1               // 1 or 2: The only thing to change between devices
#define device1Name  "TwinOne" 
#define device1Final  " N 32 " 
#define device1Alone  "Awaiting Romulus" 
#define device2Name  "TwinTwo" 
#define device2Final  " W 84 " 
#define device2Alone  "Awaiting Remus." 
// #define RF_DR_LOW   5 
// #define RF_PWR_LOW  1 
// #define RF_PWR_HIGH  2 
#define cacheMessage   "FDR TwinGeocache" 
#define keyMessage " -> GOODLUCK <-" 
#define successMessage  "Final Position: "

int rate;

void setup(){

  pinMode(5, OUTPUT); //LCD V0 Pin to control Brightness
  analogWrite(5,120); //120 seems like good Brightness level under 9 Volts
  Mirf.cePin = 9;   //ce pin on Uno
  Mirf.csnPin = 10;  //csn pin on Uno
  Mirf.spi = &MirfHardwareSpi;
  Mirf.setRADDR( ( deviceNumber == 1 ) ? (byte*)device1Name : (byte*)device2Name ); 
// Mirf.setRADDR((byte *)"serv1");
  Mirf.setTADDR( ( deviceNumber == 1 ) ? (byte*)device2Name : (byte*)device1Name );
// Mirf.setRADDR((byte *)"clie1");
  Mirf.payload = sizeof(rate);
  randomSeed( analogRead( pinUnused ) ); 
  displayMessage( cacheMessage, keyMessage ); 
  delay( 4000 ); 

void displayMessage( const char* line1, const char* line2 ) 

  lcd.setCursor(0, 0);
  lcd.print( line1 );
  lcd.setCursor(0, 1);   
  lcd.print( line2 ); 

void sendData( void ) 
  unsigned long now = millis(); 
  Mirf.send( (byte*)&now ); 
  while( Mirf.isSending() ) 
   delay( random( 10 ) ); 

bool readData( void ) 

  bool dataFound = false; 
  while( Mirf.dataReady() ) 
   byte data[Mirf.payload]; 
   dataFound = true; 
  return dataFound; 

void loop(){
  if( readData() == true ) 
   displayMessage( keyMessage, ( deviceNumber == 1 ) ? device1Final : device2Final ); 
   unsigned long now = millis();
   while( millis() <= (now + 1000) ) 
   displayMessage( cacheMessage, ( deviceNumber == 1 ) ? device1Alone : device2Alone );
   unsigned long now = millis();
   while( millis() <= (now + 1000) ) 

Step 3: Feedback Is a Gift!

Described here was only 1 other use of this versatile LBE (Location Based Entertainment) board.
We are sure you can see all sorts of Entertainment possibilities brought by modifications to the code or various sensors/hardware changes.

We want to build a community of DIY Geocachers to elevate the Geocaching hobby to the next level.
Please don't hesitate to post ideas/suggestions whether you are involved in Geocaching or not...

Boards are available through and more pictures are available on our blog at

Thank You for reading!

Supercharged Contest

Participated in the
Supercharged Contest

123D Circuits Contest

Participated in the
123D Circuits Contest