Interfacing a NES control pad to a microcontroller

Post here to discuss programming with swordfish basic

Moderators: Chuckt, Garth, bitfogav

Post Reply
User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Interfacing a NES control pad to a microcontroller

Post by brad » Thu Jul 15, 2010 11:27 pm

Image

Most of my projects are actually games (if you didn't notice)

Up until tonight, I have been using some mini push buttons, pull up resistors and some wire to construct a make-shift control pad / joystick type setup.

I thought of a much easier way of doing things and in no time at all, came up with just a few lines of code that will grab data from a nes control pad for use in all sorts of applications (like games!) or just to control whatever you want really.

In a nutshell, the NES control pad has five connections to make it all work.

:arrow: VCC
:arrow: GND
:arrow: Latch
:arrow: Clock
:arrow: Data

In order to 'read' the condition of all eight buttons of the control pad, we send a logic 1, followed by a logic 0 on the Latch wire. This will store the condition of all eight buttons of the control pad, into 1 byte of memory (8 d-type flip flops) which is on a chip inside the control pad. At this time, the condition for the a-button will be present on the Data wire.

If this is a logic 1 then we store a logic 1 in the first bit of our nes_flags variable. We then send out a clock pulse to the Clock wire of the nes control pad which will shift all bits within the control pad. Now the next bit that will be on the Data wire will be the condition of the b-button. We then save this condition (1 or 0) to the nes_flags variable, bit 1.

We then do this until the condition of all eight buttons has been determined.

Here is the NES control pad timing diagram (thanks to http://seb.riot.org/nescontr/)
Image

Here is the code to make it all happen:

Code: Select all

Sub check_control_pad()
    nes_latch = 1      // grab the state of the buttons
    nes_latch = 0      // by giving a positive edge to the latch enable
    For x = 0 To 7
        nes_flags.bits(x) = nes_data    // the first bit (button a) will be shown on the nes_data pin, we read it, then clock through
        nes_clock = 1                   // the remaining 7 bits to check the state of all buttons.
        nes_clock = 0
    Next   
End Sub
So throughout the rest of your code, if you wanted to move something left for instance, then you would check nes_flags bit 6 or if you wanted to check the start button in your code, you would check the state of nes_flags bit 3.

Hope this is handy for someone!

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sat Sep 04, 2010 5:43 am

This will come in handy because I haven't yet put a Switch Port on my 24x24 matrix, and this only really uses 3 Pins this will be great as I haven't got many I/O pins left :)

So just to make sure Ive got this correct, the colour wires of the NES pad goes as follows:

VCC = White
GND = Brown
LATCH = Orange
CLOCK = Red
DATA = Yellow

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Post by brad » Sat Sep 04, 2010 9:13 am

Yes, here's a handy pinout for you :D

Image

It is such an easy way to connect up eight buttons to your project

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sun Sep 05, 2010 8:54 pm

Nice handy print out of the control pad connector Brad, I have a few questions about this NES control pad and the flag bits:

Code: Select all

Sub check_control_pad() 
    nes_latch = 1      // grab the state of the buttons 
    nes_latch = 0      // by giving a positive edge to the latch enable 
    For x = 0 To 7 
        nes_flags.bits(x) = nes_data    // the first bit (button a) will be shown on the nes_data pin, we read it, then clock through 
        nes_clock = 1                   // the remaining 7 bits to check the state of all buttons. 
        nes_clock = 0 
    Next    
End Sub
So in this bit of code we are sending a quick pulse to the NES control pad to start the reading of the 8 data bits, and then we check all the 8 bits of data from the NES control pad, and then set the state of the flag bits, I think I understand that bit..

But can you tell me what state will the flag bit be set if a button is pressed? is the flag bit a logic 0 for a pressed button?
has looking through some of your pacman code I see this bit of code:

Code: Select all

If button_debounce = 0 And nes_left = 0

Im guessing that if the flag bit for left button = 0 which then means the button has been pressed?

And the other question, Im also guessing that the flag bits never have to be cleared as when you call the subroutine to check the NES control pad all the flags just get updated?

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Post by brad » Sun Sep 05, 2010 9:21 pm

Can you tell me what state will the flag bit be set if a button is pressed? is the flag bit a logic 0 for a pressed button?

Code: Select all

If button_debounce = 0 And nes_left = 0
Im guessing that if the flag bit for left button = 0 which then means the button has been pressed?
Yes you are correct, a logic 0 from any button means IT IS PRESSED.

The NES control pad uses pulldown resistors so all buttons are normally a logic 1. Then when you press any button, it will now be a logic 0.
has looking through some of your pacman code I see this bit of code:
And the other question, Im also guessing that the flag bits never have to be cleared as when you call the subroutine to check the NES control pad all the flags just get updated?
Correct again! because the NES flags are always updated, you will never need to clear the contents :)

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sun Sep 05, 2010 9:28 pm

Ahh yes that makes it more clear now :)

So the control pad has pullup resistors which will make all the Flag bits logic 1 when you start your microchip, that makes more sense now, and thats why a logic 0 = a PRESSED button.

I was wondering how the flag bits got set, so the wrong data was'nt read before that program starts :)

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Post by brad » Sun Sep 05, 2010 9:42 pm

I'm not sure why they opted for doing it that way - but it works :) good 'ol nintendo

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests