I'm trying to understand how my knurling tool works. I suspect that, although it's described as a "cut knurling" device, only one of the two wheels actually cuts the grooves, while the other one actually forms its groove. If so, the manufacturer seems to have done a good job of concealing it. I'd like to be able to turn the spindle by hand (rather than under power) and have the tool geared to it - that way I'd be able to have a really good, close look at what's happening.
Although it's possible to link the spindle angle to the leadscrew (Z axis) position in Linuxcnc, the G33 (feed per rev) and G33.1 (rigid tapping) g codes are limited in flexibility. If you want to tie the spindle and z axis together so that you can rotate the spindle by hand and expect the tool to remain electronically locked to it, you need to hack about with the (ie edit) HAL connections. That's not something I'd be comfortable doing just for short term experimental purposes if it risked corrupting my established HAL file settings.
Luckily it seems to be possible to make temporary changes that are wiped when you restart Linuxcnc. Here's how it's done, c/o Claude and an hour or so of my time. This is a script that is run in a terminal window. Any changes that are made to the system are volatile ie will be lost when you close and restart Linuxcnc.
To engage ELS mode, run els_engage.sh:
# Engage ELS (electronic-lead-screw) hand-knurling mode on Z.
#
# Geared connection: pid.z.command <= els-sum.out <= spindle-revs * PITCH + offset
# The offset is computed fresh every run from the CURRENT z-pos-fb / spindle.0.revs,
# so Z never jumps when the handover happens (assuming the check below passes).
#
# Usage: ./els_engage.sh <pitch_mm_per_rev>
# e.g. ./els_engage.sh 0.25
#
# A positive pitch moves Z in the direction confirmed correct on 2026-09-08
# (tool travels the right way for a normal turning-toward-headstock knurl pass
# when the spindle is turned by hand in the operator's normal forward direction).
# Negative flips to the other direction if ever needed. Internally this is
# achieved by negating the value before it drives els-sum's gain -- spindle-revs'
# raw sign happened to be backwards relative to what "positive pitch" should mean.
#
# Requires LinuxCNC already running (this attaches to its live HAL instance).
# Does NOT touch FERROR/MIN_FERROR and will not connect pid.z.command if the
# verification step doesn't match current position within tolerance.
set -euo pipefail
PITCH_REQUESTED="${1:?Usage: $0 <pitch_mm_per_rev>}"
PITCH=$(awk -v p="$PITCH_REQUESTED" 'BEGIN{printf "%.6f", -p}')
TOLERANCE_MM=0.01
echo "=== ELS engage: requested pitch=${PITCH_REQUESTED} mm/rev (internal gain=${PITCH}) ==="
# --- load the gearing component (idempotent: skip if already present) ---
if ! halcmd getp els-sum.out >/dev/null 2>&1; then
echo "Loading els-sum (sum2 component)..."
halcmd loadrt sum2 names=els-sum
halcmd addf els-sum servo-thread
else
echo "els-sum already loaded, reusing it."
fi
# defensive: drop any stale links from a previous partial run on els-sum's own
# pins only -- pid.z.command is deliberately left alone until after verification
# passes below, so any failure in this script never leaves it disconnected.
halcmd unlinkp els-sum.in0 2>/dev/null || true
halcmd unlinkp els-sum.out 2>/dev/null || true
# --- fresh live reads ---
ZPOS0=$(halcmd gets z-pos-fb)
REVS0=$(halcmd getp spindle.0.revs)
# --- compute latch offset: out = revs*pitch + offset must equal ZPOS0 at REVS0 ---
OFFSET=$(awk -v z="$ZPOS0" -v r="$REVS0" -v p="$PITCH" 'BEGIN{printf "%.6f", z - (r*p)}')
echo "ZPOS0=${ZPOS0} REVS0=${REVS0} PITCH=${PITCH} OFFSET=${OFFSET}"
halcmd setp els-sum.gain0 "$PITCH"
halcmd setp els-sum.offset "$OFFSET"
halcmd net spindle-revs els-sum.in0
# --- verify BEFORE touching pid.z.command ---
CHECK=$(halcmd getp els-sum.out)
DIFF=$(awk -v a="$CHECK" -v b="$ZPOS0" 'BEGIN{d=a-b; if(d<0)d=-d; printf "%.6f", d}')
echo "Verification: els-sum.out=${CHECK} z-pos-fb=${ZPOS0} diff=${DIFF}mm"
if awk -v d="$DIFF" -v t="$TOLERANCE_MM" 'BEGIN{exit !(d>t)}'; then
echo "ABORT: els-sum.out differs from current z-pos-fb by ${DIFF}mm (tolerance ${TOLERANCE_MM}mm)."
echo "pid.z.command was NOT touched. Investigate before retrying."
exit 1
fi
echo "Verification passed. Switching pid.z.command over..."
halcmd unlinkp pid.z.command 2>/dev/null || true
halcmd net manual-knurl-cmd els-sum.out pid.z.command
OUT_PID=$(halcmd getp pid.z.output)
FERR=$(halcmd getp joint.1.f-error)
echo "Done. pid.z.command now driven by spindle at ${PITCH_REQUESTED}mm/rev."
echo "pid.z.output=${OUT_PID} joint.1.f-error=${FERR}"
echo ""
echo "Now clear to turn the spindle."
echo "Watch pid.z.output / joint.1.f-error / z-pos-fb in HalShow's WATCH tab."
#!/bin/bash
# Revert Z from ELS hand-knurling mode back to normal trajectory-planner control.
#
# Usage: ./els_revert.sh
#
# After this runs, pid.z.command is back on the real z-pos-cmd signal, but
# motion's internal position reference is still stale relative to wherever
# Z physically ended up during the ELS session -- you should rehome Z before
# any G-code/MDI motion. This script does not rehome for you.
set -uo pipefail
echo "=== ELS revert ==="
halcmd unlinkp pid.z.command 2>/dev/null || true
halcmd net z-pos-cmd pid.z.command
echo "pid.z.command reconnected to z-pos-cmd (trajectory planner)."
# tear down the gearing component
halcmd unlinkp els-sum.in0 2>/dev/null || true
halcmd unlinkp els-sum.out 2>/dev/null || true
halcmd delf els-sum servo-thread 2>/dev/null || true
if halcmd unloadrt sum2 2>/dev/null; then
echo "els-sum unloaded."
else
echo "NOTE: could not unload els-sum live (harmless -- it's disconnected and inert)."
echo "It will disappear on the next LinuxCNC restart regardless."
fi
echo ""
echo "IMPORTANT: restart Linuxcnc or rehome Z now, before any programmed (G-code/MDI) motion."
- The overall pattern (sum2 for gearing, offset computed fresh from live position/revs at the moment of engagement, verify-before-handover, never touch the fault limit) is architecture-agnostic. If the injection point is changed to stepgen.N.position-cmd, the same script structure should work.
- <=/=> arrows get mangled by bash redirection on a raw command line, so scripts must omit them; show pin silently "succeeds" on a nonexistent pin while getp/setp correctly error, which makes show pin useless for existence checks. Anyone scripting HAL live is going to run into at least one of those.
- An absolute, non-zeroed spindle-revs counter driving a position command produces a discontinuity-on-connect hazard, independent of what's downstream of that command.
No comments:
Post a Comment