Project: Arduino NES Controller

  1. Project: Bugtrakt
  2. Project: Imgalib
  3. Project: Go Fish!
  4. Project: trewest.dev
  5. Arduino Light effects
  6. Project: Mini Stacker
  7. Project: Arduino NES Controller
  8. Project: Metroidvania-Like
  9. Project: Susminer
  10. Project: Farming Demo
  11. Project: VRC Basement
  12. Project: Hash Clear
  13. Project: Titan Help
  14. Project: Computer Craft Scripts
  15. Project: ESP8266 Plant Watering
  16. Project: Golf Demo
  17. Project: Ghost Holic
  18. Project: Multi-Chat Viewer

Status: Complete
Type: Microcontroller
Technology: C++, PlatformIO, Arduino

While learning Arduino I wanted to see if I could use a Nintendo Entertainment System controller to interface, and as it turns out there’s good diagrams of the pinout the controller uses, and since it’s keyed it’s very easy to understand.

And turns out I had no idea what I was looking at, so after learning about shift registers I had to write my own code to push through it… but it did work! After some effort figuring out how the data was mapped in serial. Sadly though I don’t have much more to write about it though, since the code’s just reading a data pulses and interpreting them as input.

#include <Arduino.h>
#include <FastLED.h>

int clk = 4;
int latch = 6;
int data= 8;

bool a = false;
bool b = false;
bool start = false;
bool select = false;
int pad = 0;

int red= 2;
int yellow = 3;
int green = 11;
int blue = 12;

int pos = 60;
CRGB color = CRGB(0,255,0);

#define STRIP_SIZE 120
CRGB leds [STRIP_SIZE];


void setup() {
  // put your setup code here, to run once:

  //Begin serial output
  Serial.begin(9600);

  FastLED.addLeds<NEOPIXEL, 7>(leds, 120);

  pinMode(data, INPUT);//Getting our data input
  pinMode(clk, OUTPUT); // Clock output
  pinMode(latch, OUTPUT);

  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(blue, OUTPUT);

  
}

void printBin(byte inByte) 
//if you try print 00011101 you will get 1101 as the leading zeros don't print
//this prints a bin number with all the leading zeros and a space between nibbles
{
  for (int b = 7; b >= 4; b--) {
      Serial.print(bitRead(inByte, b));  
      Serial.print(" "); 
      }
  for (int b = 3; b >= 0; b--) {
      Serial.print(bitRead(inByte, b));  //now prints:  0001 1101
  }
  Serial.println(); //needs a CR at end
}

bool interpretInput(int num) 
{
  if (num == 0) {return true;};
  return false;
}

void loop() {
  // put your main code here, to run repeatedly:
  //Getting data from the 4021

  pad = 0;
  Serial.println("\nOut:");
  digitalWrite(latch, LOW);
  digitalWrite(latch,HIGH);
  int readable =  digitalRead(data);
  Serial.print(readable);
  a = interpretInput(readable);
  Serial.print(" ");
  digitalWrite(latch, LOW);
  for (int i = 1; i < 8; i++ ) 
  {
    digitalWrite(clk, HIGH);
    int readable =  digitalRead(data);
    digitalWrite(clk, LOW);
    Serial.print(readable);
    switch(i) 
    {
      case 1: b = interpretInput(readable); break;
      case 2: select = interpretInput(readable); break;
      case 3: start = interpretInput(readable); break;
      case 4: if (readable == 0) {pad = 1;} break;
      case 5: if (readable == 0) {pad = 2;} break;
      case 6: if (readable == 0) {pad = 3;} break;
      case 7: if (readable == 0) {pad = 4;} break;
    }
    delay(10);
    Serial.print(" ");
  }

  if (pad == 1) 
  {
    pos++;
  }
  else if ( pad == 2) 
  {
    pos--;
  } else if (pad == 3) 
  {
    if (color == CRGB(0,255,0)) 
    {
      color = CRGB(0,0,255);
    } 
    else if (color == CRGB(0,0,255)) 
    {color = CRGB(255,0,0);}
    else if (color == CRGB(255,0,0)) {color = CRGB(0,255,0);}
    else { CRGB::White;}
  } else if (pad == 4) 
  {
    if (color == CRGB(0,255,0)) 
    {
      color = CRGB(255,0,0);
    } 
    else if (color == CRGB(0,0,255)) 
    {color = CRGB(0,255,0);}
    else if (color == CRGB(255,0,0)) {color = CRGB(0,0,255);}
    else { CRGB::White;}
  }

  if (a) 
  {
    digitalWrite(blue,HIGH);
    Serial.print("A");
  }
  else 
  {
    digitalWrite(blue,LOW);
  }

  if (b) 
   {
    digitalWrite(green,HIGH);
  }
  else 
  {
    digitalWrite(green,LOW);
  }

  if (select) 
   {
    digitalWrite(yellow,HIGH);
  }
  else 
  {
    digitalWrite(yellow,LOW);
  }  
  if (start)
   {
    digitalWrite(red,HIGH);
  }
  else 
  {
    digitalWrite(red,LOW);
  }

  for (int i = 0; i <STRIP_SIZE; i++) 
  {
    leds[i] = CRGB::Black;
  }

  leds[pos] = color;
  FastLED.show();
  //byte incoming = shiftIn(dataIn,clockIn,LSBFIRST);

  //incoming = incoming >> 4;

  //printBin(incoming);

}