Components and supplies
Resistor 47.5k ohm
Through Hole Resistor, 33 kohm
D Sub Connector, 9 Contacts
General Purpose Transistor NPN
Pushbutton Switch, Momentary
USB Host Shield
USB 2.0 Hub, 4 Port
Resistor 220 ohm
Arduino UNO
LED (generic)
Resistor 10k ohm
Project description
Code
C64 USB joystick
c_cpp
Initializes the USB Host Shield library for PS3 USB joysticks. Reads in and transfers the USB signals from the up to two joysticks to the C64 control port signals.
1/* 2 Arduino sketch to connect 2 USB joysticks to Commodore C64 3 */ 4 5/* 6 Basis for this sketch: 7 Example sketch for the PS3 USB library - developed by Kristian Lauszus 8 For more information visit my blog: http://blog.tkjelectronics.dk/ or 9 send me an e-mail: kristianl@tkjelectronics.com 10 */ 11 12 /* 13 Mapping Competition Pro to --> PS3: 14 Front Left Button --> Triangle 15 Front Right Button --> Circle 16 Rear Left Button (triangle shaped) --> Cross 17 Rear Right Button (triangle shaped) --> Square 18 Forward --> LeftHatY = 0 19 Backward --> LeftHatY = 255 20 Left --> LeftHatX = 0 21 Right --> LeftHatY = 255 22 * 23 */ 24 25#include <PS3USB.h> 26#include <usbhub.h> 27#include <UHS2_gpio.h> 28 29// Satisfy the IDE, which needs to see the include statment in the ino too. 30#ifdef dobogusinclude 31#include <spi4teensy3.h> 32#endif 33#include <SPI.h> 34 35#define PRINTREPORT 36 37#define LEFT1 4 //via GPIO_Out4 on USB Host Shield 38#define RIGHT1 5 //via GPIO_Out5 on USB Host Shield 39#define FORWARD1 2 40#define BACKWARD1 3 41#define BUTTON1 0 //via GPIO_Out0 on USB Host Shield 42#define LEFT2 4 43#define RIGHT2 5 44#define FORWARD2 6 45#define BACKWARD2 7 46#define BUTTON2 1 //via GPIO_Out1 on USB Host Shield 47#define LED_PORT1 2 48#define LED_PORT2 3 49#define SWAPBUTTON 0 // via GPIO_In0 on USB Host Shield 50#define STATE_BUTTON 0 51#define STATE_LEFT 1 52#define STATE_RIGHT 2 53#define STATE_FORWARD 3 54#define STATE_BACKWARD 4 55 56 57#define JOYSTICK_COUNT 2 58#define JOYSTICK_STATES 5 59 60#define DEBOUNCETIME 50 61 62 63USB Usb; 64USBHub Hub(&Usb); 65PS3USB PS3(&Usb); // This will just create the instance 66PS3USB PS3_1(&Usb); // This will just create the instance 67UHS2_GPIO Gpio(&Usb); // Create a GPIO object 68 69bool joystickState[JOYSTICK_COUNT][JOYSTICK_STATES]; 70bool joystickSwap = LOW; 71 72void setup() { 73 Serial.begin(115200); 74 #if !defined(__MIPSEL__) 75 while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection 76 #endif 77 78 if (Usb.Init() == -1) { 79 Serial.print(F("\ \ 80OSC did not start")); 81 while (1); //halt 82 } 83 Serial.print(F("\ \ 84PS3 USB Library Started")); 85 86 //initialize joystick states for all joysticks 87 for (unsigned char i=0; i<JOYSTICK_COUNT; i++){ 88 for (unsigned char j=0; j<JOYSTICK_STATES; j++){ 89 joystickState[i][j] = 0; 90 } 91 } 92 93 //initialize Output pins 94 Gpio.digitalWrite(LEFT1, LOW); 95 Gpio.digitalWrite(RIGHT1, LOW); 96 digitalWrite(FORWARD1, LOW); 97 digitalWrite(BACKWARD1, LOW); 98 digitalWrite(LEFT2, LOW); 99 digitalWrite(RIGHT2, LOW); 100 digitalWrite(FORWARD2, LOW); 101 digitalWrite(BACKWARD2, LOW); 102 pinMode(LEFT1, OUTPUT); 103 pinMode(RIGHT1, OUTPUT); 104 pinMode(FORWARD1, OUTPUT); 105 pinMode(BACKWARD1, OUTPUT); 106 pinMode(LEFT2, OUTPUT); 107 pinMode(RIGHT2, OUTPUT); 108 pinMode(FORWARD2, OUTPUT); 109 pinMode(BACKWARD2, OUTPUT); 110 Gpio.digitalWrite(BUTTON1, LOW); 111 Gpio.digitalWrite(BUTTON2, LOW); 112} 113 114void loop() { 115 unsigned char joystickMapping[JOYSTICK_COUNT]; 116 static bool joystickButtonState[JOYSTICK_COUNT]; 117 Usb.Task(); 118 PS3.attachOnInit(USBonInit1); 119 PS3_1.attachOnInit(USBonInit2); 120 121 // Shall Joysticks be swapped? 122 joystickSwap = ToggleButton(Gpio.digitalRead(SWAPBUTTON)); 123 124 if(joystickSwap){ 125 joystickMapping[0] = 1; 126 joystickMapping[1] = 0; 127 Gpio.digitalWrite(LED_PORT1, LOW); 128 Gpio.digitalWrite(LED_PORT2, HIGH); 129 } 130 else{ 131 joystickMapping[0] = 0; 132 joystickMapping[1] = 1; 133 Gpio.digitalWrite(LED_PORT1, HIGH); 134 Gpio.digitalWrite(LED_PORT2, LOW); 135 } 136 137 138 // Joystick 1 139 if (PS3.PS3Connected || PS3.PS3NavigationConnected) { 140 if (PS3.getAnalogHat(LeftHatX) == 0){ 141 joystickState[joystickMapping[0]][STATE_LEFT] = true; 142 Serial.print(F("\ \ 143Left1")); 144 } 145 else{ 146 joystickState[joystickMapping[0]][STATE_LEFT] = false; 147 } 148 149 if (PS3.getAnalogHat(LeftHatX) == 255){ 150 joystickState[joystickMapping[0]][STATE_RIGHT] = true; 151 Serial.print(F("\ \ 152Right1")); 153 } 154 else{ 155 joystickState[joystickMapping[0]][STATE_RIGHT] = false; 156 } 157 158 if (PS3.getAnalogHat(LeftHatY) == 0){ 159 joystickState[joystickMapping[0]][STATE_FORWARD] = true; 160 Serial.print(F("\ \ 161Forward1")); 162 } 163 else{ 164 joystickState[joystickMapping[0]][STATE_FORWARD] = false; 165 } 166 167 if (PS3.getAnalogHat(LeftHatY) == 255){ 168 joystickState[joystickMapping[0]][STATE_BACKWARD] = true; 169 Serial.print(F("\ \ 170Backward1")); 171 } 172 else{ 173 joystickState[joystickMapping[0]][STATE_BACKWARD] = false; 174 } 175 176 177 if (PS3.getButtonPress(TRIANGLE) || PS3.getButtonPress(CIRCLE) || PS3.getButtonPress(CROSS) || PS3.getButtonPress(SQUARE)){ 178 Serial.print(F("\ \ 179Button1_on")); 180 joystickState[joystickMapping[0]][STATE_BUTTON] = true; 181 } 182 else{ 183 joystickState[joystickMapping[0]][STATE_BUTTON] = false; 184 } 185 } 186 187// Joystick 2 188if (PS3_1.PS3Connected || PS3_1.PS3NavigationConnected) { 189 if (PS3_1.getAnalogHat(LeftHatX) == 0){ 190 joystickState[joystickMapping[1]][STATE_LEFT] = true; 191 Serial.print(F("\ \ 192Left2")); 193 } 194 else{ 195 joystickState[joystickMapping[1]][STATE_LEFT] = false; 196 } 197 198 if (PS3_1.getAnalogHat(LeftHatX) == 255){ 199 joystickState[joystickMapping[1]][STATE_RIGHT] = true; 200 Serial.print(F("\ \ 201Right2")); 202 } 203 else{ 204 joystickState[joystickMapping[1]][STATE_RIGHT] = false; 205 } 206 207 if (PS3_1.getAnalogHat(LeftHatY) == 0){ 208 joystickState[joystickMapping[1]][STATE_FORWARD] = true; 209 Serial.print(F("\ \ 210Forward2")); 211 } 212 else{ 213 joystickState[joystickMapping[1]][STATE_FORWARD] = false; 214 } 215 216 if (PS3_1.getAnalogHat(LeftHatY) == 255){ 217 joystickState[joystickMapping[1]][STATE_BACKWARD] = true; 218 Serial.print(F("\ \ 219Backward2")); 220 } 221 else{ 222 joystickState[joystickMapping[1]][STATE_BACKWARD] = false; 223 } 224 225 if (PS3_1.getButtonPress(TRIANGLE) || PS3_1.getButtonPress(CIRCLE) || PS3_1.getButtonPress(CROSS) || PS3_1.getButtonPress(SQUARE)){ 226 Serial.print(F("\ \ 227Button2_on")); 228 joystickState[joystickMapping[1]][STATE_BUTTON] = true; 229 } 230 else{ 231 joystickState[joystickMapping[1]][STATE_BUTTON] = false; 232 } 233 } 234 Gpio.digitalWrite(LEFT1, joystickState[0][STATE_LEFT]); 235 Gpio.digitalWrite(RIGHT1, joystickState[0][STATE_RIGHT]); 236 digitalWrite(FORWARD1, joystickState[0][STATE_FORWARD]); 237 digitalWrite(BACKWARD1, joystickState[0][STATE_BACKWARD]); 238 digitalWrite(LEFT2, joystickState[1][STATE_LEFT]); 239 digitalWrite(RIGHT2, joystickState[1][STATE_RIGHT]); 240 digitalWrite(FORWARD2, joystickState[1][STATE_FORWARD]); 241 digitalWrite(BACKWARD2, joystickState[1][STATE_BACKWARD]); 242 Gpio.digitalWrite(BUTTON1, joystickState[0][STATE_BUTTON]); 243 Gpio.digitalWrite(BUTTON2, joystickState[1][STATE_BUTTON]); 244} 245 246void USBonInit1(){ //runs once at moment of USB controller initialization 247 Serial.println(" USB 1 Connected "); 248} 249 250void USBonInit2(){ //runs once at moment of USB controller initialization 251 Serial.println(" USB 2 Connected "); 252} 253 254 255bool DebounceButton(bool reading){ 256 static unsigned int lastDebounceTime; 257 static bool lastButtonState; 258 static bool buttonState; 259 260 if (reading != lastButtonState) { 261 // reset the debouncing timer 262 lastDebounceTime = millis(); 263 } 264 265 if ((millis() - lastDebounceTime) > DEBOUNCETIME) { 266 // whatever the reading is at, it's been there for longer 267 // than the debounce delay, so take it as the actual current state: 268 buttonState = reading; 269 } 270 271 lastButtonState = reading; 272 return buttonState; 273} 274 275 276bool ToggleButton(bool reading){ 277 static bool toggleState = LOW; 278 static bool lastButtonState = LOW; 279 bool buttonState; 280 281 buttonState = DebounceButton(reading); 282 283 if((buttonState != lastButtonState) && (buttonState == HIGH)){ 284 if (toggleState == LOW){ 285 toggleState = HIGH; 286 Serial.println(" Toggle High"); 287 } 288 else{ 289 toggleState = LOW; 290 Serial.println(" Toggle Low"); 291 } 292 } 293 lastButtonState = buttonState; 294 return toggleState; 295} 296 297
C64 USB joystick
c_cpp
Initializes the USB Host Shield library for PS3 USB joysticks. Reads in and transfers the USB signals from the up to two joysticks to the C64 control port signals.
1/* 2 Arduino sketch to connect 2 USB joysticks to Commodore C64 3 */ 4 5/* 6 Basis for this sketch: 7 Example sketch for the PS3 USB library - developed by Kristian Lauszus 8 For more information visit my blog: http://blog.tkjelectronics.dk/ or 9 send me an e-mail: kristianl@tkjelectronics.com 10 */ 11 12 /* 13 Mapping Competition Pro to --> PS3: 14 Front Left Button --> Triangle 15 Front Right Button --> Circle 16 Rear Left Button (triangle shaped) --> Cross 17 Rear Right Button (triangle shaped) --> Square 18 Forward --> LeftHatY = 0 19 Backward --> LeftHatY = 255 20 Left --> LeftHatX = 0 21 Right --> LeftHatY = 255 22 * 23 */ 24 25#include <PS3USB.h> 26#include <usbhub.h> 27#include <UHS2_gpio.h> 28 29// Satisfy the IDE, which needs to see the include statment in the ino too. 30#ifdef dobogusinclude 31#include <spi4teensy3.h> 32#endif 33#include <SPI.h> 34 35#define PRINTREPORT 36 37#define LEFT1 4 //via GPIO_Out4 on USB Host Shield 38#define RIGHT1 5 //via GPIO_Out5 on USB Host Shield 39#define FORWARD1 2 40#define BACKWARD1 3 41#define BUTTON1 0 //via GPIO_Out0 on USB Host Shield 42#define LEFT2 4 43#define RIGHT2 5 44#define FORWARD2 6 45#define BACKWARD2 7 46#define BUTTON2 1 //via GPIO_Out1 on USB Host Shield 47#define LED_PORT1 2 48#define LED_PORT2 3 49#define SWAPBUTTON 0 // via GPIO_In0 on USB Host Shield 50#define STATE_BUTTON 0 51#define STATE_LEFT 1 52#define STATE_RIGHT 2 53#define STATE_FORWARD 3 54#define STATE_BACKWARD 4 55 56 57#define JOYSTICK_COUNT 2 58#define JOYSTICK_STATES 5 59 60#define DEBOUNCETIME 50 61 62 63USB Usb; 64USBHub Hub(&Usb); 65PS3USB PS3(&Usb); // This will just create the instance 66PS3USB PS3_1(&Usb); // This will just create the instance 67UHS2_GPIO Gpio(&Usb); // Create a GPIO object 68 69bool joystickState[JOYSTICK_COUNT][JOYSTICK_STATES]; 70bool joystickSwap = LOW; 71 72void setup() { 73 Serial.begin(115200); 74 #if !defined(__MIPSEL__) 75 while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection 76 #endif 77 78 if (Usb.Init() == -1) { 79 Serial.print(F("\ \ 80OSC did not start")); 81 while (1); //halt 82 } 83 Serial.print(F("\ \ 84PS3 USB Library Started")); 85 86 //initialize joystick states for all joysticks 87 for (unsigned char i=0; i<JOYSTICK_COUNT; i++){ 88 for (unsigned char j=0; j<JOYSTICK_STATES; j++){ 89 joystickState[i][j] = 0; 90 } 91 } 92 93 //initialize Output pins 94 Gpio.digitalWrite(LEFT1, LOW); 95 Gpio.digitalWrite(RIGHT1, LOW); 96 digitalWrite(FORWARD1, LOW); 97 digitalWrite(BACKWARD1, LOW); 98 digitalWrite(LEFT2, LOW); 99 digitalWrite(RIGHT2, LOW); 100 digitalWrite(FORWARD2, LOW); 101 digitalWrite(BACKWARD2, LOW); 102 pinMode(LEFT1, OUTPUT); 103 pinMode(RIGHT1, OUTPUT); 104 pinMode(FORWARD1, OUTPUT); 105 pinMode(BACKWARD1, OUTPUT); 106 pinMode(LEFT2, OUTPUT); 107 pinMode(RIGHT2, OUTPUT); 108 pinMode(FORWARD2, OUTPUT); 109 pinMode(BACKWARD2, OUTPUT); 110 Gpio.digitalWrite(BUTTON1, LOW); 111 Gpio.digitalWrite(BUTTON2, LOW); 112} 113 114void loop() { 115 unsigned char joystickMapping[JOYSTICK_COUNT]; 116 static bool joystickButtonState[JOYSTICK_COUNT]; 117 Usb.Task(); 118 PS3.attachOnInit(USBonInit1); 119 PS3_1.attachOnInit(USBonInit2); 120 121 // Shall Joysticks be swapped? 122 joystickSwap = ToggleButton(Gpio.digitalRead(SWAPBUTTON)); 123 124 if(joystickSwap){ 125 joystickMapping[0] = 1; 126 joystickMapping[1] = 0; 127 Gpio.digitalWrite(LED_PORT1, LOW); 128 Gpio.digitalWrite(LED_PORT2, HIGH); 129 } 130 else{ 131 joystickMapping[0] = 0; 132 joystickMapping[1] = 1; 133 Gpio.digitalWrite(LED_PORT1, HIGH); 134 Gpio.digitalWrite(LED_PORT2, LOW); 135 } 136 137 138 // Joystick 1 139 if (PS3.PS3Connected || PS3.PS3NavigationConnected) { 140 if (PS3.getAnalogHat(LeftHatX) == 0){ 141 joystickState[joystickMapping[0]][STATE_LEFT] = true; 142 Serial.print(F("\ \ 143Left1")); 144 } 145 else{ 146 joystickState[joystickMapping[0]][STATE_LEFT] = false; 147 } 148 149 if (PS3.getAnalogHat(LeftHatX) == 255){ 150 joystickState[joystickMapping[0]][STATE_RIGHT] = true; 151 Serial.print(F("\ \ 152Right1")); 153 } 154 else{ 155 joystickState[joystickMapping[0]][STATE_RIGHT] = false; 156 } 157 158 if (PS3.getAnalogHat(LeftHatY) == 0){ 159 joystickState[joystickMapping[0]][STATE_FORWARD] = true; 160 Serial.print(F("\ \ 161Forward1")); 162 } 163 else{ 164 joystickState[joystickMapping[0]][STATE_FORWARD] = false; 165 } 166 167 if (PS3.getAnalogHat(LeftHatY) == 255){ 168 joystickState[joystickMapping[0]][STATE_BACKWARD] = true; 169 Serial.print(F("\ \ 170Backward1")); 171 } 172 else{ 173 joystickState[joystickMapping[0]][STATE_BACKWARD] = false; 174 } 175 176 177 if (PS3.getButtonPress(TRIANGLE) || PS3.getButtonPress(CIRCLE) || PS3.getButtonPress(CROSS) || PS3.getButtonPress(SQUARE)){ 178 Serial.print(F("\ \ 179Button1_on")); 180 joystickState[joystickMapping[0]][STATE_BUTTON] = true; 181 } 182 else{ 183 joystickState[joystickMapping[0]][STATE_BUTTON] = false; 184 } 185 } 186 187// Joystick 2 188if (PS3_1.PS3Connected || PS3_1.PS3NavigationConnected) { 189 if (PS3_1.getAnalogHat(LeftHatX) == 0){ 190 joystickState[joystickMapping[1]][STATE_LEFT] = true; 191 Serial.print(F("\ \ 192Left2")); 193 } 194 else{ 195 joystickState[joystickMapping[1]][STATE_LEFT] = false; 196 } 197 198 if (PS3_1.getAnalogHat(LeftHatX) == 255){ 199 joystickState[joystickMapping[1]][STATE_RIGHT] = true; 200 Serial.print(F("\ \ 201Right2")); 202 } 203 else{ 204 joystickState[joystickMapping[1]][STATE_RIGHT] = false; 205 } 206 207 if (PS3_1.getAnalogHat(LeftHatY) == 0){ 208 joystickState[joystickMapping[1]][STATE_FORWARD] = true; 209 Serial.print(F("\ \ 210Forward2")); 211 } 212 else{ 213 joystickState[joystickMapping[1]][STATE_FORWARD] = false; 214 } 215 216 if (PS3_1.getAnalogHat(LeftHatY) == 255){ 217 joystickState[joystickMapping[1]][STATE_BACKWARD] = true; 218 Serial.print(F("\ \ 219Backward2")); 220 } 221 else{ 222 joystickState[joystickMapping[1]][STATE_BACKWARD] = false; 223 } 224 225 if (PS3_1.getButtonPress(TRIANGLE) || PS3_1.getButtonPress(CIRCLE) || PS3_1.getButtonPress(CROSS) || PS3_1.getButtonPress(SQUARE)){ 226 Serial.print(F("\ \ 227Button2_on")); 228 joystickState[joystickMapping[1]][STATE_BUTTON] = true; 229 } 230 else{ 231 joystickState[joystickMapping[1]][STATE_BUTTON] = false; 232 } 233 } 234 Gpio.digitalWrite(LEFT1, joystickState[0][STATE_LEFT]); 235 Gpio.digitalWrite(RIGHT1, joystickState[0][STATE_RIGHT]); 236 digitalWrite(FORWARD1, joystickState[0][STATE_FORWARD]); 237 digitalWrite(BACKWARD1, joystickState[0][STATE_BACKWARD]); 238 digitalWrite(LEFT2, joystickState[1][STATE_LEFT]); 239 digitalWrite(RIGHT2, joystickState[1][STATE_RIGHT]); 240 digitalWrite(FORWARD2, joystickState[1][STATE_FORWARD]); 241 digitalWrite(BACKWARD2, joystickState[1][STATE_BACKWARD]); 242 Gpio.digitalWrite(BUTTON1, joystickState[0][STATE_BUTTON]); 243 Gpio.digitalWrite(BUTTON2, joystickState[1][STATE_BUTTON]); 244} 245 246void USBonInit1(){ //runs once at moment of USB controller initialization 247 Serial.println(" USB 1 Connected "); 248} 249 250void USBonInit2(){ //runs once at moment of USB controller initialization 251 Serial.println(" USB 2 Connected "); 252} 253 254 255bool DebounceButton(bool reading){ 256 static unsigned int lastDebounceTime; 257 static bool lastButtonState; 258 static bool buttonState; 259 260 if (reading != lastButtonState) { 261 // reset the debouncing timer 262 lastDebounceTime = millis(); 263 } 264 265 if ((millis() - lastDebounceTime) > DEBOUNCETIME) { 266 // whatever the reading is at, it's been there for longer 267 // than the debounce delay, so take it as the actual current state: 268 buttonState = reading; 269 } 270 271 lastButtonState = reading; 272 return buttonState; 273} 274 275 276bool ToggleButton(bool reading){ 277 static bool toggleState = LOW; 278 static bool lastButtonState = LOW; 279 bool buttonState; 280 281 buttonState = DebounceButton(reading); 282 283 if((buttonState != lastButtonState) && (buttonState == HIGH)){ 284 if (toggleState == LOW){ 285 toggleState = HIGH; 286 Serial.println(" Toggle High"); 287 } 288 else{ 289 toggleState = LOW; 290 Serial.println(" Toggle Low"); 291 } 292 } 293 lastButtonState = buttonState; 294 return toggleState; 295} 296 297
Downloadable files
C64 USB joystick interface schematic as Eagle .sch-file
Schematic of the circuit to connect the Arduino UNO and the USB Host Shield to the specific breadboard design.
C64 USB joystick interface schematic as Eagle .sch-file
C64 USB joystick interface schematic as PDF
Schematic of the circuit to connect the Arduino UNO and the USB Host Shield to the specific breadboard design.
C64 USB joystick interface schematic as PDF
C64 USB joystick interface schematic as Eagle .sch-file
Schematic of the circuit to connect the Arduino UNO and the USB Host Shield to the specific breadboard design.
C64 USB joystick interface schematic as Eagle .sch-file
Comments
Only logged in users can leave comments
DocSnyderde
0 Followers
•1 Projects
2
1
lipi1979
6 months ago
The dried rubber ring in old Competition Pro sticks can be easily refreshed with a generous amount of silicone spray. That blue project box is a perfect size to put an arcade stick in it with two buttons. I used the same to build a joystick with the Amiga 2-button wiring.