The HAL component toggle2nist is designed to provide this function.
An example is on the forum [here].
E-Stop -A red, protruding, button that locks in position that signals LinuxCnc? to trigger an E-Stop condition Pause - An amber, protruding, momentary button, that tells LinuxCnc? to pause the running program Run - A green, recessed, momentary button. I wanted this to either begin running a program, or resume it if it is paused.
The first two buttons are trivial to add. Their signals connect directly to halui.program pins.
Here's the problem. "Run" and "Resume" are two distinct operations. HAL must decide which signal to generate based on the current state of the system. In addition, halui must be in 'auto' mode in order to run the program. It must be requested if it is not already selected. Furthermore, timing can be a bit tricky. Continuing to assert halui.mode.auto, halui.program.resume, or maybe even halui.program.run can result in screwey behavior. An ideal solution is to assert these signals only until they take effect.
We are using two inputs of the flip flop: "set" and "reset". The logic of the output is follows:
Here's how we use it to request 'auto'.
The logic uses 'and2' components to decide which mode to request. If the button is pressed and the program is idle, we want to run the program. Alternatively, if the button is pressed and the program is paused, we want to resume the program. These two 'and2' components are shown in the diagram below.
We use flip flops for each of these signals to limit how long they are presented. Once 'halui.program.is-running' is true, we no longer need to assert either 'run' or 'reset'.
You will also notice the 'edge' component. This component is used to ensure that only one signal is generated. The short pulse generated by 'edge' is sufficient to trigger the 'set' pin on either flip flop. Without this component, if linuxcnc momentarily goes to 'idle' on its way from 'paused' to 'running', the other 'and2' component would fire, generating a 'run' command, thus starting the program over instead of resuming.