Tool data is conventionally described by a tool table file specified by an inifile setting: [EMCIO]TOOL_TABLE=tooltable_filename. A tool table file consists of a text line for each available tool describing the tool’s parameters, see Tool Table Format.

The tool database interface provides an alternative method for obtaining tool data via a separate program that manages a database of tools.

1. Interface

1.1. INI file Settings

INI file settings enable the (optional) operation of a user-provided tool database program:

DB_PROGRAM = db_program [args]

When included, db_program specifies the path to a user-provided executable program that provides tooldata. Up to 10 space-separated args may be included and passed to the db_program at startup.

INI file settings for [EMCIO]TOOL_TABLE are ignored when a db_program is specified.
The db_program may be implemented in any language currently supported in LinuxCNC (e.g., BASH scripts, Python or Tcl scripts, C/C++ programs) as long as it conforms to the interface messages received on stdin and replied on stdout. A db_program could manage data from a flat file, a relational database (SQLite for example), or other data sources.

1.2. db_program operation (v2.1)

When a db_progam is specified, operation is as follows:

  1. At startup, LinuxCNC starts the db_program and connects to its stdin and stdout.

  2. The db_program must respond by writing a single line acknowledgement consisting of a version string (e.g., "v2.1"). No tools will be available if the version is not compatible with the LinuxCNC database interface version.

  3. Upon a successful acknowledgement, LinuxCNC issues a g (get) command to request all tools. The db_program must respond with a sequence of replies to identify each available tool. The textual reply format is identical to the text line format used in conventional tool table files. A final response of "FINI" terminates the reply.

  4. The db_program then enters an event wait loop to receive commands that indicate that tool data has been changed by LinuxCNC. Tool data changes include:

    • a) spindle loading(Tn M6)/unloading(T0 M6)

    • b) tool parameter changes (G10L1Pn for example)

    • c) tool substitutions (M61Qn).

When a tool data change occurs, LinuxCNC sends a command to the db_program consisting of an identifying command letter followed by a full or abbreviated tool data line. The db_program must respond with a reply to confirm receipt. If the reply includes the text "NAK", a message is printed to stdout but execution continues. The "NAK" message signifies a lack of synchronization between the db_program and LinuxCNC — accompanying text should give an indication for the cause of the fault.

The commands issued for tool data changes are:

  • "p" put data changes caused by G10L1, G10L10, G10L11 G-codes. The tool data line will include all elements of a tool table text line.

  • "l" spindle_load (TnM6). The tool data line includes only the T and P items identifying the relevant tool number and pocket number.

  • "u" spindle_unload (T0M6). The tool data line includes only the T and P items identifying the relevant tool number and pocket number.

When a NON_RANDOM tool changer is specified using [EMCIO]RANDOM_TOOL_CHANGER=0 (the default), the spindle_load command issued for TnM6 (or M61Qn) is: l Tn P0 (pocket 0 is the spindle). The spindle_unload command issued for T0M6 is u T0 P0.
When a RANDOM tool changer is specified using [EMCIO]RANDOM_TOOL_CHANGER=1, a pair of spindle_unload/spindle_load commands are issued at each tool exchange. The pair of commands issued for TnM6 (or M61Qn) are u Tu Pm followed by l Tn P0, where u is the current tool to be sent to pocket m and n is the new tool to load in the spindle (pocket 0). By convention, a tool number of 0 is used to specify an empty tool,

1.3. Usage

Using a db_program does not change the way LinuxCNC operates but provides support for new database functionality for tool management.

For example, a db_program database application can maintain the operating hours for all tools by tracking each load/unload of a tool. A machine could then have three 6 mm endmills in pockets 111, 112, and 113 with the database application programmed to assign tool number 110 to the 6 mm endmill with the fewest operating hours. Then, when a LinuxCNC program requests tool 110, the database would specify the appropriate pocket based on tool usage history.

Tool data changes made within LinuxCNC (p,u,l commands) are pushed immediately to the db_program which is expected to synchronize its source data. By default, LinuxCNC requests for tool data (g commands) are made at startup only. A database program may update tool usage data on a continuous basis so long-lived LinuxCNC applications may benefit by refreshing the tool data provided by the db_program. The G-code command G10L0 can be used to request a tool data reload (g command) from within G-code programs or by MDI. A reload operation is also typically provided by a Graphical User Interface (GUI) so that on-demand reloads can be requested. For example, a Python GUI application can use:

#!/usr/bin/env python3
from  linuxcnc import command

Alternatively, a db_program may push its local data changes to synchronize its data with LinuxCNC by using the load_tool_table() interface command. Commands which push changes to LinuxCNC may be rejected if the interpreter is running. The interpreter state can be checked before issuing a load_tool_table() command. Example:

#! /usr/bin/env python3
import linuxcnc
s = linuxcnc.stat()
if s.interp_state == linuxcnc.INTERP_IDLE:
else: # defer loading until interp is idle

If the database application adds or removes tools after initialization, a call to tooldb_tools() must be issued with an updated user_tools list. The updated list of tools will be used on subsequent get commands or load_tool_table() requests.

Removal of a tool number should only be done if the tool number is not currently loaded in spindle.

1.3.1. Debug Environmental Variables

Exporting the environmental variable DB_SHOW enables LinuxCNC prints (to stdout) that show tool data retrieved from the db_program at startup and at subsequent reloading of tool data.

Exporting the environmental variable DB_DEBUG enables LinuxCNC prints (to stdout) for additional debugging information about interface activity.

1.4. Example program

An example db_program (implemented as a Python script) is provided with the simulation examples. The program demonsrates the required operations to:

  1. acknowledge startup version

  2. receive tool data requests: g (get command)

  3. receive tool data updates: p (put command)

  4. receive tool load updates: l (load_spindle command)

  5. receive tool unload updates: u (unload_spindle command)

1.5. Python tooldb module

The example program uses a LinuxCNC provided Python module (tooldb) that manages the low-level details for communication and version verification. This module uses callback functions specified by the db_program to respond to the g (get) command and the commands that indicate tool data changes (p, l, u).

The db_program uses the tooldb module by implementing the following Python code:

user_tools = list(...)   # list of available tool numbers

def user_get_tool(toolno):
    # function to respond to 'g' (get) commands
    # called once for each toolno in user_tools
def user_put_tool(toolno,params):
    # function to respond to 'p' (put) commands
def user_load_spindle(toolno,params):
    # function to respond to 'l' (put) commands
def user_unload_spindle(toolno,params):
    # function to respond to 'u' (put) commands

# Begin:
from tooldb import tooldb_tools     # identify known tools
from tooldb import tooldb_callbacks # identify functions
from tooldb import tooldb_loop      # main loop

Use of tooldb is not required — it is provided as a demonstration of the required interface and as a convenience for implementing Python-based applications that interface with an external database.

2. Simulation configs

Simulation configs using the AXIS gui:

  1. configs/sim/axis/db_demo/db_ran.ini (random_toolchanger)

  2. configs/sim/axis/db_demo/db_nonran.ini (nonrandom_toolchanger)

Each sim config simulates a db_program implementing a database with 10 tools numbered 10—19.

The db_program is provided by a single script ( and symbolic links to it for alternative uses: and By default, the script implements random_toolchanger functionality. Nonrandom toolchanger functions are substituted if the link name includes the text "nonran".

The sim configs demonstrate the use of the Python tooldb interface module and implement a basic flat-file database that tracks tool time usage for multiple tools having equal diameters. The database rules support selection of the tool having the lowest operating time.

The sim configs use a primary task to monitor and respond to tool updates initiated from within LinuxCNC. A periodic task updates tool time usage at reguar intervals. Separate, concurrent tasks are implemented as threads to demonstrate the code required when changes are initiated by the db_program and demonstrate methods for synchronizing LinuxCNC internal tooldata. Examples include:

  1. updates of tool parameters

  2. addition and removal of tool numbers

A mutual exclusion lock is used to protect data from inconsistencies due to race conditions between LinuxCNC tooldata updates and the database application updates.

2.1. Notes

When a db_program is used in conjunction with a random tool changer ([EMCIO]RANDOM_TOOLCHANGER), LinuxCNC maintains a file (db_spindle.tbl in the configuration directory) that consists of a single tool table line identifying the current tool in the spindle.