Nintendo Keyless Entry: the Konami Code Remix

About: Twitter: @barbecue_donuts

action_owl's Nintendo Keyless Entry System is my favourite 'ible and I was inspired to make my own version...

In the Konami Code Remix NO modifications need to be made to your classic NES controller and there are more than ONE BILLION potential password combinations - If you want something more secure but with less cultural credibility than the Konami Code.*

Unlike action_owl’s original version, button order is important and the sketch allows for button repetition - The key to this is the buttonState variable you’ll read about later.

In this instructable I have simplified the buttonState variable from my light switch 'ible making the code much easier to read, understand, use and adapt to your own needs...

DISCLAIMER: A 9g Micro Servo and a cardboard box will not keep your valuables safe. The servo and cardboard box are used for demonstration purposes only. I'm still working out where to install it. A few minor changes to the sketch and you can trigger an electronic door strike via an Arduino compatible relay.

*up up down down left right left right B A

Step 1: Equipment

  • Classic NES Controller - I picked one up from Cash Converters for $AU 9.95
  • Arduino UNO - I used a DuinoTECH Classic
  • Jumper wires
  • Micro servo
  • USB cable
  • Breadboard
  • Computer with Arduino IDE
  • Cardboard and tape to make a model for prototype testing - I cut a door out of an old postpak box, cut a hole in that to mount the servo and cut a hole in the adjacent wall to run the jumper wires through

Step 2: Connect Your NES Controller to Your Arduino

  1. Use a black jumper wire to connect Arduino GND to - Breadboard
  2. Use a red wire to connect Arduino +5v to + Breadboard
  3. Use an orange wire to connect Arduino D5 to NES clock*
  4. Use a yellow wire to connect Arduino D6 to NES latch
  5. Use a green wire to connect Arduino D7 to NES data
  6. Use a black wire to connect - Breadboard to NES GND
  7. Use a red wire to connect + Breadboard to NES 5V
  8. Use an orange wire to connect Arduino D3 to Servo Signal
  9. Use a brown wire to connect - Breadboard to Servo GND
  10. Use a red wire to connect + Breadboard to Servo GND

*Jumper wires fit perfectly into the NES controller's pins. Click on each pin in the first picture to find out the function of each pin

Step 3: Get Controller Data: Check Your Classic NES Controller Works

The Konami Code Remix began with the simple sketch below - The NES controller works by sending short pulses of 8-bit information when a button is pressed or not pressed which the Arduino catches* and then uses the switch...case commands in the loop() function to assign a task to each button press. In this case printing the button name on the serial monitor.

* Code from the "Teachbot gamepad controller sketch" by Gordon McComb (in Arduino Robot Bonanza, published by McGraw-Hill in 2013) was used as the getControllerData() function.

/* This sketch reads the NES controller and then prints the button pressed on the serial monitor
8 bit information Arduino receives when BUTTON PRESSED:
right   = b01111111 (BIN) = 127 (DEC)
left    = b10111111 (BIN) = 191 (DEC)
up      = b11011111 (BIN) = 223 (DEC)
down    = b11101111 (BIN) = 239 (DEC)
start   = b11110111 (BIN) = 247 (DEC)
select  = b11111011 (BIN) = 251 (DEC)
b       = b11111101 (BIN) = 253 (DEC)
a       = b11111110 (BIN) = 254 (DEC)


8 bit information Arduino receives when NO BUTTON PRESSED =  b11111111 (BIN) = 255 (DEC)*/


#define nesClock 5 // plug CLOCK into D5
#define nesLatch 6 // plug LATCH into D6
#define nesData 7 // plug DATA into D7

void setup() {
Serial.begin (9600); // Turn on the serial monitor
delayMicroseconds (300); // Wait
Serial.println ("Press buttons to see data displayed on Serial Monitor");
pinMode (nesLatch, OUTPUT); // LATCH is an OUTPUT pin
pinMode (nesClock, OUTPUT); // CLOCK is an OUTPUT pin
pinMode (nesData, INPUT); // DATA is an INPUT PIN
}

byte getControllerData(){ //Gordon McComb's method to get data from controller  
  digitalWrite (nesLatch, HIGH);
  delayMicroseconds (12);
  digitalWrite (nesLatch, LOW);
  byte output = 0;
  for (int i = 0; i<8; i++){
    output |= digitalRead (nesData) << i; // Bitshift
    digitalWrite (nesClock, HIGH);
    delayMicroseconds (6);
    digitalWrite (nesClock, LOW);
    delayMicroseconds (6); 
  }
  return output;
}

void loop(){
getKey = getControllerData(); // Check controller data
getKey = getControllerData();
getKey = getControllerData(); // Check 3x to be certain
delay(180); // wait...
switch(getKey){
  case 255: // if no button pressed 
  return; // start loop again before anything happens
  break;

  case 127: // I used the data in DEC rather than BIN to save typing
  Serial.println("RIGHT"); // If RIGHT is pressed serial monitor will display RIGHT
  break; // Ready for next button press / keystroke

  case 191:
  Serial.println("LEFT");
  break;

  case 223:
  Serial.println("DOWN");
  break;

  case 239:
  Serial.println("UP");
  break;

  case 247:
  Serial.println("START");
  break;

  case 251:
  Serial.println("SELECT");
  break;

  case 253:
  Serial.println("B");
  break;

  case 254:
  Serial.println("A");
  break;
}

Step 4: Sketch

I built on the initial sketch by adding a variable, buttonState,which mimicked pushbutton button states (value of 1 for when button released and a value of 0 for when button pressed) and another variable, setKey, which assigned a value between 1 and 8 to each button pressed.

buttonState allowed for the sketch to cycle through (loop) with each button press, facilitating button repetition and order.
Removing the buttonState variable resulted in the inputArray[] populating in one or two button presses

The setKey values were added to the inputArray[] which was then compared against the MASTER_CODE[] array.

I also added an unlocked() function which was triggered when inputArray[] equalled MASTER_CODE[].

The unlocked() function raises the servo arm so the door can be opened - You can modify this to do whatever you want the Arduino to do once your code has been entered correctly

The sketch is then reset using gabriellalevine's resetFunc().

#include   // Use the Servo library
#define nesClock 5 // CLOCK plugs into D5
#define nesLatch 6 // LATCH plugs into D6
#define nesData 7 // DATA plugs into D7
#define led 13 // Use LED which comes with Uno board
Servo myServo; // Call my servo myServo

int servoPos = 0; //Variable for servo position
int getKey; //Variable used with switch...case command in loop() as part of reading NES controller data
int MASTER_CODE[] = {4, 4, 3, 3, 2, 1, 2, 1, 7, 8}; // Konami code (Up up down down left right left right b a)
//If you don't want to use the Konami code just change the integers and/or number of integers
int inputArray[10]; // Number of integers in input array needs to equal number of integers in the master code
int setKey; // Assigns an integer to each button press and "sets" it in the input array
int buttonState; // Toggles between 1 (released) and 0 (pressed)
int i = 0; //variable used in creating the input array

void setup() {
Serial.begin (9600); // Turn the serial monitor on
delay(300); // wait
Serial.println ("ENTER CODE:"); // get ready to enter your code
pinMode (nesLatch, OUTPUT); // LATCH is an OUTPUT pin
pinMode (nesClock, OUTPUT); // CLOCK is an OUTPUT pin
pinMode (nesData, INPUT); // DATA is an INPUT pin
pinMode (led, OUTPUT); // the LED is an OUTPUT
myServo.attach(3);// attach Servo to pin 3
myServo.write(servoPos); //Start with servo in "locked" position
digitalWrite (led, LOW); // Turn LED off
buttonState = 1; // Start with "button released"
}

byte getControllerData(){ //Gordon McComb Arduino Robot Bonanza 2013
digitalWrite (nesLatch, HIGH);
delayMicroseconds (12);
digitalWrite (nesLatch, LOW);
byte output = 0;
for (int i = 0; i<8; i++){
output |= digitalRead (nesData) << i;
digitalWrite (nesClock, HIGH);
delayMicroseconds (6);
digitalWrite (nesClock, LOW);
delayMicroseconds (6);
}
return output;
}

void(* resetFunc)(void)=0;// gabriellalevine's instructable

void unlocked(){ // You can change this code to make the arduino do what ever you want it to do once Konami Code Entered
Serial.println("UNLOCKED"); // print unlocked
digitalWrite (led, HIGH); // Turn LED on
for (servoPos = 0; servoPos <= 90; servoPos +=1){ //Sweep servo arm to "unlocked" position so door can be opened
myServo.write(servoPos);
delay(15);
}
delay (3000);
digitalWrite (led, LOW); //After 3 seconds give a warning (flashing LED) before servo arm returns to "locked" position
for (i = 0; i <= 10; i++){
digitalWrite(led,HIGH);
delay(200);
digitalWrite(led,LOW);
delay(200);
}
for (servoPos = 90; servoPos >= 0; servoPos -=1){ // Servo arm returns to "locked" position
myServo.write(servoPos);
delay(15);
}
resetFunc(); // Reset sketch
}

void loop(){
if(buttonState == 1){ // If button released:
getKey = getControllerData(); // Check if button pressed
getKey = getControllerData();
getKey = getControllerData(); // Check 3x to be certain
delay(180);
switch(getKey){
case 255: // if no button pressed start loop() again
return;
break;

case 127: // RIGHT button pressed
Serial.println("RIGHT = 1");
buttonState = 0; // button is pressed
setKey = 1; // will assign a number to inputArray
break;

case 191: // LEFT button pressed
Serial.println("LEFT = 2");
buttonState = 0;
setKey = 2;
break;

case 223:
Serial.println("DOWN = 3");
buttonState = 0;
setKey = 3;
break;

case 239:
Serial.println("UP = 4");
buttonState = 0;
setKey = 4;
break;

case 247:
Serial.println("START = 5");
buttonState = 0;
setKey = 5;
break;

case 251:
Serial.println("SELECT = 6");
buttonState = 0;
setKey = 6;
break;

case 253:
Serial.println("B = 7");
buttonState = 0;
setKey = 7;
break;

case 254:
Serial.println("A = 8");
buttonState = 0;
setKey = 8;
break;
}
}
if (buttonState == 0){ // if button / key pressed place that key (setKey) in the appropriate spot in the array
inputArray[i] = setKey; // builds inputArray
i++; //i = i + 1;
buttonState = 1; // button released
}
if (inputArray[0] == MASTER_CODE[0] //Check input array against master code
&& inputArray[1] == MASTER_CODE[1]
&& inputArray[2] == MASTER_CODE[2]
&& inputArray[3] == MASTER_CODE[3]
&& inputArray[4] == MASTER_CODE[4]
&& inputArray[5] == MASTER_CODE[5]
&& inputArray[6] == MASTER_CODE[6]
&& inputArray[7] == MASTER_CODE[7]
&& inputArray[8] == MASTER_CODE[8]
&& inputArray[9] == MASTER_CODE[9]){
unlocked(); //Run "unlocked" function - moves servo arm so door can be opened
}
}

Step 5: Nintendo Keyless Entry

Now I just need to find a nonfunctional NES that I can modify into a project box - making full use of the NES controller sockets - add a relay and an electronic door strike.

The konamiCodeRemix.ino sketch has the potential to be modified and used in other applications such as turning your NES controller into a keyboard, a game show buzzer, or even the controls for a step sequencer...

Have fun!

Share

    Recommendations

    • Trash to Treasure

      Trash to Treasure
    • Arduino Contest 2019

      Arduino Contest 2019
    • Tape Contest

      Tape Contest

    2 Discussions

    0
    None
    conissocool

    26 days ago

    oh my god this was exactly what I was looking for not just the nes lock but it using the Konami code

    1 reply