Nothing like sleeping on a problem. It turns out that a chunk of HAL code can do a nice job of locking out an inactive joystick axis.
The general idea:
- A priority encoder selects one axis when both go active simultaneously
- The prioritized outputs set flipflops that remember the active axis
- The active axis locks out the other one until they’re both inactive
That way, you can start to jog either axis on a knob without worrying about accidentally jogging the other axis by moving the knob at a slight diagonal. I hate it when that happens.
The other tweak is that the quartet of buttons on the right act as a “hat” for the Z and A axes, jogging them at the current maximum speed.
Because it’s tough to accidentally push two buttons at once, there’s no need to lock them out. So you can jog diagonally by deliberately pushing adjoining buttons, but you must want to do that.
Rather than dumping the whole program again, here are the key parts…
Figuring out if a joystick axis is active uses the window comparators. It seems the idle counts value varies slightly around 127, so I relaxed the window limits. Should the window comparator go active with the knob centered, the buttons for that axis won’t produce any motion.
net x-jog-count-int input.0.abs-x-counts conv-s32-float.0.in net x-jog-count-raw conv-s32-float.0.out wcomp.0.in setp wcomp.0.min 125 setp wcomp.0.max 130 net X-inactive wcomp.0.out not.0.in net X-active not.0.out
The priority encoder is just a gate that prevents Y (or A) from being selected if X (or Z) is simultaneously active. Here’s a sketch for the ZA knob:

The active and inactive signals come from the window detectors. The sketch gives the K-map layout, although there’s not a whole lot of optimization required.
The corresponding code:
net Z-inactive and2.5.in0 net A-active and2.5.in1 net A-select and2.5.out # select A only when Z inactive net Z-inactive and2.6.in0 net A-inactive and2.6.in1 net ZA-Deselect and2.6.out # reset flipflops when both inactive net Z-active and2.7.in0 # set Z gate when knob is active net A-gate-not and2.7.in1 # and A is not already gated net Z-set and2.7.out flipflop.2.set net ZA-Deselect flipflop.2.reset # reset when neither is active net Z-gate flipflop.2.out not.6.in net Z-gate-not not.6.out net A-select and2.8.in0 # set A gate when knob is active net Z-gate-not and2.8.in1 # and Z is not already gated net A-set and2.8.out flipflop.3.set net ZA-Deselect flipflop.3.reset # reset flipflop when both inactive net A-gate flipflop.3.out not.7.in net A-gate-not not.7.out
The flipflops remember which axis went active first and lock out the other one. When both axes on a knob return to center, the flipflops reset.
The quartet of buttons produce binary outputs, rather than the floats from the Hat, so a pair of multiplexers emit -1.0, 0.0, or +1.0, depending on the state of the buttons, for each axis.
setp mux2.6.in0 0.0 setp mux2.6.in1 -1.0 net A-btn-neg input.0.btn-trigger mux2.6.sel net A-btn-neg-value mux2.6.out sum2.1.in0 setp mux2.7.in0 0.0 setp mux2.7.in1 1.0 net A-btn-pos input.0.btn-thumb2 mux2.7.sel net A-btn-pos-value mux2.7.out sum2.1.in1 net A-jog-button sum2.1.out net A-btn-neg or2.1.in0 net A-btn-pos or2.1.in1 net A-btn-any or2.1.out or2.2.in0 net A-gate or2.2.in1 net A-motion or2.2.out
The A-motion signal is true when either of the A jog buttons or the A joystick axis is active. That gates the MAX_ANGULAR_VELOCITY value to halui.jog-speed, rather than the default MAX_LINEAR_VELOCITY. Or, depending on the state of the toggle from the two joystick push switches, 5% of that maximum. A mere 5% may be too slow for the A axis, but it’ll take some experience to determine that.
With that in hand, the final step is gating either the knob or the button values to halui.jog.*.analog.
net Z-jog-button mux2.8.in0 net Z-jog-knob-inv mux2.8.in1 net Z-gate mux2.8.sel net Z-jog mux2.8.out halui.jog.2.analog net A-jog-button mux2.9.in0 net A-jog-knob input.0.abs-z-position mux2.9.in1 net A-gate mux2.9.sel net A-jog mux2.9.out halui.jog.3.analog
The complete source file (Logitech Dual Action Gamepad – joystick axis lockout – custom_postgui-hal.odt) is over on the G-code and Suchlike page, so you can download it as one lump. It’s an OpenOffice document because WordPress doesn’t allow plain text files.
I loves me my new joggy thing!
I finally got it working thanks to your examples. It would have taken me a LOT longer to get it figured out without you having done the leg work first. I have a three axis machine X2 with a cncfusion/xylotec kits installed. With the mode button selected it locks out both the x & y axis from being selected at the same time on the hat and knob buttons. It has three speed selections using the 3 right buttons with the lowest speed allowing me to jog at .00025 at a time. I’m going to try and post the contents of the custom hal file in hopes that it might save others some pain in creating there own.
Thank again,
Dave
It’d probably be better as an addition to the EMC2 wiki or doc, as they have a page for joystick things and it’d be visible to more folks there than here.
There must be a limit to the comment size because it won’t accept the size of the file but I’d be glad to sent it to you to post if you like. I prefer the way the speed selection as it allows for very fine jog speeds using the knobs.