TinyG edge-next: 126 fixes from a long-overdue bug hunt
TinyG has been quiet for a while. Its last firmware branch, edge-0.97, dates from 2016, and the forum archive is full of reports that never got a fix: a homing cycle that "worked" with a broken switch wire, a stray character that turned a 5 mm move into a 545 mm one, a spindle that kept running after an alarm. We went back and hunted them down.
The result is a new firmware branch, edge-next. It builds on edge-0.97, keeps its settings defaults, and fixes 126 bugs. Every fix comes with a test that reproduces the bug on a real TinyG v8 board and then passes once the fix is in.
- 126bugs fixed
- 23rated critical or high severity
- 263hardware tests, one or more per bug
- 47,604test runs on real boards
Safety first: the fixes that matter most
A motion controller has one job above all others: never move when it shouldn't. These fixes close gaps where TinyG could move unexpectedly or keep going when it should have stopped:
- Damaged serial input no longer runs. If the receive buffer overflowed, two G-code lines could be spliced into one, and on our bench this produced a 583 mm Y move. Now a damaged line never executes; the board raises an alarm and tells the sender which line was lost. (E162)
- No more invented numbers.
G1 X10 E5read the E as an exponent and sent X to a million millimetres. A stray character like*was deleted and the digits around it joined, soY5*45becameY545. Both lines are now rejected. (E159, E161) - Unsupported codes are errors, not guesses.
G59.1used to run asG59, andM3.1started the spindle. Codes TinyG doesn't implement are now refused. (E150) - Alarms stop the spindle and coolant. They used to stay on through an alarm or shutdown. Now they switch off at once and can't be turned back on until the alarm is cleared. (E019)
- Limit switches no longer miss edges. A lockout after one switch event could drop the next one. (E050)
- A broken limit switch fails homing. A stuck or open switch, such as a broken normally-closed wire, used to let homing "succeed" anywhere. Now homing fails. (E132)
- Probing in the air fails.
G38.2with the probe already closed used to report success. It now alarms. (E070) - Arcs respect soft limits. Arcs were never checked; now the endpoint and every extreme of the arc are. (E041)
- Moves queued before an alarm stay stopped. They used to run anyway. (E044)
- Kill job works.
Ctrl-Ddid nothing on any build. It now stops the job and flushes the queue, which is what CNCjs's "Stop (force)" sends. (E096)
However good the firmware gets, software is not an emergency stop. Every machine needs a hardware E-stop that cuts motor power, within reach of the operator.
Stopping sooner at a limit switch
When a limit switch tripped, TinyG used to start a gentle feedhold from its main loop, using the normal deceleration. Now the switch interrupt requests a stop directly, using the much steeper homing jerk, and the board keeps track of its position through the stop. We measured both versions on the bench with a logic analyzer on the step line, hitting the switch at 10 mm/s:
Smoother starts
From idle, TinyG used to start the first move before it had seen the second one, so it planned a full stop between them even when the path was straight. Now the planner waits a few milliseconds for the next move before starting. Two back-to-back moves now flow into each other instead of stopping in between:
Where the bugs were
A few more worth knowing about:
- Settings survive firmware updates. Every build number change used to wipe all settings. (E022)
- Feedhold is reliable. A feedhold that arrived just as a move finished could leave the machine stuck; resume used stale speeds; plain
G0/G1moves never started a cycle at all, which broke hold and cycle-end reporting. (E116, E030, E033) - A
%or~inside a comment such as(50% feed)no longer flushes the queue or resumes motion. (E021) - Settings are validated. Zero or negative step angles, travel and jerk, and empty values like
$xvm=, are refused instead of saved. (E158, E131) - Better sender compatibility. The CNCjs connect sequence no longer causes an alarm, and OpenPnP no longer times out on every move. (E095, E097)
- Machine position is kept through a shutdown or panic. (E046)
New features
- For pick-and-place:
M114(report position),M115(firmware info),M400(wait for moves to finish), per-axis jerk withM201.3, and a raw analog input for vacuum sensing (M105). - Optional stop:
M1pauses only when$os=1. - Configurable polarity for spindle enable, spindle direction and the probe input.
- Motor power timeout with
{me:N}. - Rotary axis homing within one turn.
- Longer JSON lines, up to 254 characters.
- Old backups restore: settings files saved from 440-series firmware load correctly.
How it was tested
Every bug started as a failing test. A test harness drives a real TinyG v8 over USB, and each known bug is recorded as a test that's expected to fail. A fix only counts when its test passes on the board, and when the whole suite still passes with it. The harness won't move a motor unless motion is explicitly allowed, and it snapshots the board's settings before each session and restores them afterwards.
Timing fixes like the two above are measured with a logic analyzer on the step, direction and switch lines, sampling at 12 MHz. The raw captures and the scripts that turn them into numbers are kept with the firmware, so anyone can check the results.
Before you upgrade
Most machines will just work better, but a few changes can affect existing setups:
- Stricter G-code. Lines that older firmware quietly misread, such as modal conflicts like
G0 G1, dotted codes TinyG doesn't support, or 3D-printerEwords, are now rejected with an error. Run your usual programs in the air first. - G18 arcs now turn the standard way, matching RS274NGC, LinuxCNC and grbl. If your CAM post was set up to work around the old direction, change it back. (E029)
- Tool length offset (
G43.1) now has the standard sign and is applied once, as in LinuxCNC and g2core. (E037) - Probing no longer turns the spindle or vacuum off. (E061)
Ctrl-Dnow kills the job.{me:N}sets the motor power timeout; it no longer selects motor N.- Settings defaults are unchanged. Back up your settings anyway: going back to older firmware after upgrading can reset or misread them.
Known issues
A bug hunt this size finds more than it can fix in one go. Still open, and tracked: a suspected race between feedhold and homing (E114), and requests that read alarm, shutd or me actually triggering them (E138), which matters if you write host software. Speed overrides (M48–M51) were never implemented and now return an error instead of being silently ignored.
How to get it
The source is on the edge-next branch of synthetos/TinyG on GitHub, along with the full change log and the test results. It reports firmware build 450.01 ($fb), so you and your sender can tell it apart from the older edge-0.97 (449.01). Back up your settings before flashing, test with an E-stop within reach, and if something doesn't behave, tell us on the community forum.
A browser-based firmware updater is on the way, so you won't need a toolchain to install it. More on that soon.