NicoHood / Nintendo

Use Nintendo Controllers with Arduino
http://www.nicohood.de
MIT License
278 stars 55 forks source link

SNES to GC help #13

Closed tevey closed 6 years ago

tevey commented 7 years ago

Hi! I have build a SNES to GC controller adapter using your library. The problem i have is that when i keep a button pressed down it acts as if i press it and release it really fast over and over again instead of being pressed down.

Here is my code, is there something i'm missing? greatful for any help.

#include` "Nintendo.h"

//SNES button mapping
const int BUTTON_A = 8;
const int BUTTON_B = 0;
const int BUTTON_X = 9;
const int BUTTON_Y = 1;
const int BUTTON_SELECT = 2;
const int BUTTON_START = 3;
const int BUTTON_R = 11;
const int BUTTON_L = 10;
const int DPAD_UP = 4;
const int DPAD_DOWN = 5;
const int DPAD_LEFT = 6;
const int DPAD_RIGHT = 7;

//SNES pins
const int SNES_DATA_CLOCK_PIN = 11;
const int SNES_DATA_LATCH_PIN = 10;
const int SNES_DATA_SERIAL_PIN = 12;

//Array holding SNES buttons states
int buttons[12];

int GC_DATA_PIN = 8;
//This makes the controller bidirection data line on pin number8
CGamecubeConsole GamecubeConsole(GC_DATA_PIN);      //Defines a "Gamecube Console" sending data to the console on pin 8
Gamecube_Data_t d = defaultGamecubeData;   //Structure for data to be sent to console

//This is needed but you don't need a controller on pin 7
CGamecubeController GamecubeController1(7);

void setup(){
    // Set SNES_DATA_CLOCK_PIN normally HIGH
    pinMode(SNES_DATA_CLOCK_PIN, OUTPUT);
    digitalWrite(SNES_DATA_CLOCK_PIN, HIGH);

    // Set SNES_DATA_LATCH_PIN normally LOW
    pinMode(SNES_DATA_LATCH_PIN, OUTPUT);
    digitalWrite(SNES_DATA_LATCH_PIN, LOW);

    // Set SNES_DATA_SERIAL_PIN normally HIGH
    pinMode(SNES_DATA_SERIAL_PIN, OUTPUT);
    digitalWrite(SNES_DATA_SERIAL_PIN, HIGH);
    pinMode(SNES_DATA_SERIAL_PIN, INPUT);

     //This is needed to run the code.
    GamecubeController1.read();
}

void loop() {
    // Latch for 12us
    digitalWrite(SNES_DATA_LATCH_PIN, HIGH);
    delayMicroseconds(12);
    digitalWrite(SNES_DATA_LATCH_PIN, LOW);
    delayMicroseconds(6);

    // Retrieve button presses from shift register by pulling the clock high for 6us
    for(int i = 0; i < 16; i++){
        digitalWrite(SNES_DATA_CLOCK_PIN, LOW);
        delayMicroseconds(6);
        if(i <= 11){
                buttons[i] = !digitalRead(SNES_DATA_SERIAL_PIN);
        }
        digitalWrite(SNES_DATA_CLOCK_PIN, HIGH);
        delayMicroseconds(6);

    }

    //sends the complied data to console when console polls for the input
    d.report.a = buttons[BUTTON_A];
    d.report.b = buttons[BUTTON_B];
    d.report.x = buttons[BUTTON_X];
    d.report.y = buttons[BUTTON_Y];
    d.report.z = buttons[BUTTON_SELECT];
    d.report.start = buttons[BUTTON_START];
    d.report.r = buttons[BUTTON_R];
    d.report.l = buttons[BUTTON_L];
    d.report.dleft = buttons[DPAD_LEFT];
    d.report.dup = buttons[DPAD_UP];
    d.report.dright = buttons[DPAD_RIGHT];
    d.report.ddown = buttons[DPAD_DOWN];
    GamecubeConsole.write(d);
}
ghost commented 6 years ago

The main thing that sticks out to me is your delays, you have 2 delays in your loop for quite a bit longer than what is in the examples for arduino shift registers. Everything else looks pretty good otherwise in comparison.

https://www.arduino.cc/en/Tutorial/ShftIn12

Ps. For anyone wondering snes uses a shift register in its controllers to read what button is pressed.

NicoHood commented 6 years ago

The tricky part is to answer the gamecube console just in time. if you do not, the console will drop the controller and tries to intialise it again. You can see it best in the game mario football where the game will pause once a controller disconnects. if it doesnt, your code is working fine

I suggest to try out different delays, and debug with a logic analyser if you miss any signal. it may also depend on the game you are playing. the code is somehow limited to that, you have to work around that.

tevey commented 6 years ago

Thank you for pointing me in the right direction! Now it's working and I uploaded everything here if somebody else want to build one.

NicoHood commented 6 years ago

Thanks for sharing! What did you do to solve the problem now?

tevey commented 6 years ago

I just had to move the code where i write to the gc console inside the read loop so that the data is always acurate when the gc asks for it.