SNES Controller as Wii Classic Controller

Hello,
I want to build a SNES Controller that I can hook up to my Wii as Classic Controller, so I began reading in the SNES Controller which works just fine…
then I started looking how to communicate with the Wiimote and I found this lib http://gitorious.org/randomstuff/arduino-wiimote in the Playground…

But when I use it with my Sketch it makes weird things…

After uploading it, the Wii akts like the “Home Button” got pressed… after that it keeps pressing the Minus Button… I think it is the Minus Button cause I can not scroll Forward through the Channels.

Sometimes I can scroll through the Channels but when pressing Start on the SNES Controller it scrolls two times forward and then it keeps scrolling backwards in the channels…

This is my Sketch:

#include <Wire.h> // This seems redundant, but we need to declare this

                  // dependency in the pde file or else it won't be included

                  // in the build.



#include "wiimote.h"
// Wiimote Lib found in Arduino Playground
// SNES Lib based on Values found online

// Controller buttons
#define SNES_B        32768  // 1000000000000000
#define SNES_Y        16384  // 0100000000000000
#define SNES_SELECT   8192   // 0010000000000000
#define SNES_START    4096   // 0001000000000000
#define SNES_UP       2048   // 0000100000000000
#define SNES_DOWN     1024   // 0000010000000000
#define SNES_LEFT      512   // 0000001000000000
#define SNES_RIGHT     256   // 0000000100000000
#define SNES_A         128   // 0000000010000000
#define SNES_X          64   // 0000000001000000
#define SNES_L          32   // 0000000000100000
#define SNES_R          16   // 0000000000010000
 
//SNES Pins at Arduino
int SNES_LatchPin  = 2; // Latch
int SNES_ClockPin  = 3; // Clock
int SNES_DataPin   = 4; // Serial Data

// Here's how to connect the Arduino to the Wiimote:

// *      Arduino    Wiimote

// *      GND        GND  (white cable)

// *      AREF       3.3V (red cable)

// *      A4         SDA  (green cable)

// *      A5         SCL  (yellow cable)
 
// Current controller data
unsigned int ControllerData = 0;

// Classic Controller Buttons

int bdl = 0; // D-Pad Left state

int bdr = 0; // D-Pad Right state

int bdu = 0; // D-Pad Up state

int bdd = 0; // D-Pad Down state

int ba = 0; // A button state

int bb = 0; // B button state

int bx = 0; // X button state

int by = 0; // Y button state

int bl = 0; // L button state

int br = 0; // R button state

int bm = 0; // MINUS button state

int bp = 0; // PLUS button state

int bhome = 0; // HOME button state

int bzl = 0; // ZL button state

int bzr = 0; // ZR button state



/*

 * Analog Buttons.

 * They are initialized with center values from the calibration buffer.

 */

byte lx = calbuf[2]>>2;

byte ly = calbuf[5]>>2;

byte rx = calbuf[8]>>3;

byte ry = calbuf[11]>>3;



// Wiimote button data stream
byte *stream_callback(byte *buffer)
{
  
  wiimote_write_buffer(buffer, bdl, bdr, bdu, bdd, ba, bb, bx, by, bl, br, bm, bp, bhome, lx, ly, rx, ry, bzl, bzr);
 
  return buffer;
}

// Setup the controller and serial output
void setup() {
  
  pinMode(SNES_LatchPin,OUTPUT);
  pinMode(SNES_ClockPin,OUTPUT);
  pinMode(SNES_DataPin,INPUT);
 
  digitalWrite(SNES_LatchPin,HIGH);
  digitalWrite(SNES_ClockPin,HIGH);
  
// Prepare wiimote communications
  wiimote_stream = stream_callback;
  wiimote_init();
  
  Serial.begin(9600);
}
 
  // Read controller
  void controllerRead() {
  // Reset controller states and data
  ControllerData = 0;
  digitalWrite(SNES_LatchPin,LOW);
  digitalWrite(SNES_ClockPin,HIGH);
 
  // Controller needs to latch the state of all buttons
  digitalWrite(SNES_LatchPin,HIGH);
  delayMicroseconds(1);
  digitalWrite(SNES_LatchPin,LOW);
  delayMicroseconds(6);
 
  // Read controller data (initial reading)
  ControllerData = digitalRead(SNES_DataPin);
 
  // Send 16 clock pulses, one for each button. 
    for (int i = 0; i < 16; i ++) {
    digitalWrite(SNES_ClockPin,LOW);
    delayMicroseconds(6);
    ControllerData = ControllerData << 1;
    ControllerData = ControllerData + digitalRead(SNES_DataPin) ;
    delayMicroseconds(6);
    digitalWrite(SNES_ClockPin,HIGH);
  }
 
  // Do a NOT, so '1' will be pressed buttons and '0' to the rest
  ControllerData = ~ControllerData;
}
 
//Main Program
void loop() {
  // Read controller data
  controllerRead();
 
  // Debuging
  //Serial.println(~ControllerData, BIN);

  if (ControllerData != 0) {
    Serial.print("Pressed buttons:");
    if (ControllerData & SNES_B) {
      Serial.print(" B");
      bb = HIGH;
    }
    if (ControllerData & SNES_Y) {
      Serial.print(" Y");
      by = HIGH;
    }
    if (ControllerData & SNES_SELECT) {
      Serial.print(" SELECT");
      bm = HIGH;
    }
    if (ControllerData & SNES_START) {
      Serial.print(" START");
      bp = HIGH;
    }
    if (ControllerData & SNES_UP) {
      Serial.print(" UP");
      bdu = HIGH;
    }
    if (ControllerData & SNES_DOWN) {
      Serial.print(" DOWN");
      bdd = HIGH;
    }
    if (ControllerData & SNES_LEFT) {
      Serial.print(" LEFT");
      bdl = HIGH;
    }
    if (ControllerData & SNES_RIGHT) {
      Serial.print(" RIGHT");
      bdr = HIGH;
    }
    if (ControllerData & SNES_A) {
      Serial.print(" A");
      ba = HIGH;
    }
    if (ControllerData & SNES_X) {
      Serial.print(" X");
      bx = HIGH;
    }
    if (ControllerData & SNES_L) {
      Serial.print(" L");
      bzl = HIGH;
    }
    if (ControllerData & SNES_R) {
      Serial.print(" R");
      bzr = HIGH;
    }
    Serial.println("");
  }
  delay(50);
}

Is there some error in my sketch that I dont see? Or is it the Lib?

Hi there!

The arduino-wiimote lib indeed does work. It’s kinda outadated compared to its improved version used on the https://gitorious.org/wii-retropad-adapter project.

Anyways, did you manage to test the sketch from http://gitorious.org/randomstuff/arduino-wiimote/ as is by using a push button or even a piece of wire on pin 2 to GND and see if a Classic Controller digital right signal gets activated?

Edit: Your logic on checking buttons presses and setting the correspondent classic controller button variable needs some work, as you’re not restoring them to LOW if buttons are not pressed:

    if (ControllerData & SNES_START) {
      Serial.print(" START");
      bp = HIGH;
    }

You could use something like: “bp = ControllerData & SNES_START;” for example.

bootsector