[Home]Closed Loop Spindle Speed Control

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org

Showing revision 1
I've managed to get closed loop spindle speed control working. It takes a few seconds for the RPMs to settle down to the commanded RPMs but I'm sure with better PID loop tuning it could settle down faster.


An encoder is attached to the spindle, in my case a 1 pulse per revolution encoder. The position of the encoder is scaled using a HAL scale component from pulses per second to pulses per minute thereby giving RPMs. In my case since I had a single pulse per revolution I scaled by 60 to give spindle RPM. This spindle RPM is connected to the feedback pin of a HAL pid component. The commanded spindle RPM is connected to the command pin of the PID. The PID is tuned to use Pgain=0, Igain=1, Dgain=1. The output of the PID is added to the commanded spindle RPM and then fed into the pwmgen as the value of the pwm.

Hal file snippet

# --------------------------------------------------
#   Closed Loop Spindle Control
# --------------------------------------------------
    # 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 1
        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
        setp pid.0.Igain 1
        setp pid.0.Dgain 1
        setp pid.0.maxoutput 4000

    # Initialize the pwmgen
        loadrt pwmgen output_type=0
        addf pwmgen.update servo-thread
        addf pwmgen.make-pulses base-thread
        setp pwmgen.0.pwm-freq 1000.0
        setp pwmgen.0.scale 4000
        setp pwmgen.0.dither-pwm true

    # Initialize the scale
    # (This is used to scale the encoder pulse to RPM)
    # (In my case, i have 1 ppr so it is scaled by 60)
        loadrt scale count=1
        addf scale.0 servo-thread
        setp scale.0.gain 60

    # Initialize the sum2
        loadrt sum2 count=1
        addf sum2.0 servo-thread

    # Attach the motion.spindle-on to enable the pwmgen and the pid
        net spindle_enable motion.spindle-on => pwmgen.0.enable => pid.0.enable

    # Attach the encoder to the parallel port pin
        net parport_15_in         parport.0.pin-15-in => encoder.0.phase-A => encoder.0.phase-Z

    # Attach the encoder to the motion and the scale
        net spindle_rev_count     encoder.0.position => motion.spindle-revs
        net spindle_index_enable  encoder.0.index-enable <=> motion.spindle-index-enable
        net encoder_raw_velocity  encoder.0.velocity => scale.0.in

    # Attach the pid to the scale, motion, and sum
        net pid_feedback          pid.0.feedback <= motion.spindle-speed-in <= scale.0.out
        net pid_command           pid.0.command  <= motion.spindle-speed-out => sum2.0.in0
        net pid_output            pid.0.output   => sum2.0.in1

    # Attach the pwmgen to the sum and the parallel port
        net pwmgen_value          pwmgen.0.value <= sum2.0.out
        net pwmgen_out            pwmgen.0.pwm   => parport.0.pin-16-out

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org
This page is read-only. Follow the BasicSteps to edit pages. | View other revisions | View current revision
Edited April 11, 2009 3:29 pm by FlyingElectron (diff)
Published under a Creative Commons License