· 8 years ago · Mar 16, 2018, 03:18 AM
1/*
2================================================================================
3
4 File........... NES Controller Test Code
5 Purpose........ To demonstrate how to interface to an NES controller
6 Author......... Joseph Corleto
7 E-mail......... corleto.joseph @ gmail.com
8 Started........ 04/13/2016
9 Finished....... 04/14/2016
10 Updated........ --/--/----
11
12================================================================================
13 Notes
14================================================================================
15- The NES controller contains one 8-bit 4021 shift register inside.
16
17- This register takes parallel inputs and converts them into a serial output.
18
19- This code first latches the data and then shifts in the first bit on the data line.
20 Then it clocks and shifts in on the data line until all bits are received.
21
22- What is debugged are the button states of the NES controller.
23
24- A logical "1" means the button is not pressed. A logical "0" means the button is
25 pressed.
26
27- This code shifts the first bit of data into the LSB.
28
29- The order of shifting for the buttons is shown in the table below:
30
31 Bit# | Button
32 --------------
33 0 | A
34 --------------
35 1 | B
36 --------------
37 2 | Select
38 --------------
39 3 | Start
40 --------------
41 4 | Up
42 --------------
43 5 | Down
44 --------------
45 6 | Left
46 --------------
47 7 | Right
48 --------------
49
50- The NES controller pinout is shown below (looking into controllers
51 connector end):
52 __________
53 / |
54 / O 1 | 1 - Ground
55 | | 2 - Clock
56 | 7 O O 2 | 3 - Latch
57 | | 4 - Data Out
58 | 6 O O 3 | 5 - No Connection
59 | | 6 - No Connection
60 | 5 O O 4 | 7 - +5V
61 |___________|
62
63- Please visit http://www.allaboutcircuits.com to search for complete article!
64
65================================================================================
66 Updates
67================================================================================
68*/
69
70//===============================================================================
71// Header Files
72//===============================================================================
73
74//===============================================================================
75// Constants
76//===============================================================================
77// Here we have a bunch of constants that will become clearer when we look at the
78// readNesController() function. Basically, we will use these contents to clear
79// a bit. These are chosen according to the table above.
80const int A_BUTTON = 0;
81const int B_BUTTON = 1;
82const int SELECT_BUTTON = 2;
83const int START_BUTTON = 3;
84const int UP_BUTTON = 4;
85const int DOWN_BUTTON = 5;
86const int LEFT_BUTTON = 6;
87const int RIGHT_BUTTON = 7;
88
89//===============================================================================
90// Variables
91//===============================================================================
92byte nesRegister = 0; // We will use this to hold current button states
93
94//===============================================================================
95// Pin Declarations
96//===============================================================================
97//Inputs:
98int nesData = 4; // The data pin for the NES controller
99
100//Outputs:
101int nesClock = 2; // The clock pin for the NES controller
102int nesLatch = 3; // The latch pin for the NES controller
103
104//===============================================================================
105// Initialization
106//===============================================================================
107void setup()
108{
109 // Initialize serial port speed for the serial terminal
110 Serial.begin(9600);
111
112 // Set appropriate pins to inputs
113 pinMode(nesData, INPUT);
114
115 // Set appropriate pins to outputs
116 pinMode(nesClock, OUTPUT);
117 pinMode(nesLatch, OUTPUT);
118
119 // Set initial states
120 digitalWrite(nesClock, LOW);
121 digitalWrite(nesLatch, LOW);
122}
123
124//===============================================================================
125// Main
126//===============================================================================
127void loop()
128{
129 // This function call will return the states of all NES controller's register
130 // in a nice 8 bit variable format. Remember to refer to the table and
131 // constants above for which button maps where!
132 nesRegister = readNesController();
133
134 // Slight delay before we debug what was pressed so we don't spam the
135 // serial monitor.
136 delay(180);
137
138 // Print the binary value of the register
139 Serial.print(nesRegister, BIN);
140}
141
142//===============================================================================
143// Functions
144//===============================================================================
145///////////////////////
146// readNesController //
147///////////////////////
148byte readNesController()
149{
150 // Pre-load a variable with all 1's which assumes all buttons are not
151 // pressed. But while we cycle through the bits, if we detect a LOW, which is
152 // a 0, we clear that bit. In the end, we find all the buttons states at once.
153 int tempData = 255;
154
155 // Quickly pulse the nesLatch pin so that the register grab what it see on
156 // its parallel data pins.
157 digitalWrite(nesLatch, HIGH);
158 digitalWrite(nesLatch, LOW);
159
160 // Upon latching, the first bit is available to look at, which is the state
161 // of the A button. We see if it is low, and if it is, we clear out variable's
162 // first bit to indicate this is so.
163 if (digitalRead(nesData) == LOW)
164 bitClear(tempData, A_BUTTON);
165
166 // Clock the next bit which is the B button and determine its state just like
167 // we did above.
168 digitalWrite(nesClock, HIGH);
169 digitalWrite(nesClock, LOW);
170 if (digitalRead(nesData) == LOW)
171 bitClear(tempData, B_BUTTON);
172
173 // Now do this for the rest of them!
174
175 // Select button
176 digitalWrite(nesClock, HIGH);
177 digitalWrite(nesClock, LOW);
178 if (digitalRead(nesData) == LOW)
179 bitClear(tempData, SELECT_BUTTON);
180
181 // Start button
182 digitalWrite(nesClock, HIGH);
183 digitalWrite(nesClock, LOW);
184 if (digitalRead(nesData) == LOW)
185 bitClear(tempData, START_BUTTON);
186
187 // Up button
188 digitalWrite(nesClock, HIGH);
189 digitalWrite(nesClock, LOW);
190 if (digitalRead(nesData) == LOW)
191 bitClear(tempData, UP_BUTTON);
192
193 // Down button
194 digitalWrite(nesClock, HIGH);
195 digitalWrite(nesClock, LOW);
196 if (digitalRead(nesData) == LOW)
197 bitClear(tempData, DOWN_BUTTON);
198
199 // Left button
200 digitalWrite(nesClock, HIGH);
201 digitalWrite(nesClock, LOW);
202 if (digitalRead(nesData) == LOW)
203 bitClear(tempData, LEFT_BUTTON);
204
205 // Right button
206 digitalWrite(nesClock, HIGH);
207 digitalWrite(nesClock, LOW);
208 if (digitalRead(nesData) == LOW)
209 bitClear(tempData, RIGHT_BUTTON);
210
211 // After all of this, we now have our variable all bundled up
212 // with all of the NES button states.*/
213 return tempData;
214}