Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
496 lines (321 sloc) 27.8 KB

The UniJoystiCle™ Documentation


The UniJoystiCle is a unicycle simulator for the Commodore 64, and much more! It allows you to control the joystick lines remotely, with anything that you have in mind like:

  • play c64 games using modern game controllers (Xbox, iOS or Android game controllers)
  • play The Uni Games, a c64 unicycle game, using a real unicycle
  • automate your home from the C64 with the Commodore Home
  • and more!

It consists of two major parts:

  • The UniJoystiCle WiFi device
  • The UniJoystiCle client application: iOS, Android, Mac, Windows and Linux

The WiFi device

The WiFi device goes attached to the Commodore 64, and is the one that generates the real joystick movements. It does so by opening/closing the joystick lines.

In order to work it needs power. Unfortunately the C64 joystick ports DON'T have enough current to power it. The options to power it are:

  • Using the barrel jack:
  • Using the micro USB socket:
    • It can be connected to a computer
    • or using a wall charger

Booting the WiFi device

  • DO NOT plug the UniJoystiCle WiFi device to the Commodore 64 yet (if you plug it, you won't break anything, it is that it just might not boot)
  • Power the UniJoystiCle WiFi device (see above)
  • Wait a few seconds and you should see one LED. That means that the device booted, and you can connect to it.
  • Now, you can plug it to the Commodore 64

By default, the WiFi device will start in Access Point mode, and will create a WiFi network named "unijoysticle-xxyyzz". From your smartphone Settings, connect to it...:

...and then launch the UniJoystiCle smartphone app.

Smartphone Client Application

The client application can be download for free from the App Store / Google Play:

Get it on Google Play

It sends "joystick commands" to the WiFi device. These commands are regular joystick movements: Up, Down, Left, Right and Fire. It can send one or multiple commands at the time.

There are five modes: UniJoystiCle mode, D-pad mode, Commando mode, Gyruss mode and Commodore Home mode.

UniJoystiCle mode


In this mode, the joystick commands are generated from the smartphone's accelerometer. The accelerometer detects acceleration in the three coordinates: X, Y and Z. If we attach an accelerometer (in this case the smartphone) to a unicycle (or bike) pedal, and we measure the accelerometer's data while we pedal, we will notice that the X and Z axis generates data similar to a sine and cosine.

And if we put those values in cartesian coordinates (eg: Accelerometer(Z) = Y axis, and Accelerometer(X) = X axis), we will have something similar to a circle.

And if we calculate the arctangent (atan2()) value of sin/cosine we get the angle. And with the angle we can simulate the joystick movements. We divide the circle in 8 segments, and assign a joystick movement to each segment. Eg:

There are no such things as "joystick diagonal commands". So in order to simulate the top-right diagonal, we just send the "top" and "right" joystick movements at the same time.

From the graphic we can deduce that:

One pedal revolution == one joystick "revolution"

But it is possible to change that ratio. For example, we can change it to "One pedal revolution == two joystick revolutions". Just go to settings and do:

A ratio of 2.0 will divide the circle in 16 segments (8 segments * 2.0 ratio == 16 segments), and what will happen is that:

One pedal revolution == Two joystick revolutions

This is useful to:

  • Increase your speed when you have an slow unicycle (eg: long cranks or big wheel size), or you don't pedal fast enough
  • You want to play face-to-face with another rider, but one has an slower unicycle

Firing: In order to fire, you have to hop. Settings has a "Jump Threshold" settings that is used to control how hard you have to hop.

Compatibility: This mode is compatible with multiple sports games like:

Video: Using a unicycle to play The Uni Games

Video: Using one foot to play C64anabalt

D-pad mode

This mode converts the smartphone in a virtual D-pad. Just press the arrows for joysticks movements, and the circle to fire.


  • Any game can be played in this mode.

Using this mode: YouTube video

D-pad + Game Controllers

This is the same D-pad mode as before. But if you connect any Game Controller to your smartphone (for iOS it supports both MFi and iCade controllers; for Android it supports official controllers as well as OUYA ones), it will automatically detect it. And with it you can control the virtual D-pad giving you a great gaming experience.

You can configure it to:

  • Use Button "B" to jump. When enabled, it will disable to "Up" D-pad arrow
  • Swap Buttons "A" and "B" (swaps Jump and Shoot buttons)


Using this mode: YouTube video

Which controller should you use:

For iOS:

For Android:

  • Any Game Controller that supports the Android protocol. See reviews here and here
  • OUYA Game Controllers (they are not that great though). Get it here
  • Notes:
    • Amazon Fire Game Controllers support the Android protocol
    • Moga Game Controllers support the Android protocol when in "B" mode
    • WiFi-Direct game controllers are supported as well, like the NVIDIA SHIELD, or the Amazon Fire 2nd gen. But since most smartphones don't support WiFi-Direct, you should install the Android UniJoystiCle app into WiFi-Direct-enabled devices, like the Amazon Fire TV, or the NVIDIA SHIELD Android TV.

Commando mode + Game Controllers

In this mode you control both joysticks at the same time. A game controller is needed for this. Can't be played with the "virtual" dpad. It is called "Commando" mode, since it allows you to play games like Commando, Turrican II or Dropzone since:

  • The dpad and the left stick are mapped to Joystick #2 direction movements
  • The right stick is mapped to Joysticke #1 directional movements
  • Button A is mapped to Joystick #2 Fire
  • Button B is mapped to Joystick #1 Fire
  • Button X is mapped to Joystick #1 Down
  • Button Y is mapped to Joystick #1 Rigth

For example:

  • in Commando you can throw grenades by pressing button B.
  • in Turrican II you can trigger the power lines by pressing button B, and trigger the super weapon by pressing button A and B simultaneously
  • in Dropzone you can use button B to throw bombs and button X to active cloak


  • Any game that uses Joystick #2 + spacebar can be used in this mode. eg: Commando, Turrican II, Dropzone
  • Any dual player game can be played in this mode.

Using this mode: YouTube video

Which controller should you use:

Refer to D-pad + Game Controllers section.

Gyruss mode

In this mode you control the black circle that is inside the blue circle strip. You move the black ball by tilting your smartphone, and gravity will do the rest. Press the gray circle at the right for fire.


  • Gyruss
  • all the UniJoystiCle mode games
  • and games with similar techniques to Gyruss

Using this mode: YouTube video

Note: This mode is only avaible on iOS. Android support coming soon.

Commodore Home mode


Using this mode: YouTube video

Desktop Client Application

The desktop application can be downloaded from here:

It supports three modes:

  • Dpad mode
  • Commando mode
  • Commodore Home mode

Dpad mode

It can be used with a game controller, or with the keyboard. For win32, it supports any Xinput controller (like the xbox 360 controllers), and for Mac, it supports any MFi controller. The keyboard mapping is:

  • cursor arrows: directional movement
  • z: button A
  • x: button B

Commando mode

It can be used with a game controller, or with the keyboard. For win32, it supports any Xinput controller (like the xbox 360 controllers), and for Mac, it supports any MFi controller. The keyboard mapping is:

  • a, s, d, w: Joy #1 directional movement
  • x: Joy #1 fire
  • j, k, l, i and cursor arrows: Joy #2 direction movement
  • z: Joy #2 fire

Commodore Home mode


The Protocol

You can create your own UniJoystiCle controller. Your controller just needs to "speak" the UniJoystiCle protocol, which is very simple.

The WiFi receiver listens to UDP port 6464 and it expects a packet of 4 bytes:

|ver |mode|joy1|joy2|

byte 0, version: must be 2
byte 1, mode: contains state for which joysticks?. 1=joy1, 2=joy2, 3=joy1 and joy2
byte 2, joy1 state
byte 3: joy2 state

Joystick state values:

  • bit 0: Joystick up enable/disable
  • bit 1: Joystick down enable/disable
  • bit 2: Joystick left enable/disable
  • bit 3: Joysticke right enable/disable
  • bit 4: Joysticke fire enable/disable
  • bits 5,6,7: unused

Example, a packet with these bytes means:

0x02, 0x03, 0x11, 0x1f
  • byte 0 = 0x02
  • byte 1 = 0x03: It means the both joy1 and joy2 states are being sent
  • byte 2 = 0x11 = %00010001 = It means that both fire and up are enabled. the rest are disabled
  • byte 3 = 0x1f = %00011111 = It means that all lines are enabled: up, down, left, right and fire

Building the WiFi device

Assembling the PCB

The hardware as well as the software are open source. So you can build one yourself. The schematic and board files are in Eagle format:

You will need the following components (BOM):

And solder them. It should be straightforward where to place the components. If not, ping me

The barrel jack and the diode are optional. They are needed if you want to power the device from an external power source. eg: from the C64 datasette port. Any +5v DC power with at least 320mA should be enough. If you want to avoid the soldering, you can order an already assembled PCB from here.

After assembling the PCB, it should look like this:

Instaling the firmware

And from here you have two options: the "easy" one for users, and the "hard" one for developers:

Option A: For users only

Either you can use:

For you should do:

  • Download the latest UniJoystiCle firmware from here: unijoysticle_firmware.bin
  • Install esptool
    • $ pip install esptool
  • Execute: $ sudo python --port /dev/cu.SLAB_USBtoUART write_flash -fm dio -fs 32m 0x00000 /path/to/unijoysticle_firmware.bin

In case it is needed, it uses a:

  • ESP8266-12e module
  • It has a 4Mbyte (32Mbit) flash
  • use 0x00000000 as offset

For detailed info, read: Flashing the NodeMCU firmware

Since firmware v0.4.2, manual upgrading no longer needed to. It has an option to upgrade itself.

Option B: For developers only

  • Install PlatformIO
  • Clone the UniJoystiCle github repo
  • And do make && make upload


$ git clone
$ cd unijoysticle/esp8266_firmware/firmware
$ make
$ make upload

Firmware options

Click here to enlarge

  • A: Use http://unijoysticle.local/ to access the firmware options
  • B: Stats, includes: IP Address, firmware version, and other status
  • C: WiFi modes:
    • Access Point mode: default mode. Creates its own WiFi network
    • Station mode: uses SSID/password to join the WiFi network
    • Station mode + WPS: Uses WPS to join a network
  • D: Set the SSID/password here in order to use Station mode
  • E: Inactivity timeout. Default: 10 secodns. After N seconds of inactivity, the joystick state will be reset
  • F: Multicast DNS name. Default: "unijoysticle.local". Useful if you want to have more than one UniJoystiCle device in the same network
  • G: To reboot the device
  • H: Press here in order to upgrade the firmware


The first thing to do: download and run this C64 program. Then follow its intructions:

The device (Wemos D1 Mini) doesn't boot

If you don't see one LED on the device then:

  • Make sure it is NOT plugged into the Commmodore 64
  • Power it either:
    • via the micro USB cable
    • or by using the barrel jack: a +5V with at least 320mA should be Ok.
  • Press the RESET button on the Wemos D1 Mini device

If that doesn't work (you don't see the one LED), probably:

  • try booting it again. Just press the RESET button that is in the device
  • or perhaps your device doesn't have the UniJoystiCle firmware. Go to the "Installing the firmware" section
  • you are using power from c64 (datasette, user port or expansion port), and the C64 doesn't have enough current. See When using power from the C64)

When using power from the C64

You should know that all the connected devices compete for the current. Example: If you have an 1541 Ultimate II, a WiModem and the UniJoystiCle, then the three of them will compete for current. If that is the case, most probably one of them won't work.

Tested configurations with current taken from the datasette port:

  • UniJoystiCle + regular c64 PSU + C64: Works Ok.
  • UniJoystiCle + 1541 Ultimate II + regular c64 PSU + c64: Works Ok.
  • UniJoystiCle + Turbo Chameleon 64 + regular c64 PSU + c64: Sometimes it works, sometimes it doesn't
  • UniJoystiCle + Turbo Chameleon 64 + Ray Carlen's PSU + c64: Works Ok
  • UniJoystiCle + Turbo Chameleon 64 + WiModem + Ray Carlen's PSU + c64: Works Ok
  • UniJoystiCle + C128D: Works Ok

So, How much power does The UniJoystiCle use ?

The WiFi module alone uses up to 200mA when it is in Access Point and the clients try to connect to it. But on average it uses ~56mA. More info here: ESP8266 Power Consumption. It also uses 12mA for each joystick line that is High. For example, if 3 lines are High (Joy #1 Up, Joy #1 Fire, joy #Left) then it will use 36mA for that alone. So, a max of 320mA might be needed:

  • Up to 200mA for the WiFi module (but the average ~56mA)
  • plus 120mA when all ten joystick lines are High

Joysticks don't work

  • From your smartphone, make sure that you are connected to the Unijoysticle WiFi network
    • If it fails to connect, try again. Sometimes it take a few tries to connect
    • No more than 2 connections will be accepted (at least in firmware 0.3.1)
  • From the smartphone UniJoystiCle application, make sure that the WiFi device address is:
    • (when in Access Point mode)
    • or unijoysticle.local (which will work both for Access Point and Station modes)

The C64 keyboard doesn't work

This is because the UniJoystiCle smartphone application is sending joystick commands to the C64. Just make sure that the UniJoystiCle smartphone application is not running.

This is not a bug/limitation of the UniJoystiCle. It is a c64 limitation. The c64 keyboard won't work correctly if you keep moving a regular joystick while using the keyboard.

Since firmware v0.4.3, a default inactivity timeout of 10 seconds was added. If no data is received within that period of time, the joysticks are going to be reset.

The game controllers don't work

  • For iOS, both MFi and iCade (the "old" unofficial) game controllers should work.
  • For Android, any official (including Amazon, Nvidia, Moga game controllers) and the OUYA game controllers should work.
  • For Windows, any Xinput-based (the new joystick API) controller should work, like the Xbox 360. If you have a DirectInput-based game controller, try using x360ce
  • For Mac, any MFi game controllers are supported.
  • Make sure that the Game Controller is paired via Bluetooth to the smartphone / PC / Mac.
  • When the game controller is paired to the smartphone/PC/Mac, you can use it in the D-pad and Commando modes:
    • on iOS you should see a legend that says "Game controller detected" (MFi controllers). Or nothing if using iCade controllers.
    • on Android you should see the name of the game controller in the title
    • on Mac/Windows, you should see "Game controller: Connected" on the status bar (bottom-left)

Some joystick movements work but others don't

  • Probably one (or more) of the 4066 ICs are malfunctioning. Try swapping them until you find the broken one. And then replace it with a new one
  • or perhaps one of the traces in the PCB is open. With a multimeter and the schematic you should be able to find it.


Did you find a bug? Please report it here: