Spindle Orient and Rigid Tapping without an Encoder (M19, G33.1)
- mattroberts
- Offline
- New Member
- Posts: 14
- Thank you received: 8
Firstly a little bit of background: I am using a servo as my spindle motor, and that servo is connected to a hardware stepgen. With a bit of effort, I'm using the stepgen position-fb to get both spindle orient (M19) and rigid tapping (G33.1, ...) to work.
The main trick is a custom hal component that I wrote. I've called it "stepgenencoder", but that is unlikely to be the best name.
Here is source code for it:
component stepgenencoder "use a stepgen position-fb output as an encoder";
pin in float position-in;
pin io bit index-enable;
pin in bit reset;
pin out float position-out;
variable float offset = 0;
variable float offset_frac = 0;
variable float whole_revs = 0;
function _ fp;
license "GPL";
;;
#include <rtapi_math.h>
FUNCTION(_) {
float whole_revs_old;
whole_revs_old = whole_revs;
whole_revs = floor(position_in - offset);
if (index_enable && whole_revs != whole_revs_old) {
offset = floor(position_in - offset_frac) + offset_frac;
whole_revs = 0;
index_enable = false;
}
if (reset) {
offset = position_in;
offset_frac = floor(position_in);
whole_revs = 0;
}
position_out = position_in - offset;
}
The idea is that you connect three signals like this to get rigid tapping to work:
- position-in <= stepgen.?.position-fb
- index-enable <=> spindle.0.index-enable (part of the motion hal component)
- position-out => spindle.0.revs (also part of the motion hal component)
And also connect position-out to a pid control loop for spindle orient to work (see later for a fully working example):
- position-out => pid.s-pos.feedback
The reset input resets position-out to be zero and also 'moves' the index pulse that a real encoder would have to the current angle.
Anyway, it feels to me that something like stepgenencoder could be added to linuxcnc proper and possibly help a few people out.
In the meantime, what's in this post works (in v2.8.2) and should be a useful reference for anyone in a similar position.
For completeness, here is the relevant parts of the hal file I use with my machine.
in addition to rigid tapping and spindle orient this also controls a spindle-brake and creates a spindle-vel-rpm net.
spindle-brake is only applied when then spindle is almost stopped.
spindle-vel-rpm net is useful for a virtual control panel display showing the spindle-speed
# snip
loadrt pid names=pid.s-pos
loadrt orient
loadrt stepgenencoder
loadrt mux2 names=mux2.s
loadrt near names=near.s-vel,near.s-brake
loadrt and2 names=and2.s-brake
loadrt scale names=scale.s-vel
addf hm2_7i76e.0.read servo-thread
# snip
addf pid.s-pos.do-pid-calcs servo-thread
addf orient.0 servo-thread
addf stepgenencoder.0 servo-thread
addf near.s-vel servo-thread
addf near.s-brake servo-thread
addf and2.s-brake servo-thread
addf scale.s-vel servo-thread
addf mux2.s servo-thread
addf hm2_7i76e.0.write servo-thread
# snip
# --- spindle velocity stuff ---
setp scale.s-vel.gain 60 # rpm = 60 * rps
setp near.s-vel.difference 1 # spindle-at-speed is within 1rps (i.e. within 60rpm)
setp near.s-brake.difference 0.1 # can apply brake when spindle rps < 0.1 (i.e. rpm < 6)
setp near.s-brake.in2 0 # brake should be applied near 0rps / 0rpm
net spindle-vel hm2_7i76e.0.stepgen.04.velocity-fb => spindle.0.speed-in near.s-vel.in1 near.s-brake.in1 scale.s-vel.in
net spindle-vel-rpm scale.s-vel.out
net spindle-vel-stepgen mux2.s.out => hm2_7i76e.0.stepgen.04.velocity-cmd
net spindle-vel-cmd spindle.0.speed-out-rps => near.s-vel.in2 mux2.s.in0
net spindle-vel-cmd-rpm spindle.0.speed-out
net spindle-at-speed near.s-vel.out => spindle.0.at-speed
net spindle-can-brake near.s-brake.out => and2.s-brake.in0
net spindle-want-brake spindle.0.brake => and2.s-brake.in1
net spindle-brake and2.s-brake.out
# --- spindle position stuff ---
net spindle-index-enable spindle.0.index-enable <=> stepgenencoder.0.index-enable
net spindle-pos-raw hm2_7i76e.0.stepgen.04.position-fb => stepgenencoder.0.position-in
net spindle-pos stepgenencoder.0.position-out => spindle.0.revs pid.s-pos.feedback orient.0.position
net spindle-pos-cmd orient.0.command => pid.s-pos.command
net spindle-angle spindle.0.orient-angle => orient.0.angle
net spindle-pos-pid pid.s-pos.output => mux2.s.in1
net spindle-in-pos orient.0.is-oriented => spindle.0.is-oriented
# --- switch between modes ---
net spindle-velocity-mode spindle.0.on
net spindle-orient-mode spindle.0.orient => orient.0.enable pid.s-pos.enable mux2.s.sel
net spindle-orient-dir spindle.0.orient-mode => orient.0.mode
# -- stepgen setup ---
setp hm2_7i76e.0.stepgen.04.dirsetup [SPINDLE]DIRSETUP
setp hm2_7i76e.0.stepgen.04.dirhold [SPINDLE]DIRHOLD
setp hm2_7i76e.0.stepgen.04.steplen [SPINDLE]STEPLEN
setp hm2_7i76e.0.stepgen.04.stepspace [SPINDLE]STEPSPACE
setp hm2_7i76e.0.stepgen.04.position-scale [SPINDLE]STEP_SCALE
setp hm2_7i76e.0.stepgen.04.step_type 2 # quadrature output
setp hm2_7i76e.0.stepgen.04.control-type 1 # velocity mode
setp hm2_7i76e.0.stepgen.04.maxaccel [SPINDLE]MAX_ACCELERATION
setp hm2_7i76e.0.stepgen.04.maxvel [SPINDLE]MAX_VELOCITY
# keep the stepgen always on so that the spindle always respects MAX_ACCELERATION and doesn't try to stop instantly
# (this probably means that the physical drive enable should be attached to the estop signal for safety)
setp hm2_7i76e.0.stepgen.04.enable true
# --- setup the position PID ---
setp pid.s-pos.Pgain [SPINDLE]P_POS
setp pid.s-pos.Igain [SPINDLE]I_POS
setp pid.s-pos.Dgain [SPINDLE]D_POS
setp pid.s-pos.bias [SPINDLE]BIAS_POS
setp pid.s-pos.FF0 [SPINDLE]FF0_POS
setp pid.s-pos.FF1 [SPINDLE]FF1_POS
setp pid.s-pos.FF2 [SPINDLE]FF2_POS
setp pid.s-pos.deadband [SPINDLE]DEADBAND_POS
setp pid.s-pos.maxoutput [SPINDLE]MAX_OUTPUT_POS
setp pid.s-pos.error-previous-target true
# This setting is to limit bogus stepgen
# velocity corrections caused by position
# feedback sample time jitter.
setp pid.s-pos.maxerror 0.012700
Please Log in or Create an account to join the conversation.
- mattroberts
- Offline
- New Member
- Posts: 14
- Thank you received: 8
linuxcnc.org/docs/html/man/man1/halcompile.1.html
linuxcnc.org/docs/html/hal/comp.html
Please Log in or Create an account to join the conversation.
- drummond
- Offline
- Junior Member
- Posts: 38
- Thank you received: 4
If I am correct would you take the time to post your complete HAL and INI files? Examples like this are difficult to find, and this is just the information that I'm looking for. Thanks
I'm also enjoying your postings so far, please keep them coming
Please Log in or Create an account to join the conversation.
- mattroberts
- Offline
- New Member
- Posts: 14
- Thank you received: 8
The standard disclaimer of 'here be dragons' applies.
In particular: I haven't wired a physical estop circuit yet. So if the spindle stalls: it will trash the part and probably the tool as well. That said, I've been using the machine for the last year with only two broken endmills - so I guess the trick is not be bone-headed!
(I only swapped the spindle from the original DC motor to a servo a couple of weeks ago, so that bit is tested much less than the rest of the config).
I gather you are running your spindle servo without feedback from an encoder?
Yes-ish. I have wired the encoder outputs of the servo drive to my 7i76e, but halscope shows very noisy signals. The longer term plan is attach my real oscilloscope to the 7i76e input pins and see what's going on. But in the meantime the stepgen position is good enough (and potentially useful to others - hence the original post).
A youtuber has had problems with noise on the encoder output from a servo, so maybe this is common problem (he talks about it at about 9:40):
For what it is worth: my spindle servo is a 750W Pro-Net ESTUN one, so different to one in that youtube video. 750W sounds small, but it is around 2x-3x the power the original DC motor on the machine (a, now edited, Boxford VMC 280) so it is probably good enough.
Please Log in or Create an account to join the conversation.
- mattroberts
- Offline
- New Member
- Posts: 14
- Thank you received: 8
The hardware encoder is wired to the these three nets: spindle-encoder-pos, spindle-encoder-vel, spindle-encoder-vel-rpm
and they are not used (except to display spindle-encoder-pos in the virtual control panel).
The commented out section starting "# ---digital potentionmeter output signals/setup---" was used to drive the old spindle, which used a traditional 0-10v speed signal.
I have two hardware manual-pulse-generators that I use for jogging. But the movement per pulse (and which axis is attached to the jog wheel) is controlled by virtual control for time being.
The A axis stuff has only been tested with manually written gcode - so there may well be something silly about the A axis config that I haven't found yet.
Correction:
The machine is a Boxford VMC 260. Not that it matters, because there is almost no information about it online.
Please Log in or Create an account to join the conversation.
- drummond
- Offline
- Junior Member
- Posts: 38
- Thank you received: 4
What you have done is admirable because a work in process is just that. I have seen many references to using a velocity mode servo or stepper and switching that to a position mode to perform other operations, lots of mentions but no examples (maybe my google-fu just sucks <lol>)
6 months from now perhaps you have your encoder noise problems sorted out, and you just don't think it's worth documenting what you did before that because "no-one will be interested".
I'm glad you decided to do it the way you did.
Please Log in or Create an account to join the conversation.
- mattroberts
- Offline
- New Member
- Posts: 14
- Thank you received: 8
- All five stepgens are in velocity mode always. There is one stepgen each of the X, Y, Z, and A axis. The fifth stepgen drives the spindle.
- The stepgens for the various axes have a pid loop each to take position targets and tell the stepgens what to do (which is how PnCconf would set them up - so this shouldn't be controversial).
- The stepgen for the spindle has a pid loop for orientation (or position if you like), once again the output of the pid loop is a velocity. Which is optionally used depending on the what the motion controller says (spindle.0.orient).
- Otherwise the stepgen velocity target is taken straight from the motion component (spindle.0.speed-out-rps).
- The switching of sindle velocity (pid output or spindle.0.speed-out-rps) is done by a mux2.
- The spindle stepgen has acceleration and velocity limits so that those are enforced even when switching modes. (with a low enough acceleration, this could certainly work with a lathe spindle).
Please Log in or Create an account to join the conversation.
- mattroberts
- Offline
- New Member
- Posts: 14
- Thank you received: 8
I have seen many references to using a velocity mode servo or stepper and switching that to a position mode to perform other operations, lots of mentions but no examples.
The thing that I found that helped me was this example config from linuxcnc itself (in particular the spindle.hal file):
github.com/LinuxCNC/linuxcnc/tree/master...smach/VMC_toolchange
github.com/LinuxCNC/linuxcnc/blob/master...olchange/spindle.hal
For what it is worth, I had to look in my browser history to find this - a fresh internet search came up blank. I feel your pain.
Please Log in or Create an account to join the conversation.
- drummond
- Offline
- Junior Member
- Posts: 38
- Thank you received: 4
Wait that's a sim development thing, let me go check........
Yes it's in the sample configs under (surprise, surprise) sim, axis, vismach, vmc, toolchange. Pick that and it will write the files into your linux config folder.
It's funny how you can find things when you know what to look for, so I've now got the spindle HAL to look at along with a couple of ini files and gingerbread.
Please Log in or Create an account to join the conversation.