Arcade joystick lever
The lever in a fight stick or an arcade cabinet, Sanwa JLF style: a ball top on a shaft with four microswitches around its foot.
Aliases: arcade stick, Sanwa lever, JLF, 8-way joystick, digital joystick.
It is not the thumb stick in the starter kits. That one is two potentiometers and
reads with analogRead; this one is four switches and reads with
digitalRead. Push it up and the up switch closes; push it into a corner and two
close, which is how a diagonal reaches the board.
Pins
The five-pin harness, left to right:
| Pin | What it does |
|---|---|
GND |
The common: one leg of every switch. Wire it to ground. |
UP |
Closed to GND while the lever is up, up-left or up-right. |
DOWN |
Closed to GND while the lever is down or in a lower corner. |
LEFT |
Closed to GND while the lever is left or in a left corner. |
RIGHT |
Closed to GND while the lever is right or in a right corner. |
On a real JLF the switch that closes for up sits at the bottom of the PCB, because the shaft pushes the far side. The harness is labeled by direction, and so are these pins.
Properties
gate is the restrictor plate under the washer:
square, what a JLF ships with: all eight directions.octagon, the common swap: all eight directions, with grooves that guide the lever into the corners. Electrically the same as square.4way, a plus-shaped slot for maze games: no corners, so never two switches at once.
bounce, off by default, makes each switch chatter once as it closes or opens,
inside 2 ms.
While it runs
Drag the ball toward a direction, or use the arrow keys or W A S D. Hold two keys for a diagonal. Let go and it springs back to center.
Reading it on an Arduino
Four pins with their pull-ups on, each LOW while its direction is held:
const int UP_PIN = 2, DOWN_PIN = 3, LEFT_PIN = 4, RIGHT_PIN = 5;
void setup() {
pinMode(UP_PIN, INPUT_PULLUP);
pinMode(DOWN_PIN, INPUT_PULLUP);
pinMode(LEFT_PIN, INPUT_PULLUP);
pinMode(RIGHT_PIN, INPUT_PULLUP);
}
void loop() {
bool up = digitalRead(UP_PIN) == LOW;
bool right = digitalRead(RIGHT_PIN) == LOW;
// up and right together is the up-right diagonal
}
The Arcade lever template prints the direction in numpad notation, the way fighting game players write it: 5 is neutral, 8 is up, 6 is right, 9 is up-right.
What the model gets right
Four contacts and a common. A closed switch is a low-resistance contact from its
pin to GND, passing current either way; an open one leaves its pin floating, so
without a pull-up the pin reads nothing useful, as on the real harness.
The shaft cannot be on both sides. Up and down are never closed together, and neither are left and right. If both of an opposed pair are pushed at once (two keys held), the newer one wins, the way the shaft swings over. A fight stick firmware's SOCD cleaning still matters for a hitbox, where four separate buttons can all be down; it does not for a lever.
The 4-way plate. With the lever in one arm of the plus, pushing the other axis too does nothing: the only way into the other arm is back through the center.
Bounce, when it is on: one make, one rebound, one settle per switch that moves, the pattern a snap-action microswitch shows on a scope.
What it does not model
The spring's feel, the engage distance and the throw: the lever is either in a direction or not. Square and octagon gates differ only in the picture. The microswitch's bounce, when on, is the same fixed pattern every time.
Common mistakes
Forgetting INPUT_PULLUP: with nothing pulling the pins up, a released direction
floats instead of reading HIGH.
Reading the lever as analog. analogRead on a switch pin gives 0 or 1023 and
nothing in between; the thumb stick is the analog one.
See it in action
Arcade lever prints the numpad direction and lights an LED per direction on an Uno. Open it at /templates.