Designing Spindle PID

More
9 years 1 month ago #99071 by danimal300
I tried this a while back, and could not tune my spindle properly and ended up just deleting it. Now I am in a dynamics and controls class in college and plan to develop a solid closed loop control system for my CNC machine as part of a project. Project guidelines call for full explanation of design choices and how they affect the control, so I think that it would make a good tutorial for future hobby mill configurations similar to mine. I just need some help with the scope and big picture design and I will apply the rest and hopefully document it here.

One big problem that I have is that I am not even sure what production machines are capable of. My entire machining experience has been a self taught run of do's and dont's through hobby mills that have led up to a pretty accurate machine that I feel that I can rely on but want to take to the next level. I want to know that it is loaded properly and removing material as efficiently as possible.

My machine setup: LMS 3990 with Gecko G540 controller, using nema 23 stepper motors. I have a hall effect sensor and 4 magnetic sensor points on the spindle, and so far I have that configured correctly to view RPM as verified by hand held tachometer. I have the spindle control board and can view RPM on my HMI in LinuxCNC.

Mechanical Configuration:
1) I am considering printing a ring and converting the sensor to a IR type sensor with higher resolution than 4 pulses per revolution. But for a machine that has 0 - 2500 RPM capability, how many pulses would be best for optimal resolution and highest accuracy?
2) My spindle is 500W, so it is pretty easy to overload it even if my end mill is well within its chip load. Will I need to consider different material types? Will I need to change PID set points in order to mill steel vs aluminum?

I have read most threads on here for PID, but please feel free to link any and all of them because I tend to overlook information if it does not immediately appear useful to my immediate work. Also feel free to offer any guidance or "what if" suggestions because I want to get the most out of this machine and I have a narrow window to design and build the best controller that I can. I would like to make it as diverse and capable as I can because I may not have time to improve it for a while.

Thanks for all the help in advance!

Please Log in to join the conversation.

More
9 years 1 month ago #99231 by andypugh
Replied by andypugh on topic Designing Spindle PID
If you are using a parallel port then the first thing to work out for the spindle sensor is how fast your parallel port can reliably see all 4 edges of the quadrature counter.
This is a very simple calculation based on the base thread period. Plus some headroom.

Please Log in to join the conversation.

More
8 years 11 months ago #102246 by danimal300
Replied by danimal300 on topic Designing Spindle PID
I am sure that this is easy to a lot of the folks on here, but I finally got closed loop PID control working on my machine. It is a LMS 3900 benchtop mill that has been converted to CNC and I built a hall effect sensor encoder for the spindle output. I chose a simple detector for the time being to avoid quadrature and simplify tuning.

I need some help optimising the tuning, and see if I can find a way to view the transfer function to a step input. I tried the hal-scope, but did not have much luck. It seemed like the sample period was too small to capture the whole impulse response. I was measuring pid_feedback and hoping to get something that resembles the total overshoot.

I can run the calculations if I can just figure out a way to record the machine response in a way that I can determine the location of the poles in the transfer function.

Thanks for the help!

Please Log in to join the conversation.

More
8 years 11 months ago #102247 by danimal300
Replied by danimal300 on topic Designing Spindle PID
Here is my .hal file, can I get some feedback on general efficiency and best practices? I am getting better at organizing everything, but I still have a lot to learn.
Code:
loadrt trivkins loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES # Parallel port setup loadrt probe_parport loadrt hal_parport cfg="0x378 out" setp parport.0.reset-time 1000 addf parport.0.read base-thread addf parport.0.write base-thread addf parport.0.reset base-thread net spindle-ccw => parport.0.pin-01-out net xstep => parport.0.pin-02-out setp parport.0.pin-02-out-reset 1 setp parport.0.pin-03-out-invert 1 net xdir => parport.0.pin-03-out net ystep => parport.0.pin-04-out setp parport.0.pin-04-out-reset 1 net ydir => parport.0.pin-05-out net zstep => parport.0.pin-06-out setp parport.0.pin-06-out-reset 1 net zdir => parport.0.pin-07-out net astep => parport.0.pin-08-out setp parport.0.pin-08-out-reset 1 net adir => parport.0.pin-09-out net charge-pump => parport.0.pin-16-out net spindle-on => parport.0.pin-17-out net spindle-phase-a <= parport.0.pin-10-in net spindle-index <= parport.0.pin-11-in # Stepgen setup loadrt stepgen step_type=0,0,0,0 addf stepgen.make-pulses base-thread loadrt abs count=1 addf stepgen.capture-position servo-thread addf stepgen.update-freq servo-thread # Initialize the scale (This is used to scale the encoder pulse to RPM) # Scaling factor 6 pulses per revolution x 60 sec per min = 360 loadrt scale count=3 addf scale.0 servo-thread setp scale.0.gain 360 addf scale.1 servo-thread setp scale.1.gain 60 addf scale.2 servo-thread setp scale.2.gain 60 # Initilize Low Pass Filter for Spindle loadrt lowpass count=2 addf lowpass.0 servo-thread addf abs.0 servo-thread addf lowpass.1 servo-thread # E-Stop and Charge Pump enable loadrt charge_pump net estop-out charge-pump.enable iocontrol.0.user-enable-out net charge-pump <= charge-pump.out addf charge-pump base-thread net estop-out <= iocontrol.0.user-enable-out net estop-out => iocontrol.0.emc-enable-in loadrt near addf near.0 servo-thread # Initialize the encoder (spindle) loadrt encoder num_chan=1 addf encoder.update-counters base-thread addf encoder.capture-position servo-thread setp encoder.0.position-scale 6.000000 setp encoder.0.counter-mode 1 # Initialize the PID loadrt pid num_chan=1 addf pid.0.do-pid-calcs servo-thread setp pid.0.Pgain 0.003 setp pid.0.Igain 1 setp pid.0.Dgain 0.004 setp pid.0.maxoutput 80 # Initialize the pwmgen # loadrt pwmgen output_type=1 loadrt pwmgen output_type=0 addf pwmgen.update servo-thread addf pwmgen.make-pulses base-thread setp pwmgen.0.pwm-freq 50.0 setp pwmgen.0.scale 4000.0 setp pwmgen.0.offset -.0090 setp pwmgen.0.dither-pwm true #setp pwmgen.0.min-dc 0.001 # min output duty cycle --> lowest possible spindle speed #setp pwmgen.0.max-dc .8 # max output duty cycle --> highest possible spindle speed # Initialize the sum2 loadrt sum2 count=1 addf sum2.0 servo-thread # Initialize the inverter for negative feedback loadrt invert count=1 addf invert.0 servo-thread addf motion-command-handler servo-thread addf motion-controller servo-thread # Spindle PID closed loop controler net spindle-cw <= motion.spindle-forward net spindle-phase-a encoder.0.phase-A net spindle-index encoder.0.phase-Z net spindle-on motion.spindle-on => pwmgen.0.enable => pid.0.enable net spindle-pwm pwmgen.0.pwm => parport.0.pin-14-out net spindle-index-enable encoder.0.index-enable <=> motion.spindle-index-enable net spindle-position encoder.0.position => motion.spindle-revs net spindle-velocity encoder.0.velocity => scale.2.in net pid_feedback pid.0.feedback <= motion.spindle-speed-in <= scale.2.out net pid_command pid.0.command <= motion.spindle-speed-out => sum2.0.in1 net pid_error pid.0.error net pid_output pid.0.output => sum2.0.in0 net pwmgen_value pwmgen.0.value <= sum2.0.out setp stepgen.0.position-scale [AXIS_0]SCALE setp stepgen.0.steplen 2500 setp stepgen.0.stepspace 2500 setp stepgen.0.dirhold 1000 setp stepgen.0.dirsetup 1000 setp stepgen.0.maxaccel [AXIS_0]STEPGEN_MAXACCEL net xpos-cmd axis.0.motor-pos-cmd => stepgen.0.position-cmd net xpos-fb stepgen.0.position-fb => axis.0.motor-pos-fb net xstep <= stepgen.0.step net xdir <= stepgen.0.dir net xenable axis.0.amp-enable-out => stepgen.0.enable setp stepgen.1.position-scale [AXIS_1]SCALE setp stepgen.1.steplen 2500 setp stepgen.1.stepspace 2500 setp stepgen.1.dirhold 1000 setp stepgen.1.dirsetup 1000 setp stepgen.1.maxaccel [AXIS_1]STEPGEN_MAXACCEL net ypos-cmd axis.1.motor-pos-cmd => stepgen.1.position-cmd net ypos-fb stepgen.1.position-fb => axis.1.motor-pos-fb net ystep <= stepgen.1.step net ydir <= stepgen.1.dir net yenable axis.1.amp-enable-out => stepgen.1.enable setp stepgen.2.position-scale [AXIS_2]SCALE setp stepgen.2.steplen 2500 setp stepgen.2.stepspace 2500 setp stepgen.2.dirhold 1000 setp stepgen.2.dirsetup 1000 setp stepgen.2.maxaccel [AXIS_2]STEPGEN_MAXACCEL net zpos-cmd axis.2.motor-pos-cmd => stepgen.2.position-cmd net zpos-fb stepgen.2.position-fb => axis.2.motor-pos-fb net zstep <= stepgen.2.step net zdir <= stepgen.2.dir net zenable axis.2.amp-enable-out => stepgen.2.enable setp stepgen.3.position-scale [AXIS_3]SCALE setp stepgen.3.steplen 1 setp stepgen.3.stepspace 0 setp stepgen.3.dirhold 20200 setp stepgen.3.dirsetup 20200 setp stepgen.3.maxaccel [AXIS_3]STEPGEN_MAXACCEL net apos-cmd axis.3.motor-pos-cmd => stepgen.3.position-cmd net apos-fb stepgen.3.position-fb => axis.3.motor-pos-fb net astep <= stepgen.3.step net adir <= stepgen.3.dir net aenable axis.3.amp-enable-out => stepgen.3.enable loadusr -W hal_manualtoolchange net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared

Please Log in to join the conversation.

More
8 years 11 months ago #102248 by danimal300
Replied by danimal300 on topic Designing Spindle PID
My Encoder design:
Here are the cad files for the sensor mount. It fits on the LMS 3990 mill, not sure if it will work on others.

Spindle Lock Cap

Main Sensor Body

Sensor Ring

Please Log in to join the conversation.

More
8 years 11 months ago #102256 by andypugh
Replied by andypugh on topic Designing Spindle PID

danimal300 wrote: I need some help optimising the tuning, and see if I can find a way to view the transfer function to a step input. I tried the hal-scope, but did not have much luck. It seemed like the sample period was too small to capture the whole impulse response.


You can change the Haslcope sampling frequency to record for longer. By default it samples every 1mS but you can sample every 2, every 4 and so on.

Click where is says something like "4000 samples in 4 seconds"

I think that you might be over-thinking this, with the talk of poles etc.

Please Log in to join the conversation.

More
8 years 11 months ago #102268 by danimal300
Replied by danimal300 on topic Designing Spindle PID
I am over thinking the design of the controller, but that is because it is for a college dynamics and controls class. I would really like to dive into the inner workings and really tune the response of the controller, so I just need a way to determine the transfer function of the plant and I can use matlab sisotool to really tweak the inputs. I have a perfectly functional controller, but the fine tuning aspects are what I am shooting for with this project.

Here is a video of it functioning. It is a little long because I plan on clipping it down and creating a project video for the class presentation:

Please Log in to join the conversation.

More
8 years 11 months ago #102269 by danimal300
Replied by danimal300 on topic Designing Spindle PID
Is there any way to sample pins and dump the information into a spreadsheet? I see the hal histogram, and will play with that a little bit but it looks a little limited, and it would be nice to select a couple pins and have it dump some values into a spreadsheet on like a servo thread periodicity.

Any ideas on how I could get this to print out?

Please Log in to join the conversation.

More
8 years 11 months ago #102270 by andypugh
Replied by andypugh on topic Designing Spindle PID
You can save the data file from Halscope.

Please Log in to join the conversation.

More
8 years 11 months ago #102274 by Muzzer
Replied by Muzzer on topic Designing Spindle PID
A machine technician would traditionally start with P only, increasing until instability starts, then add some D to improve the transient response and some I to eliminate any offset. Of course, they all interact, so it tends to be an iterative process. It helps if you are watching the output (speed) so you can observe any overshoot etc. With some messing about you should be able to get a reasonable result. I'm sure there are loads of Pootube videos out there that cover this.

A slightly more insightful approach would be to run the system open loop and give it a step input (set voltage). Then observe the delay (s) and response rate (rpm per second etc) and use a rule of thumb method like Ziegler Nichols to estimate some starting values.

But if you are aiming to become a control engineer in some way (ie what you should be doing here?), you should be making your own model of the plant - it's not difficult. For that you simply need stuff like the moment of inertia of the spinning bits (taking account of the gear ratios etc), the volts per rev of the feedback signal and the torque-volts gain of the motor vs the control voltage etc. This is fairly simple stuff and I expect you will probably find something very close to what you need if you check out the Matlab tutorials.

From the system you have, you need to be able to see the demand signal (presumably a DC voltage to the spindle VFD) and the feedback signal from the pickup, ideally normalised to the same basis as the demand signal. It's the difference between these 2 signals that the PID controller works on.

Murray

Please Log in to join the conversation.

Time to create page: 0.064 seconds
Powered by Kunena Forum