Lathe Chuck Table

  • anfänger
  • anfänger's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
More
12 Oct 2026 09:29 - 12 Oct 2026 09:40 #350209 by anfänger
Lathe Chuck Table was created by anfänger
While getting my linuxcnc rettrofit lathe running again after moving shop. I wanted to turn close to the spindle. But my soft limits protect me from doing this. Of course you can ignore limits, but I was thinking about a "chuck table" with some more details on it like:
diameter, max rpm, z_limit, number of jaws and weight.

My concept so far...

Files:
  • chucks.json – Stores your database of chucks, limits, and parameters.
    • current_chuck.json – Automatically created/updated to persist the currently active chuck across reboots.
      • chuck_manager.py – The Python handler script linked to your custom tab.

      Widgets:

      Widget TypeObject Name (objectName)Description
      QComboBoxchuck ComboBoxDropdown showing line numbers and chuck names (synced with the table)
      QPushButton activateChuckBtn  confirmation button to apply limits and save state.
      QTableWidget chuckTable 7-column interactive table to view, add, edit, and delete chuck profiles.
      QPushButton addChuckBtn Button to insert a new blank row into the table.
      QPushButton saveTableBtn Button to save table modifications permanently back to chucks.json.
      QPushButton deleteChuckBtn Button to remove the currently selected row.
      QLabel lblMaxRpm Displays the maximum allowed spindle RPM for the selected chuck.
      QLabel lblZLimit Displays the active Z-axis soft limit (ini.z.min_limit).
      QLabel lblDiameter Displays the chuck body diameter.
      QLabel lblJaws Displays the number of jaws.
      QLabel lblJawsDisplays the number of jaws.QLabellbl Weight Displays the chuck weight in kilograms.


      At the moment I have four chucks:

      {
         "Standard 3-Jaw Chuck (250mm)": {
            "max_rpm": 2400,
            "z_limit": -45.0,
            "diameter": 250,
            "jaws": 3,
            "weight_kg": 25.5
         },
         "centric 4-jaw Chuck (160mm)": {
            "max_rpm": 3000,
            "z_limit": -60.0,
            "diameter": 160,
            "jaws": 4,
            "weight_kg": 4.2
         },
         "Heavy 4-jaw Chuck (400mm)": {
            "max_rpm": 800,
            "z_limit": -30.0,
            "diameter": 400,
            "jaws": 4,
            "weight_kg": 40.0
         }
         "Power chuck (250mm)": {
            "max_rpm": 2400,
            "z_limit": -45.0,
            "diameter": 250,
            "jaws": 3,
            "weight_kg": 50.0
         }
      ​​​​​​   "Spindle": {
            "max_rpm": 3000,
            "z_limit": -110.0,
            "diameter": 60,
            "jaws": 0,
            "weight_kg": 0.0
         }
      }

      Next is writing and debugging the script.
Last edit: 12 Oct 2026 09:40 by anfänger.

Please Log in or Create an account to join the conversation.

  • anfänger
  • anfänger's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
More
12 Oct 2026 19:51 #350217 by anfänger
Replied by anfänger on topic Lathe Chuck Table
I Cheated and used Claude in the end.If anyone wants to use soothing like this also here is a manual and the necessary files

File Attachment:
OverviewThis UserTab lets a lathe operator pick the mounted chuck from a list and enforce that chuck's limits in HAL: a maximum spindle speed and a Z soft limit. It is built for Probe Basic Lathe (QtPyVCP) and tested on a Mesa 7i97 machine, but nothing in it is hardware-specific.
  • Chuck table: add, edit, delete and save chucks (name, max RPM, Z limit, diameter, jaws, weight). Data lives in 
    chucks.json
     in the config directory.
  • Dropdown + info line: select a chuck and see its data at a glance. The active chuck is highlighted green in the table.
  • Activation with confirmation: one button writes both limits to HAL after a Yes/No dialog. If 
    halcmd
     fails, the chuck is not marked active and an error dialog appears.
  • Plausibility check: rejects RPM <= 0, RPM above 
    [SPINDLE_0] MAX_FORWARD_VELOCITY
    , Z at or above 
    [AXIS_Z] MAX_LIMIT
    , and optionally Z below a configurable floor.
  • Persistence: the active chuck is stored in 
    current_chuck.json
     and re-applied automatically at startup, so the display and HAL never disagree after a restart.
  • Fail-safe RPM clamp: the spindle clamp is a HAL component with a conservative default, so the low limit holds even if the GUI never starts.
Requirements and file layoutYou need LinuxCNC 2.9 or newer (for the writable 
ini.<axis>.min_limit
 HAL pins) and Probe Basic Lathe with UserTab support. Check the Z pin exists with 
halcmd show pin ini.z.min_limit
.
~/linuxcnc/configs/<your-config>/
├── <your-machine>.ini
├── <your-main>.hal              # gets the RPM clamp (Step 1)
├── chucks.json                  # chuck database (created on first save)
├── current_chuck.json           # active chuck (written by the tab)
└── user_tabs/
    └── chuck_manager/
        ├── chuck_manager.py     # logic (class UserTab)
        └── chuck_manager.ui     # Qt Designer layout
The folder name, 
.py
 name and 
.ui
 name must match. The JSON files live in the config directory, not in the tab folder; the tab finds it through the 
CONFIG_DIR
 environment variable that LinuxCNC sets.Step 1: HALLinuxCNC has no writable HAL pin for the maximum spindle speed, so a 
limit1
 component is inserted into the speed command chain. The Z soft limit needs no HAL change: the tab writes the existing 
ini.z.min_limit
 pin.Find the line in your main HAL file that takes 
spindle.0.speed-out-abs
 (or 
speed-out
) to your output stage. Insert the clamp between them. Example for a chain that ends in a 
gearchange
 component:
# --- load (with your other loadrt lines) ---
loadrt limit1 names=chuck-rpm-limit

# --- thread: AFTER motion-controller, BEFORE whatever reads the speed,
#     and BEFORE hm2_xxx.write ---
addf chuck-rpm-limit servo-thread

# --- wiring ---
# before:  net spindle-vel-cmd-rpm-abs spindle.0.speed-out-abs => gearchange.0.speed-in
net spindle-vel-cmd-rpm-abs  spindle.0.speed-out-abs => chuck-rpm-limit.in
net spindle-rpm-limited      chuck-rpm-limit.out     => gearchange.0.speed-in

# --- fail-safe default until the GUI activates a chuck ---
setp chuck-rpm-limit.min 0
setp chuck-rpm-limit.max 500     # RPM of your weakest chuck
Without a gearbox, connect 
chuck-rpm-limit.out
 to whatever 
speed-out-abs
 fed before (a PWM generator, a scale component, a VFD pin). The clamp sits after the spindle override and before the gearbox, so it limits the real chuck speed and the override knob cannot push past it.The pins are named 
min
 and 
max
, without underscore. The 
limit1
 source declares them as 
min_
 / 
max_
, but 
halcompile
 strips the trailing underscore. 
setp chuck-rpm-limit.max_
 aborts LinuxCNC startup with "parameter or pin not found".After a restart, check with 
halcmd show pin chuck-rpm-limit
.Step 2: install the UserTab files
  1. Create 
    user_tabs/chuck_manager/
     in your config directory and copy 
    chuck_manager.py
     and 
    chuck_manager.ui
     into it.
  2. Point Probe Basic at the folder in your INI, if it is not there yet:
    [DISPLAY]
    USER_TABS_PATH = user_tabs/
  3. Optionally copy the example 
    chucks.json
     into the config directory. Without it the table starts empty and the file is created on the first "Save Changes".
The database is one object per chuck, keyed by its name:
{
    "3-Jaw 160": {
        "max_rpm": 3000,
        "z_limit": 5.0,
        "diameter": 160,
        "jaws": 3,
        "weight_kg": 12.0
    },
    "4-Jaw 250 Heavy": {
        "max_rpm": 1200,
        "z_limit": 25.0,
        "diameter": 250,
        "jaws": 4,
        "weight_kg": 38.0
    }
}
The values in the example are placeholders. Take max RPM from the chuck's rating plate or datasheet, and measure the Z limit on your machine. Z is in machine coordinates, so its sign depends on your machine's travel and home position.Step 3: configure and testFour constants at the top of 
chuck_manager.py
 control the behaviour:ConstantDefaultMeaning
AUTO_APPLY_ON_START
True
Re-apply the saved chuck to HAL at startup without a dialog. 
False
 only logs a warning and marks nothing active.
HAL_PIN_Z_MIN
"ini.z.min_limit"
Pin for the Z soft limit.
HAL_PIN_RPM_MAX
"chuck-rpm-limit.max"
Pin for the RPM clamp from Step 1.
Z_LIMIT_FLOOR
None
Lowest Z limit a chuck may have, in mm. 
None
 disables the check. Set it a few tenths of a mm inside the physical limit switch once you have measured it.The chuck limit can only make the machine more restrictive. LinuxCNC still enforces 
[JOINT_n] MIN_LIMIT
 and 
[AXIS_Z] MIN_LIMIT
 from the INI, so a chuck Z limit below them has no effect. Set the INI values to the real travel and let the chucks narrow it.Test before cutting:
  1. Start LinuxCNC and open the tab. The dropdown and the table must show your chucks.
  2. Activate a chuck. Then run 
    halcmd show pin ini.z.min_limit chuck-rpm-limit
     and check both values arrived.
  3. In MDI, command an 
    S
     value above the chuck's limit. 
    chuck-rpm-limit.out
     must stay at the limit while 
    .in
     shows the commanded value.
  4. Jog Z slowly toward the chuck. Motion must stop at the chuck's Z limit.
  5. Restart LinuxCNC. The same chuck must be green again and step 2 must show the same values.
How it worksEditing and activating are separate: changing the table never touches HAL, only "Activate Chuck" does.
  • Edit: type into the table, use "Add Chuck" / "Remove Chuck", then "Save Changes". Save validates all numbers and rewrites 
    chucks.json
    . A row with invalid data aborts the save with a message.
  • Select: pick a chuck in the dropdown or click its row. The info line shows max RPM, Z limit, diameter, jaws and weight. Nothing is applied yet.
  • Activate: "Activate Chuck" runs this sequence:
    1. Plausibility check against the INI and 
      Z_LIMIT_FLOOR
      . On failure: error dialog, nothing applied.
    2. Confirmation dialog showing the two limits.
    3. halcmd setp
       for the Z pin, then the RPM pin. Each return code is checked.
    4. Only if both succeeded: green row and 
      current_chuck.json
       written.
  • Startup: the tab loads 
    chucks.json
    , selects the saved chuck and, with 
    AUTO_APPLY_ON_START
    , re-runs steps 1, 3 and 4 without the dialog.
The dropdown items carry the chuck name as item data. Matching is exact, so "Collet" never selects "Collet ER32".Safety notes and limitationsThis is a software convenience layer, not a safety function. It reduces operator error; it does not replace hardware protection.
  • It clamps the command, not the spindle. A drive fault, a wrong analog scale or a runaway VFD can still overspeed the chuck. Real overspeed protection needs independent monitoring of the encoder speed, or a drive-side speed limit.
  • The clamp is silent. 
    S2000
     with a 1500 RPM chuck runs at 1500 RPM without a warning. Surface speed and feed per rev change accordingly.
  • The operator must select the right chuck. The system cannot detect which chuck is mounted.
  • The fail-safe default only helps if it is low. Set 
    chuck-rpm-limit.max
     in the HAL file to your weakest chuck.
  • Limits apply until the next activation or restart. Changing a chuck's row and saving does not re-apply it; activate again.
  • Keep hardware limit switches and E-stop in the drive enable chain. If LinuxCNC or the GUI hangs, only hardware stops the machine.
Use at your own risk, and test every chuck with a low commanded speed first.Pitfalls we hitThese cost the most time during development and apply to any QtPyVCP tab.SymptomCauseFixDropdown stays empty although the table loadsPyQt gives 
QComboBox
 a 
__len__()
, so an empty combo box is falsy. 
if not self.combo: return
 returns before the first item is added.Test widgets with 
is None
 / 
is not None
, never by truthiness. 
QLayout
behaves the same.LinuxCNC aborts: "parameter or pin 'chuck-rpm-limit.min_' not found"
halcompile
 strips a trailing underscore from pin names.Use 
.min
 / 
.max
.Activation seems to work but the spindle is not limited
motion.spindle-max-speed
 does not exist; 
os.system()
ignored the error.Clamp in HAL (Step 1) and check the 
halcmd
 return code.A button does nothingIts objectName in the 
.ui
 (e.g. 
saveTableBtn_2
 after copy/paste) differs from the name in the code.Keep the names in the table below.
halcmd setp
 on a LED pin failsQtPyVCP turns 
_
 in a widget name into 
-
 in the pin name: widget 
LEDIN_00
 becomes 
qtpyvcp.LEDIN-00.on
.Look up pin names with 
halcmd show pin qtpyvcp
.Object names the code expects in the 
.ui
:WidgetobjectNameQComboBox
chuckComboBox
QPushButton
activateChuckBtn
, 
saveTableBtn
, 
addChuckBtn
, 
deleteChuckBtn
QTableWidget
chuckTable
QLabel
lblMaxRpm
, 
lblZLimit
, 
lblDiameter
, 
lblJaws
, 
lblWeight
If 
chuckComboBox
 is missing from the 
.ui
, the code creates one and inserts it into the layout named 
horizontalLayout
.
Attachments:

Please Log in or Create an account to join the conversation.

Moderators: KCJ, Lcvette
Time to create page: 0.511 seconds
Powered by Kunena Forum