Skip to the content
2 layers68.6 × 53.3 mmUltimate USB joystick, the printed circuit board in 3D

Arduino project to convert USB joystick or mouse to digital for use with Commodore or Atari computers

Size
68.6 × 53.3 mm
Copper layers
2
Thickness
1.6 mm
Parts
25
Nets
47
Pads
94
Tracks, vias
166, 0
Routed
Yes
KiCad
KiCad 5 (file 20171130)
Created
5 May 2020
Updated
6 Dec 2021

Overview

Ultimate USB joystick is an open-source printed circuit board by doj, from the doj/Ultimate-USB-to-Controlport repository on GitHub. It is a 2-layer board of 68.6 × 53.3 mm with 25 parts on 47 nets, routed with 166 tracks and 0 vias.

It belongs with the retro computing and games and keyboards and input boards of this library.

README

README.md

Ultimate USB to Controlport

An Arduino project to convert a USB joystick and mouse to digital for use with Commodore or Atari computers.

See the Controllers section below for supported USB devices.

Compile and Install

Install the USB Host Shield Library 2.0 version 1.3.2 using the Arduino IDE library manager.

Then compile and upload the program main/main.ino with the Arduino IDE.

Usage

Connect a USB joystick, gamepad, mouse, keyboard to the USB Host Shield. If the USB Host Shield (Library) supports the device it will produce events on the Commodore control port. You can also use a USB hub to connect multiple devices.

The following buttons of a gamepad are assigned to the following directions:

NESSonyControl Port
Bcrossfire
Acircleauto fire A, 10 Hz
Ysquareauto fire Y, 5 Hz
Xtriangleup
n/aL1left
n/aR1right
LL2left
RR2right
selectselectfire 2 on POT Y
startstartfire 3 on POT X

You can configure the frequency of the auto fire from 1 Hz to 255 Hz. To configure the frequency press:

  • select+start+A+up : increase the frequency of auto fire A
  • select+start+A+down : decrease the frequency of auto fire A
  • select+start+Y+up : increase the frequency of auto fire Y
  • select+start+Y+down : decrease the frequency of auto fire Y

You can switch the directions of all buttons (lefty mode), press: select+start+B+left.

You can switch the Control Port a device uses by pressing: select+start+L2+up

A USB mouse will be used to output the Commodore 1351 mouse protocol on the Pot X and Pot Y control port inputs. The following table shows the mouse button mapping:

MouseControl Port
leftfire
middledown
rightup
wheel upleft
wheel downright
left sideleft
right sideright

The mouse wheel is using the Micromys protocol. Left and Right side buttons are used on the Microsoft Intellimouse.

The table below shows how keyboard keys are mapped to the control port:

KeyControl Port
up, num 8, w, iup
down, num 2, s, kdown
left, 4, a, jleft
right, 6, d, lright
ins, space, ~, enter, F1, bfire (gamepad B)
yauto fire (gamepad Y)
xup (gamepad X)
F2fire 2 on POT Y (gamepad select)
F3fire 3 on POT X (gamepad start)

Hardware

This project was tested with a Arduino Uno R3 board and the Arduino USB Host Shield. While the USB Host Shield is no longer sold by the Arduino company, you can easily find clones of the board on AliExpress, where you can also buy a clone Arduino Uno board. To connect the resistors and cables (or Sub-D connectors) you can also purchase a Proto Shield R3.

The following picture shows the location of all I/O pins on the Arduino Uno R3 board.

Arduino Uno R3 pinout

The following table shows how the 2 control ports with [https://en.wikipedia.org/wiki/D-subminiature](D-sub 9) connectors should be connected to the Arduino pins. This suggested connection is for a Commodore 64. You can change the pin assignments in the config.h file. Except for the +5V (which doesn't need to to connected) and the GND, all connections between the Arduino and the control port should be made via a resistor. The exact resistor value is not important, anything in the 100-500 Ohm range should be fine.

Control Port 1

ArduinoResistorD-subFunction
A0220 Ohm1Up
A1220 Ohm2Down
A2220 Ohm3Left
A3220 Ohm4Right
A5220 Ohm5Pot Y
A4220 Ohm6Fire
(n/c)-7+5V
GND-8GND
D2220 Ohm9Pot X

Control Port 2

ArduinoResistorD-subFunction
D4220 Ohm1Up
D5220 Ohm2Down
D6220 Ohm3Left
D7220 Ohm4Right
D1220 Ohm5Pot Y
D8220 Ohm6Fire
(n/c)-7+5V
GND-8GND
D3220 Ohm9Pot X

Note: On the Arduino pins D0 and D1 are used for the serial debug console. If you connect the control port Pot Y line to D1, you can't use the serial console any more.

If you want to change the Arduino pin assignments, change the config.h file.

If you have a clone USB Host Shield from China it is likely that the 3.3V and 5V power supply to the board and USB device connector are not connected. The solder pads show a gap. Closing them with a soldering iron should make the USB Host Shield operational. See https://esp8266-notes.blogspot.com/2017/08/defective-arduino-usb-host-shield-boards.html for details.

The following picture shows the development prototype with an Arduino Uno, the USB Host Shield, a 4 port USB hub and connections to both Commodore 64 control ports.

prototype

custom Arduino Uno Shield

the arduino-shield/ directory contains a KiCad project of an Arduino Uno Shield.

Arduino Uno Shield

The following picture shows a build of the first version of the shield.

Arduino Uno Shield

The following changes would improve the Arduino Uni Shield:

  • increase distance of resistor pads
  • use control port +5V to power the arduino. We need to protect against drawing too much current from the C64.
  • design a new shield which can be plugged directly into a C64.

Feature Implementation Status

The following list shows which features are implemented.

  • use digital x-pad for joystick directions.
  • use B button for fire
  • use X button for up direction
  • use L button for left
  • use R button for right
  • use A button for auto fire
  • use Y button for auto fire
  • configure auto fire frequency
  • use start button for fire 2 on POT Y
  • use select button for fire 3 on POT X
  • support two USB joysticks with both control ports
  • lefty mode
  • support mouse side buttons
  • support PlayStation Classic USB controller
  • use keyboard as joystick
  • set keyboard numlock LED for each fire event
  • switch joystick 1,2 and mouse 1,2 with button combination
  • the USB controller should remember the button state and count how many button down pushes were made. However this is not so easy when autofire is selected. For example the following is buggy: press d-pad down, then X (up). When d-pad is released, both states are cleared.
  • reconfigure any USB button to any Commodore button
  • configure a USB button to set multiple directions at once. this could be useful for up+down and left+right to encode a special button.
  • save configuration to Arduino EEPROM https://www.arduino.cc/en/Reference/EEPROM
  • support PlayStation 3 controller
  • support PlayStation 4 controller
  • use analog joystick of a PlayStation 3 controller for POT X and POT Y
  • support analog hat button
  • support Xbox controller
  • use USB mouse for POT X and POT Y with 1351 protocol
  • support 1351 mouse wheel
  • fix device mapping in USB Host Shield Library
  • MIDI input
  • burst fire mode, can also be used for one-shot fire mode
  • fix 1351 analog jitter when USB data is received

Controllers

The following controllers have been tested with the software:

Serial Debug Console

By default the serial debug console is enabled and uses 115200 baud. See the config.h file to configure the baud rate or to disable the debug console output.

Issues

  • the USB Host Shield 2.0 Library does not properly enumerate devices. This software currently works around that issue by using the universal HID device and manually parsing all incoming data packets. This may cause problems for untested USB HID devices.

  • 1351 mouse support on POT is not working yet. When USB data is received the timer1 does not reliably work.

Links

This software uses the arduino-timer library.

Information on Commodore 1351 mouse: http://sensi.org/~svo/[m]ouse/ http://www.zimmers.net/anonftp/pub/cbm/documents/projects/interfaces/mouse/Mouse.html

Information how to read joystick and POT on the C64: https://codebase64.org/doku.php?id=base:io_programming

Information on the USB protocol: http://www.usbmadesimple.co.uk/ums_4.htm

USB Host Shield 2.0 Library with fixes and better debugging messages: https://github.com/doj/USB_Host_Shield_2.0

PSX64 Interface The PSX64 interface connects Playstation controllers to most computers and consoles that use a DB9 joystick port.

PadSwitcher64 is an interface for SNES controllers and Commodore 64 control ports.

Unijoysticle 2 an interface for bluetooth wireless controllers and Commodore 64 control ports.

Test Program

The following C64 Basic program can be used to test the 2 control ports and the POT of control port 1. You also find it in the GIT repository as joysticktest.prg

basic
10 j = NOT PEEK(56321)
15 b = NOT PEEK(56320)
20 PRINT CHR$(147);
30 IF (j AND 1) THEN PRINT "1U ";
35 IF (b AND 1) THEN PRINT "2U ";
40 IF (j AND 2) THEN PRINT "1D ";
45 IF (b AND 2) THEN PRINT "2D ";
50 IF (j AND 4) THEN PRINT "1L ";
55 IF (b AND 4) THEN PRINT "2L ";
60 IF (j AND 8) THEN PRINT "1R ";
65 IF (b AND 8) THEN PRINT "2R ";
70 IF (j AND 16) THEN PRINT "1F ";
75 IF (b AND 16) THEN PRINT "2F ";
80 PRINT
200 POKE 56322,224 : REM disable keyboard
210 PRINT "POT1X " ; PEEK(54297) ; " POT1Y " ; PEEK(54298)
290 POKE 56322,255 : REM enable keyboard
1000 GOTO 10

Contact

Write an email to Dirk Jagdmann doj@cubic.org The source code is hosted on https://github.com/doj/Ultimate-USB-to-Controlport

Changes

DateChanges
2020-05-171351 fixes
2020-09-29add Arduino Uno Shield PCB
2020-09-30fix stuck direction when switching control ports

Parts

25
QtyValueFootprintReferences
14220Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P7.62mm_Horizontal220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220
2470Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P7.62mm_Horizontal470, 470
2Commodore_Control_PortConnector_Dsub:DSUB-9_Female_Horizontal_P2.77x2.84mm_EdgePinOffset4.94mm_Housed_MountingHolesOffset7.48mmport1, port2
2LEDLED_THT:LED_D5.0mmLED1, LED2
1AnalogSocket_Arduino_Uno:Socket_Strip_Arduino_1x06A0 A1 A2 A3 A4 A5
1DigitalSocket_Arduino_Uno:Socket_Strip_Arduino_1x08D7 D6 D5 D4 D2 D0
1DigitalSocket_Arduino_Uno:Socket_Strip_Arduino_1x10 GND 13 12 11 10 D9 D8
1PowerSocket_Arduino_Uno:Socket_Strip_Arduino_1x08power
1SW_PushButton_Switch_THT:SW_TH_Tactile_Omron_B3F-10xxreset

Similar boards

  • 2 layers159.5 × 30 mmType f, the printed circuit board in 3D

    Type f

    google/mozc-devices

    Circuit diagrams and firmware source code for Gboard DIY keyboards

    25 parts3kApache-2.0
  • 2 layers113.5 × 95.1 mmSweep high, the printed circuit board in 3D

    Sweep high

    davidphilipbarr/Sweep

    Sweep - a small promicro based keyboard inspired by the Ferris.

    25 parts2.1k
  • 2 layers58.4 × 114.3 mmPicoPedal, the printed circuit board in 3D

    PicoPedal

    hackclub/OnBoard

    💡 Join 1,000 teenagers and make your first PCB with a $100 grant!

    25 parts915
  • 2 layers54 × 15 mmXyp gpib, the printed circuit board in 3D

    Xyp gpib

    xyphro/UsbGpib

    Versatile, cheap and portable USB to GPIB converter (USBTMC class based)

    25 parts690MIT
  • 2 layers50 × 76 mmVoron 0, the printed circuit board in 3D

    Voron 0

    dennisss/dacha

    Monorepo for awesome tools/projects/libraries

    25 parts397Apache-2.0
  • 2 layers237.5 × 102.9 mmStorage, the printed circuit board in 3D

    Storage

    jes/scamp-cpu

    A homebrew 16-bit CPU with a homebrew Unix-like-ish operating system.

    25 parts301Unlicense
  • 2 layers43.3 × 21 mmNanoS3 Carrier, the printed circuit board in 3D

    NanoS3 Carrier

    UnexpectedMaker/esp32s3

    Assorted files for my ESP32-S3 development boards

    25 parts296

Questions

How big is the Ultimate USB joystick PCB?

It measures 68.6 × 53.3 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Ultimate USB joystick use?

25 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Ultimate USB joystick KiCad files?

From the doj/Ultimate-USB-to-Controlport repository on GitHub, at the commit this page was made from: the board is arduino-shield/Ultimate-USB-joystick.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.

Can I use the Ultimate USB joystick design in my own project?

Its repository states no licence, so its author keeps all rights: ask doj before reusing the design.