Spindle Step/Dir servo ramp down before stop on M stop command.

07 Apr 2021 16:38 #205266 by NoJo
I posted on the 'Show Your Stuff' pages re my attempt at a scratch built CNC lathe, and the difficulties I have in getting to grips with HAL...To the point where I decided to call it quits and walk away from the project...Andy came back and said 'Don't give up'...So I am giving it another try, but in this forum Topic rather - I think the Show Your Stuff pages is not really where this work should be taking place..!

Anyway, let me try again, but this time I will stick to ONE problem at a time.

If you would be so kind as to want to try help me, please take the time to read this LONG post through - you may understand why it is so long and why I am so frustrated! Else, just walk away...

The lathe is 'working' - everything moves, Homes, Jog wheels and jog buttons work, etc. Of the various functions still to implement, the current one is a Ramp down of the Spindle speed to zero RPM before removing the spindle drive enable.
The drive is a STEP/DIR drive servo. It is an internally closed loop servo, ie , it has an internal encoder that it's controller uses to control the (Brushless DC) motor. From the outside world you treat it as you would a plain stepper drive. The difference is that the motor will do its best to not lose steps since it closes the loop with its encoder.

The lathe spindle has a 1024 line ( 4096 edge) ABZ encoder fitted.

I have torn my hair out trying to understand HAL and what people have been telling me I need to do - I have so far understood nothing of it and have spent too many days reading LinuxCNC docs that stubbornly remain relatively meaningless.
I have also searched for many,many hours through the many heading's posting on this specific subject - there are a few, but mostly not applicable - there is one from 'The Feral Engineer' - he asked how to do seemingly exactly what I am trying to do, his next post was 'never mind found out how to do it' and was asked by others to post the solution as others (ME!!) might benefit from it - he never did...

I know I need to implement a mechanism using the limit2 component, and as PCW said -

In this type of situation you would typically limit the spindle speed rate of change
with VFD programming but since you are using a servo you would need to limit
the rate of change in LimuxCNC's commanded spindle speed. This can be done with
the "limit2" component. By passing LinuxCNCs commanded spindle speed through the
limit2 component, you can now specify the maximum rate of change in spindle speed
(in RPM/Second)

I understand what that 'means' but have NO idea how to do it. I then read up all I could, dug through the forum postings, read MANY of them...
I found this: ( it has all the right 'names' that everyone keeps speaking of, so I think this is the sort of thing I need to implement)

Spindle Soft Start
If you need to ramp your spindle speed command and your control does not have that feature it can be done in HAL. Basically you need to hijack the output of spindle.N.speed-out and run it through a limit2 component with the scale set so it will ramp the rpm from spindle.N.speed-out to your device that receives the rpm. The second part is to let LinuxCNC know when the spindle is at speed so motion can begin.

A "limit2" is a HAL component (floating point) that accepts an input value and provides an output that has been limited to a max/min range, and also limited to not exceed a specified rate of change.

A "near" is a HAL component (floating point) with a binary output that says whether two inputs are approximately equal.

# load real time a limit2 and a near with names so it is easier to follow
loadrt limit2 names=spindle-ramp
loadrt near names=spindle-at-speed

# add the functions to a thread
addf spindle-ramp servo-thread
addf spindle-at-speed servo-thread

# set the parameter for max rate-of-change
# (max spindle accel/decel in units per second)
setp spindle-ramp.maxv 60

# hijack the spindle speed out and send it to spindle ramp in
net spindle-cmd <= spindle.0.speed-out => spindle-ramp.in

# the output of spindle ramp is sent to the scale in
net spindle-ramped <= spindle-ramp.out => scale.0.in

# to know when to start the motion we send the near component
# (named spindle-at-speed) to the spindle commanded speed from
# the signal spindle-cmd and the actual spindle speed
# provided your spindle can accelerate at the maxv setting.
net spindle-cmd => spindle-at-speed.in1
net spindle-ramped => spindle-at-speed.in2

# the output from spindle-at-speed is sent to spindle.0.at-speed
# and when this is true motion will start
net spindle-ready <= spindle-at-speed.out => spindle.0.at-speed

However, I have no idea where to even start doing this, I don't understand the names and structure yet, so even though this example makes sense to an extent, I have no idea how to transfer this to MY pncconf generated HAL file! The HAL file names Pncconf created are not the same as in the example, so I have no idea which parameters/names are in fact the same item, etc. Utterly confused.

My HAL file uses the near component to verify spindle speed is as required before axis moves, but I have not tested that because the only way to do that is with a G_code file and any spindle stop in that file ends up with a big bang as the spindle slams to a halt..Which is why I am here..

So, to the crux of the matter:
Will someone be so kind as to take the gist of that example ( or if it is not appropriate to create appropriate HAL definitions) and include it INLINE in the correct places in my attached HAL file PLEASE. If you could include an English description of what that line or entry actually does, that would be really great...As though you are adding comments to properly document a C source file...

If you can do that, using the naming structure as in my HAL file, I can then take that file and try my best to understand how these elements interlink, and what they link to, what pins go where, etc - If the HAL file works and my lathe ramps to a halt, that would be nice too, but that is not the main purpose - I need to begin to understand how the HAL file works and reads. When the names mean little, and cannot be correlated, it is very difficult to sperate in ones mind HAL's pins and the electronic modules pins, and which direction each goes!

It does NOT help me for someone to give me a stand-alone example, hanging in the air with no hooks, with their own name choices, that differ from from my file's naming and that I cannot tie to what my file has in it - that has remained Greek to me.

I thank ALL willing to drag me along..

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

07 Apr 2021 17:37 #205271 by PCW

File Attachment:

File Name: CNC_Lathe.ini
File Size:4 KB

File Attachment:

File Name: CNC_Lathe_...4-07.hal
File Size:15 KB

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

07 Apr 2021 23:02 #205288 by andypugh
PCW has created what is probably a fully working config, but if I might muddy the waters a bit...

I actually think that in your case there is an easy way to do this.

Because you are using step/dir to control the spindle you must be using a step generator. And the step generators all have a built in rate-limit.

So, if you add to the HAL file the following
setp [HMOT](CARD0).stepgen.02.maxaccel 50
the spindle speed will ramp up and down slowly.

Handling the servo drive enable remains a little more complicated. The absolute simplest thing to do would be to leave the drive permanently enabled, but then you would probably not be able to turn the spindle by hand.
I think you said that turning off the drive-enable imediately stopped the spindle?
To try a permanently enabled spindle drive, (I don't think that PCW addressed the drive enable point) replace
net spindle-enable  =>     [HMOT](CARD0).7i76.0.0.output-15
setp   [HMOT](CARD0).7i76.0.0.output-15     1

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

08 Apr 2021 00:04 - 08 Apr 2021 00:04 #205299 by PCW
I had considered using the stepgen limits, but I thought that it might complicate
the C Axis setup since the spindle and C axis share the same stepgen and the
velocity and accel stepgen limits are parameters.
Last edit: 08 Apr 2021 00:04 by PCW.

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

08 Apr 2021 08:39 #205310 by andypugh
I think we need Joe to report back on whether your version of the config works.
(I suspect that the drive enable might need a little more work)

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

08 Apr 2021 09:11 - 08 Apr 2021 10:04 #205311 by NoJo
Thank You Andy and PCW.

The info you both provided has been a big help.
PCW, I understand so much better how things tie together! Thank you for that. I am by no means 'much' smarter yet, but it is making more and more sense.

Unfortunately, neither options work yet but I am working hard at trying to understand why, etc.
PCW and Andy, in both your solutions the spindle still bangs to an instant halt.

I have been testing this using MDI commands -
M03 S1000 to start spindle
I have an RPM Panel display which shows the Spindle RPM and an LED that shows Spindle-At-Speed. The LED is green when at speed, else red, so seems to work.
Then If I use a Stop command - either M02 or M30, the spindle halts immediately.
So I thought maybe its a problem using MDI command. I then loaded a G code file, generated by my Rhino-7 CAD/CAm software - just a simple file which starts the spindle with M03 S1000 and then 'machines' a short rebate on the end of a 20mm OD bar. I home the machine first, touch-off the tool, and run the file. The file ends with M30.
I made the spindle maxaccel ( see note below..) very slow - a value of 5 in the ini file, so that the spindle spins up very slowly so I can see what happens.
The axes remain motionless for the 3-5secs that the spindle takes to get to speed (LED is red during this time). As soon as speed is achieved, led goes green and axes start moving on the cut path.
When the file is done, M30 bangs the spindle to a halt still.

I then hacked a little to see that the ramp DOWN also works
- edit the G_code file to include at the end: ( note Spindle speed setting was S1000)
Nxxx ( last XZ motion completed here, next cmd would have been M30 -
Nxx1 S500
Nxx2 G0 X0 Z0 - this motion command paused till the preceding S500 speed was achieved
Nxx3 S300
Nxx4 G0 X10 Z10 - this motion command paused till the preceding S300 speed was achieved
Nxx5 S100
Nxx6 M30 - This just banged to a halt - did not wait till spindle speed S100 was achieved..

So the 'near' function seems to work, since motion pauses till speed is in range ( My compare range is set to 100rpm), but any stop command does not execute the ramp down process.

Andy, you indicated to add -
setp  [HMOT](CARD0).stepgen.02.maxaccel   50
to the file -

This is already in the file :
setp   [HMOT](CARD0).stepgen.02.maxaccel     [SPINDLE_0]MAX_ACCELERATION
with the value for MAX_ACCELERATION in the ini file - I just changed that from 50 to 5 to slow it down drastically to be observable.

I added the permanent spindle enable -
setp   [HMOT](CARD0).7i76.0.0.output-15   1

That works - the spindle remains enabled ( it is in fact how I want it finally - I have a manual handwheel to loosen and tighten the 5C collet, and the spindle servo is supposed to hold the spindle fixed against my hand tightening/loosening force - it does too!)
How that will work with the C_Axis mode remains to be battled with..

At the end, the spindle still does not ramp down and I am digging, but not obvious!


EDIT - Andy, you mentioned regarding the way the spindle servo stops when removing the enable :
This appears to be a peculiarity of the spindle - To evaluate this I placed a NC switch in the enable wire to the servo and used used a MDI command - M03 S500 - to set spindle running.
While running I then opened the switch, disabling the servo.
The spindle came to a halt very fast - doing it from 2000rpm resulted in a massive bang...but once at standstill, I could turn the servo by hand with little effort. I believe this rapid halt is simply the magnetic breaking due to the back-emf of the fast spinning motor ( it is a Neodymium magnet rotor). So removing the enable in spin does not do the job..it still stops very, very quickly.
Last edit: 08 Apr 2021 10:04 by NoJo. Reason: Added text re- servo enable/disable effect while spinning

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

08 Apr 2021 12:35 - 08 Apr 2021 12:36 #205319 by andypugh

I added the permanent spindle enable -
setp   [HMOT](CARD0).7i76.0.0.output-15   1
That works - the spindle remains enabled ( it is in fact how I want it finally - I have a manual handwheel to loosen and tighten the 5C collet, and the spindle servo is supposed to hold the spindle fixed against my hand tightening/loosening force - it does too!)
How that will work with the C_Axis mode remains to be battled with..

Actually, that's pretty good news. It will make the C axis easier too.
I would suggest
net machine-is-on   [HMOT](CARD0).7i76.0.0.output-15
. That will enable the drive and lock the spindle when the machine is on (F2 button on many GUIs) . And you can press F2 if you do need to move a spindle or an axis by hand.

At the end, the spindle still does not ramp down and I am digging, but not obvious!

I think this is probably the stepgen enable going false imediately.

You have
net spindle-enable          =>  [HMOT](CARD0).stepgen.02.enable
which would normally be right, but in this case I would suggest trying
net machine-is-on          =>  [HMOT](CARD0).stepgen.02.enable

There is still the issue that e-stop will set machine-is-on to false, and stop the spindle dead. But then that might be what you want.
Last edit: 08 Apr 2021 12:36 by andypugh.
The following user(s) said Thank You: timo

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

08 Apr 2021 14:25 #205326 by NoJo
THAT is a resounding Success!
Thank you Andy. Works perfectly. E-stop does stop all dead, but that is what I would want - Sort of what the 'E' is in E-stop!

This works very well indeed.

I fear I am still in need of much more assistance on this machine!
Still to get going is :

  • C_Axis with proper orient control.
  • Be able to jog the C_Axis with a jog wheel.
  • ATC - much later as the ATC still has to be designed, but for that I would like to have some details of how it will be driven by 'HAL' - read many posts on ATC's, esp EMCO machines, but still know too little.
  • Basic live tool - a single mill spindle fixed in radial or axial plane - also much later as the spindle is in progress.

  • To prioritise I think the C_Axis and its jog is first.
    I very much need guidance on the C_Axis - It is a lot more complex and the few posts I have read that seem very much to be what I wish to achieve are very detailed and created by chaps who really know this stuff well!
    Where do I start?

    It is really nice to watch this lathe do its thing now. The servos are dead quiet, the spindle motor likewise, a 5C collet system so not even any wind noise from the chuck jaws - just sits there and quietly gets on - and then comes to a halt gently!

    Thanks Andy

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

    08 Apr 2021 20:47 - 08 Apr 2021 20:48 #205360 by andypugh
    Late reply as I have been investigating an idea.

    I liked the idea of configuring the C-axis as a locking-indexer then using the "joint.2.unlock" pin to control whether the spindle was under velocity control or C-axis control.

    But it seems that you can't jog an indexer, and can only do G0 moves.

    Both these restrictions seem arbitrary, I might look in to removing them.

    But, back to your machine:

    It's easy enough to set up a PID controller to add a a second velocity command to the spindle stepgen command for positioning.

    What complicates this is that you might have 1,000,000 full revolutions already on the spindle when you engage the C axis, and the PID would want to unwind (very nearly) all of them to go to +90 degrees, for example.

    Does your spindle encoder work? (It is in the HAL file, I see. Does the HAL pin spindle.0.revs increase by 1 for every spindle rotation?

    (You can test this with the HAL meter, under the "Machine" menu in the Axis GUI.)

    Here is a possible solution.

    1) Define a user M-code to enable C-axis control.
    2) Set up a 4th PID to control the C axis
    3) Add the output of that PID to the spindle velocity command.
    4) When enabling the C-axis PID, also set the "index-enable" for the spindle encoder. This means that there will be a largely uncontrolled movement of up to 1 turn when the C-axis is engaged, but then it will be referenced to the encoder index.

    First you need to make the lathe into a 3-axis machine.

    I suggest making a copy of the entire current working config (just copy the ~/linuxcnc/configs/CNC_lathe folder and rename the new one)

    In the INI in the [DISPLAY] section:

    In the [KINS] section
    JOINTS = 3
    KINEMATICS = trivkins coordinates=XZC


    MAX_VELOCITY = 40.0
    MIN_LIMIT = -3600
    MAX_LIMIT = 3600
    HOME = 0
    FERROR = 1.0
    MIN_FERROR = .1
    MAX_VELOCITY = 40.0
    P = 2
    I = 0.0
    D = 0.0
    FF0 = 0.0
    FF1 = 0.0
    FF2 = 0.0
    BIAS = 0.0
    DEADBAND = 0.0
    MAX_OUTPUT = 0.0
    MIN_LIMIT = -3600
    MAX_LIMIT = 3600
    HOME_OFFSET = 0.000000

    And see if a C-axis appears in the GUI. (with only these changes it will f-error immediately if you try to move it)

    Then attach the HAL and INI from that config here so that we can have a look at setting up the C-axis.
    Last edit: 08 Apr 2021 20:48 by andypugh.

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

    08 Apr 2021 20:53 - 08 Apr 2021 20:53 #205361 by PCW
    Note that hostmot2 in master supports clearing the stepgen position
    and also supports index on the stepgen
    Last edit: 08 Apr 2021 20:53 by PCW.

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

    Time to create page: 0.099 seconds
    Powered by Kunena Forum