TinyG Feedhold and Resume - synthetos/TinyG GitHub Wiki

updated 6/8/13 - ash

NOTE: This page describes feedholds supported in release 0.95 / build 377.08 and later which is currently in the edge branch

See Single Character Controls in edge-0.97 build 449 below for the current behavior of !, ~, % and the other characters the serial input traps.

Character Command AKA Description
! Feedhold Pause Stop movement immediately. Maintains positional accuracy
~ Cycle Start Resume Resume movement from stopping point
% Queue Flush Empty planner buffer. Used for jogging and other cycles

To pause motion send a feedhold character ('!') character during motion. Movement will decelerate to a stop while maintaining positional accuracy. To resume motion send a cycle start tilde character ('~').

If you wish to not perform the remainder of the move after the feedhold send a queue flush character ('%') after the feedhold character. Motion will start with the next Gcode command entered. A cycle start is not necessary after a queue flush.

During a G4 dwell, ! enters feedhold immediately and the board reports the hold state. The dwell timer continues to run, but queued motion stays stopped until ~ resumes the job. A % during the hold discards the remaining dwell and queued work immediately, then clears the hold. A job kill (^D) also discards the remaining dwell and enters ALARM; it does not wait for the dwell timer to expire. A ! sent while the machine is idle outside a cycle remains a no-op. Pausing the dwell timer itself is a possible future extension.

Stop requests while output is paused

A feedhold (!) or job kill (^D) that reaches the board is honored even when outgoing serial data is paused by XOFF or CTS and the transmit buffer is full. Feedhold decelerates motion normally. Job kill also enters the alarm state and turns off spindle and coolant. Replies and the job-kill alarm message wait until output can continue; silence on the paused output does not mean the stop request was ignored. Resume and input-queue cleanup finish through the normal command loop after the blocked output clears.

Hardware flow control during a hold

With RTS/CTS enabled ($ex=2), TinyG keeps its receive-ready signal asserted during a requested or active feedhold, a program pause, or an alarm. This lets controls reach the board even when queued motion cannot drain the input buffer. Stop sending program data when pausing; the input storage remains finite.

If incoming data exhausts that storage, TinyG refuses resume, discards the damaged input backlog, and raises an alarm with status 13 and the message input lost. A ~ cannot resume that damaged job. Resolve the alarm and restart from a known program position instead of assuming all transmitted lines were retained. The usual line-start rules still apply to ~ and %.

Jogging Using Feedhold and Queue Flush

To jog using feedhold and queue flush do the following:

  • Start the jog by issuing a move in the jogging direction at the velocity you want for the jog
  • Send a ! when the user wants the jog to stop
  • Send a % to flush the remainder of the move. These can be sent together in a single transmission: "!%"

Nudge moves to fine-tune the jog can be performed by issuing short Gcode moves such as G91 G1 F100 X0.001

Jog Commands (build 449)

This section describes edge-0.97 build 449.01.

{jogx:<position>}, {jogy:...}, {jogz:...} and {joga:...} (or $jogx=<position> etc.) start a jog of one axis:

  • The value is the destination in machine coordinates, in mm (degrees for A), whatever the G20/G21, G90/G91 and coordinate system settings.
  • The axis moves from where it actually is, starting at 10 mm/min and ramping up over a series of short moves (at most 25, covering up to about 26 mm) to the axis maximum velocity ($xvm), then runs to the destination.
  • When the jog has finished TinyG sends {"jog":0} (JSON, also in text mode) and restores the units, distance mode, coordinate system and feed rate; the motion mode is set to G80.
  • A jog clears any feedhold and discards moves that are still in the planner queue when it starts.
  • Reading a jog token ({jogx:n}) returns nothing. There are no B or C jog tokens.
  • Use ! to stop a jog early, then % to discard the rest of it.
  • Like other settings, jog commands are rejected while the machine is alarmed.
  • An alarm raised during a jog remains an alarm after the jog stops and its settings are restored. Ending the jog does not clear it or turn it into a normal program stop. Resolve the cause and explicitly clear the alarm before starting another move; see TinyG Alarms.

Remember to set the system back to absolute mode by issuing a G90.

Single Character Controls in edge-0.97 build 449

Changed in edge-0.97 build 449: % and ~ are recognized only at the start of a line, and a % discards only the input that arrived before it.

The USB serial receive interrupt traps the characters below as soon as they arrive. They are not put in the input buffer, they are not queued behind other input, and they do not generate a response line.

Character Name Recognized Effect
! Feedhold Anywhere in the input, including inside a line, a Gcode comment or a JSON string Requests a feedhold. Honored only while the machine is moving and not already in a feedhold; otherwise ignored.
~ Cycle start (end hold) Only at the start of a line (spaces and tabs before it are allowed) Resumes from a feedhold. Ignored if no feedhold is in effect. If a queue flush is also pending, the flush is done first.
% Queue flush Only at the start of a line Honored only while a feedhold is in effect (an alarm also enters a feedhold). Once motion has stopped the planner queue is flushed, the position is set to where the machine actually stopped, the feedhold is ended, and all host input that arrived before the % is discarded. Input sent after the % is kept and runs normally. A % received when no feedhold is in effect is ignored and discarded.
^d (0x04) Job kill Anywhere, including inside a line Raises an ALARM with status 207 ("Kill job"), in or out of a feedhold: motion stops, spindle and coolant turn off, the planner queue is flushed, and commands are rejected until {clear:n}, $clear, M2 or M30 (see TinyG Alarms). Added in edge-0.97 build 449 (E096); earlier builds ignored ^d.
^x (0x18) Reset Anywhere Immediate hardware reset through the watchdog timer, the same as pressing RESET. Position, machine state and all queued input are lost; the board restarts and prints its startup messages.
ENQ, ^e (0x05) Enquiry Anywhere Answered with {"ack":true} from the main loop.
XON (0x11), XOFF (0x13) Flow control Anywhere, only when XON/XOFF flow control is enabled ($ex=1) Resume or pause TinyG's serial transmitter.

Notes:

  • A % or ~ that is not at the start of a line (for example inside a comment, or after other characters) is passed through as ordinary text.
  • A ! is always trapped, even inside a comment or a (msg...) message. Do not use ! in Gcode comments.
  • Sending !% together still works: the trapped ! does not count as the start of a line, so the % that follows it is recognized.
  • An M0, M60 (or M1 with $os=1) program stop also leaves the machine in a feedhold when it is reached; send ~ to continue, or % to discard the rest of the queue.
  • A ! that arrives while the last queued move is finishing is either honored (the machine holds, hold reports 6) or, if the move has already ended, dropped (hold stays 0). It is never left pending. Before the fix in edge-0.97 build 449 (E116), a ! landing on the final segment could stay requested: the cycle never ended, a later ! was ignored and the next move was held as soon as it started.
  • A ! sent in the first moments after a move was queued from idle (see "First move after idle" on Jerk Controlled Motion Explained) holds at once: no step has been taken, so there is nothing to decelerate.
  • {qf:1} (or $qf=1) requests the same queue flush as %, but discards all buffered host input. Like other settings it is rejected while the machine is alarmed.
⚠️ **GitHub.com Fallback** ⚠️