Skip to content

Jogging from a Host

Riley Porter edited this page Nov 11, 2026 · 1 revision

Jogging from a host

This page describes how a sender, UI or pendant can jog a TinyG smoothly with ordinary G-code: single steps, a held key or button, and a handwheel. It needs no special firmware commands and works on current firmware (tested on the bench with 450.04 and 450.02: continuous motion with no slowdown between moves, and the reported position matches the motor steps after a stop).

The idea: send short relative moves, keep only a few of them queued, and stop with a feedhold and a queue flush.

Before you start

  • Use line mode ($rxm=1). Every line gets one answer, so the host always knows how many lines the board has taken, and control commands are served first even while moves are queued. See Sending Data to TinyG using RX Packet Mode.
  • Send one line at a time: write the next line only after the previous one is answered. Realtime characters (!, ~, %) are the exception; they are acted on at once.
  • Read the modes you will change ({"unit":null}, {"dist":null}) so you can put them back afterwards.
  • Set the units on their own line first (G21): a G20/G21 in the same block as an F word applies after F is read.

A single jog step

A step is one relative move of the whole distance:

G21
G21 G91 G1 X10 F1000

When the machine is at rest again, restore the distance mode (G90, and G20 if the machine was in inches). The planner gives the step a normal acceleration and deceleration, so it is one smooth move.

A held key or button

While the key is held, feed the motion in short pieces:

  • Piece length = feed rate x piece time. With a piece time of 150 ms at F1000: 1000 / 60 x 0.15 = 2.5 mm, so each piece is G21 G91 G1 X2.5 F1000.
  • Keep about 4 pieces queued. Work out how many are queued from the queue report: queued = planner size (32) - qr + pieces sent since that report. Send the next piece whenever fewer than 4 are queued: after each piece's answer, and after each status poll.
  • Stop when the key is released, or when the UI stops renewing the jog (for example, no renewal for 500 ms). Stopping on a missing renewal means a lost connection or a hung UI cannot leave the machine jogging.

Because the pieces are queued back to back in the same direction, the planner blends them into one continuous motion; there is no slowdown between pieces. Four pieces of 150 ms keep about 0.6 s of motion ahead, which is enough to ride out normal host and USB delays while still letting a stop take effect quickly.

Stopping

  1. Stop sending pieces.
  2. Send ! (feedhold). The machine decelerates along its path.
  3. Poll until the hold is complete (hold 6) or the machine is at rest.
  4. If anything is still held or queued, send % (queue flush). The remaining pieces are discarded.
  5. Poll until hold is 0 and qr is 32 (planner empty), then restore the modes (G90, and G20 if needed).

The reported position after the stop matches where the motors actually stopped.

Note: with spindle pause on feedhold enabled ($spph=1, the default on 450.04), a spindle that is running stops when the hold completes. Jogging is normally done with the spindle off.

A handwheel (MPG)

Send each detent, or the detents counted in a short interval, as a small relative move: G91 G1 X0.1 F<feed>, where the feed is chosen so the move takes about as long as the interval. Cap the number of queued moves as above (about 4), and drop detents that arrive while the queue is full, so the machine never runs on after the wheel stops. Stop with ! then % as above when the wheel has been still for a short time and you want an immediate stop.

Typed moves

A long move typed by the operator (for example G1 X40 F600) can be split the same way into pieces of about 1.25 s each, fed 4 deep, so that Pause (!), Resume (~) and Stop (! then %) respond quickly.

Related

Clone this wiki locally