4-way Or 8-way Joystick Restrictor Mod

4-way or 8-way joystick mod

Having a restricted 4-way or 8-way digital joystick for an arcade game is fine if the joystick is built into a game cabinet that plays only one game — 4-way for Pacman and 8-way for Super Cobra. But [Tinker_On_Steroids] wanted a joystick that could be restricted as either 4-way or 8-way for a cabinet that could play a multitude of games, and it had to switch from one type of restriction to the other automatically based on the selected game.

His digital joystick already came with a plate that can be mounted for either 4-way or 8-way restriction, but it has to be manually screwed in place for one or the other. He removed it and designed two 3D-printable parts, one that is to be mounted firmly to the bottom of the joystick and the other that rotates within the first one. Rotated in one orientation gives 4-way restriction and in the other orientation gives 8-way. That left only attaching a servo to do the rotation. The first video below shows mounting this all to the joystick and demoing the servo using a Teensy. The STL files for the parts are on his Thingiverse project page.

He also shows a simple circuit board he made that has two buttons and two LEDs on it for connecting to the Teensy and controlling the servo. And as an added option he shows how to talk to the Teensy from his desktop computer through USB and control the servo that way. In the second video below he details all that and also does a walk-through of the code he wrote for the Teensy. On the Thingiverse page he provides only the hex file but it’s likely you’d write your own software for interfacing with a game anyway.

[Tinker_On_Steroids] isn’t the only one who’s had to modify joysticks to get good gameplay on the old games. [Chris Osborn] had to make a modern USB gamepad work with his Apple II to get around problems with his old Apple joystick. Or maybe your joystick is getting worn out and needs fixing as [Frenetic Rapport] did for his Nintendo 64.

Thanks to [EVR] for the tip.

41 thoughts on “4-way Or 8-way Joystick Restrictor Mod

      1. Only if you just apply full power to it. There are solenoid driver designs out there that cut back the current significantly after activation. I designed one for a shutter that charged up a capacitor with a little DC/DC converter and then dumped that into the solenoid with a SCR and then kept it solenoid closed with just 5v.

        But all you really need is a small transistor off one of the GPIOs. And a diode to kill the inductive pulse when it releases.

    1. Wouldn’t even need a fancy rotary solenoid. A linear one, without a return spring, a rod and a couple of mini Heim rod ends would do the job. Incorporate a spring loaded ball detent to keep the mechanism in position and the thing could be switched with a DPDT, spring loaded, center-off toggle. Pop it one way for 8-way, the other for 4-way.

      Electromechanical FTW.

  1. I’m a little bit sceptical about the holding power of that microservo – I remember treating those sticks rather badly in heated highscore battles back then, I presume that the servo will loose the fight against the leverage of the joystick really quick…

    1. I was wondering the same thing myself. I bought a bunch of servos that look very much like those (I didn’t check the part #s) for just a couple of bucks each. They were marketed as suitable for polystyrene foam model planes.

      It’s hard to see how the restrictor actually works, but I’m thinking the stresses on the plate isn’t in the right direction to force the servo out of position. The videos aren’t loading for me at the moment, so I’m guessing that information is in there.

      1. Yep! …exactly right.
        Most of the players force is captured by the joystick itself.
        The only forces that affect the servos base assembly push against the limiting square of the inner tube. And that tupe gets pushed agains the wall of the base plate which is very solid itself and hold with 4 screws.
        Regards,
        Stefan (aks “ToS”)

  2. Arcade machine Joysticks do get a lot of abuse over the years. A plastic restrictor may be fine for individuals, but in a real arcade environment they won’t last more than a few days…

    1. You may want to go inform Happ, Sanwa, and Seimitsu that they’ve been doing it wrong all these decades now.
      The design of the joystick doesn’t apply a lot of force to the restrictor plate itself.

  3. I really want a dual-analog wireless PC gamepad that can change between circular travel (for mainstream modern games AKA console ports – yes, all your console gamepads can’t hit the limits of X&Y travel at the same time, they’re restricted to a circle that excludes the corners!) and square travel (for old games and flight sims – they expect you to be able to reach the corners). Maybe something like this could make it possible.

    1. There are joystick controllers that will happily emulate such behavior on an analog stick. IIRC, Ultimarc has a controller that does this. I never bought it so I can’t vouch for it, I just built my own.

  4. Lol at the responses.. nope, it doesn’t look super robust, its a “hack” not a production design. Isn’t that the name of the site? I found it clever and novel. This is the kind of content hackaday really needs more of. People don’t come here looking for a complete, polished, turn-key tutorial to blindly follow and learn nothing – but for a great source of inspiration.

    I hadn’t considered something like this could even exist – if I want it in a project where I need it to be robust, i can re-engineer it to be so, this article/project has still provided the basis and passed along the idea, very nice.

    1. I don’t recall myself, it’s been a long time since I played one with a joystick, so I went by what [Thinking_On_Steroids] said (plus it seemed to make sense). However, I just did a google image search for “pacman arcade machine” and turned up photos of the machine with joysticks with 4 arrows surrounding them (https://www.google.ca/search?q=pacman&biw=1177&bih=652&source=lnms&tbm=isch&sa=X&ved=0ahUKEwj8xrjW19jRAhWD54MKHRqOBE0Q_AUIBigB#tbm=isch&q=pacman+arcade+machine&imgrc=haoe73cqQ0euKM%3A). I’m guessing that means 4-way.

    2. Nope, I own one. Definitely 4-way. And as others said, many 4-way games (including Pac-Man), misbehave with an 8-way stick. It’s not really a bug, per se, because it’s the result of an invalid input.

        1. I have an old Dell pc running my arcade But I have an Arduino nano that’s sitting on a shelf in my garage. Are you saying I could use it?
          Please can you show my how
          Thank you for your time.

          1. The Raspberry has GPIOs. The Dell PC doesn’t.
            With the Arduino you could create the GPIOs. PC> USB> NANO> GPIOs> Servos

            Some links:

            https://www.meccanismocomplesso.org/en/tutorial-sending-values-from-pc-to-arduino-by-serial-communication/

            https://geekduino.de/2019/08/26/arduino-pwm-servo/

            Unfortunately, you have to do the details yourself.
            You have to sit in front of the hardware to test it. Unfortunately, I cannot offer a plu-and-play solution.

          2. Arduino ino:

            #include <Servo.h>
            
            Servo servo_test; // Erstellen eines Servo-Objekts
            
            void setup() {
               Serial.begin(9600); 
               servo_test.attach(8); // Das gelbe Kabel (PWM) wird an D8 angeschlossen.
            }
            
            void loop() {
            
                char buffer[] = {' ',' ',' '}; // Receive up to 3 bytes
                while (!Serial.available()); // Wait for characters
                Serial.readBytesUntil('\n', buffer, 3);
                int incomingValue = atoi(buffer);
                //Serial.println(incomingValue);    // Zeige Wert im Monitor
            
                int n = incomingValue;
            
                if (n < 0) {
                 n = 0;
                }
            
                if (n > 180) {
                 n = 180;
                }
            
                Serial.println(n);    // Zeige Wert im Monitor
                servo_test.write(n);
            
            }
            

            Python program for PC:

            #!/usr/bin/python3
            
            import serial
            import time
            ser = serial.Serial('/dev/ttyUSB0',9600)   # USB anpassen!
            ser.isOpen()
            time.sleep(1)
            
            while 1:
               eingabe = input("Winkel? ")
               print(eingabe)
               ser.write(eingabe.encode())
            
        2. Thank you for the links with this information you provided I should be able to get it working .Fantastic if you do mine when I finish I will update you
          I appreciate you Help!

          1. Here is a new ino that can control 2 servos.

            Values from 0 to 180 control servo 1.

            Values from 200 to 380 control servo 2.

            In addition, the PWM signal is now always switched off after execution. So you can also connect an LED as an indicator to the relevant PWM pin (I connected a red LED using a 220 Ohm resistor).

            This also prevents the servo from twitching.

            [CODE]#include

            Servo servo_test; // Erstellen eines Servo-Objekts

            int Servopin1 = 8; // Das gelbe Kabel (PWM) von Servo 1 wird an D8 angeschlossen.

            int Servopin2 = 7; // Das gelbe Kabel (PWM) von Servo 2 wird an D7 angeschlossen.

            void setup() {

            Serial.begin(9600);

            }

            void loop() {

            char buffer[] = {‘ ‘,’ ‘,’ ‘}; // Receive up to 3 bytes

            while (!Serial.available()); // Wait for characters

            Serial.readBytesUntil(‘\n’, buffer, 3);

            int incomingValue = atoi(buffer);

            //Serial.println(incomingValue); // Zeige Wert im Monitor

            int n = incomingValue;

            if (n 380) {

            n = 380;

            }

            if (n >= 200) {

            n = n – 200;

            Serial.println(n); // Zeige Wert im Monitor

            servo_test.attach(Servopin2);

            servo_test.write(n);

            delay(600);

            servo_test.detach();

            }

            else {

            Serial.println(n); // Zeige Wert im Monitor

            servo_test.attach(Servopin1);

            servo_test.write(n);

            delay(600);

            servo_test.detach();

            }

            }[/CODE]

          2. Here is a new ino that can control 2 servos.

            Values from 0 to 180 control servo 1.

            Values from 200 to 380 control servo 2.

            In addition, the PWM signal is now always switched off after execution. So you can also connect an LED as an indicator to the relevant PWM pin (I connected a red LED using a 220 Ohm resistor).

            This also prevents the servo from twitching.

            #include <Servo.h>
            
            
            Servo servo_test; // Erstellen eines Servo-Objekts
            
            
            int Servopin1 = 8; // Das gelbe Kabel (PWM) von Servo 1 wird an D8 angeschlossen.
            
            int Servopin2 = 7; // Das gelbe Kabel (PWM) von Servo 2 wird an D7 angeschlossen.
            
            
            
            void setup() {
            
               Serial.begin(9600);
            
            }
            
            
            void loop() {
            
            
                char buffer[] = {' ',' ',' '}; // Receive up to 3 bytes
            
                while (!Serial.available()); // Wait for characters
            
                Serial.readBytesUntil('\n', buffer, 3);
            
                int incomingValue = atoi(buffer);
            
                //Serial.println(incomingValue);    // Zeige Wert im Monitor
            
            
                int n = incomingValue;
            
            
                if (n < 0) {
            
                 n = 0;
            
                }
            
            
                if (n > 380) {
            
                 n = 380;
            
                }
            
            
                if (n >= 200) {
            
                 n = n - 200;
            
                 Serial.println(n);    // Zeige Wert im Monitor
            
                 servo_test.attach(Servopin2);
            
                 servo_test.write(n);
            
                 delay(600);
            
                 servo_test.detach();
            
                }
            
                else {
            
                 Serial.println(n);    // Zeige Wert im Monitor
            
                 servo_test.attach(Servopin1);
            
                 servo_test.write(n);
            
                 delay(600);
            
                 servo_test.detach();
            
                }
            
            }
            

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.