Servo as spindle problems with speed and encoder feedback

More
04 Dec 2019 14:23 #151998 by jools
Currently have the spindle connected to an AC servo and was considering PWM but liked the idea of speed control as PWM on startup gave very little torque.

So I connected the servo up and hooked it to a spare stepgen on the 7i96. To get the basic settings I ran a pnc conf for a 7i76 and copied pasted the spindle section across editing the bits to 7i96. Read the 1.8 manual about mesa, hal and ini but couldn't find the answer.

The spindle turns on and monitoring the hal pins shows things should be correct apart from:
- Speed is limited to 1100 RPM gained from the servo driver readout. This is achieved with one click of the 'axis button that increases speed'.
- My encoder feedback through the 7i96 is stupidly high. Its suggesting I'm doing 3 million rpm
- I don't think my PID is hooked up as spindle-output when monitored as a signal never moves

Any help is appreciated.

Jools
NB: The 1.8 documentation for the INI configuration doesn't document SPINDLE
HAL
# This file was created with the 7i96 Wizard on Nov 21 2019 15:52:11
# If you make changes to this file DO NOT run the configuration tool again!
# This file will be replaced with a new file if you do!

# kinematics
loadrt [KINS]KINEMATICS

# motion controller
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS

# standard components
loadrt pid num_chan=4 

# hostmot2 driver
loadrt hostmot2

loadrt [HOSTMOT2](DRIVER) board_ip=[HOSTMOT2](IPADDRESS) config="num_encoders=[HOSTMOT2](ENCODERS)num_stepgens=[HOSTMOT2](STEPGENS)"sserial_port_0=[HOSTMOT2](SSERIAL_PORT)pwm_gens=1
setp hm2_[HOSTMOT2](BOARD).0.watchdog.timeout_ns 25000000

# THREADS
addf hm2_[HOSTMOT2](BOARD).0.read servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
setp hm2_[HOSTMOT2](BOARD).0.dpll.01.timer-us -100
setp hm2_[HOSTMOT2](BOARD).0.stepgen.timer-number 1 
addf pid.0.do-pid-calcs servo-thread
addf pid.1.do-pid-calcs servo-thread
addf pid.2.do-pid-calcs servo-thread
addf pid.3.do-pid-calcs servo-thread
addf hm2_[HOSTMOT2](BOARD).0.write servo-thread

# Spindle

setp pid.3.Pgain [SPINDLE]P
setp pid.3.Igain [SPINDLE]I
setp pid.3.Dgain [SPINDLE]D
setp pid.3.bias [SPINDLE]BIAS
setp pid.3.FF0 [SPINDLE]FF0
setp pid.3.FF1 [SPINDLE]FF1
setp pid.3.FF2 [SPINDLE]FF2
setp pid.3.deadband [SPINDLE]DEADBAND
setp pid.3.maxoutput [SPINDLE]MAX_RPM
setp pid.3.maxerror [SPINDLE]MAX_ERROR
setp pid.3.error-previous-target true
setp pid.3.maxerror .1

net spindle-index-enable  		<=> pid.3.index-enable
net spindle-enable        		=>  pid.3.enable
net spindle-vel-cmd-rpm     		=> pid.3.command
net spindle-vel-fb-rpm      		=> pid.3.feedback
net spindle-output        		<=  pid.3.output


setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.dirsetup [SPINDLE]DIRSETUP
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.dirhold [SPINDLE]DIRHOLD
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.steplen [SPINDLE]STEPLEN
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.stepspace [SPINDLE]STEPSPACE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.position-scale [SPINDLE]SCALE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.maxvel [SPINDLE]MAX_RPM
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.maxaccel [SPINDLE]STEPGEN_MAX_ACCEL
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.step_type 0
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.control-type 1

#

net spindle-enable          		=>  hm2_7i96.0.stepgen.03.enable
net speedsend spindle.0.speed-out     	=>  hm2_7i96.0.stepgen.03.velocity-cmd
net spindle-vel-fb-rpm         		<=  hm2_7i96.0.encoder.00.velocity

# ---setup spindle control signals---

net spindle-vel-cmd-rps        		<=  spindle.0.speed-out-rps
net spindle-vel-cmd-rps-abs    		<=  spindle.0.speed-out-rps-abs
net spindle-vel-cmd-rpm-abs    		<=  spindle.0.speed-out-abs
net spindle-enable             		<=  spindle.0.on
net spindle-cw                 		<=  spindle.0.forward
net spindle-ccw                		<=  spindle.0.reverse
net spindle-brake              		<=  spindle.0.brake
net spindle-revs               		=>  spindle.0.revs
net spindle-at-speed           		=>  spindle.0.at-speed
net spindle-vel-fb-rps         		=>  spindle.0.speed-in
net spindle-index-enable      		<=>  spindle.0.index-enable

# Standard I/O Block - EStop, Etc
# create a signal for the estop loopback
net estop-loop iocontrol.0.user-enable-out => iocontrol.0.emc-enable-in
net all-fault hm2_7i96.0.gpio.005.in <= joint.0.amp-fault-in


net home-joint-1 joint.1.home-sw-in <= hm2_7i96.0.gpio.000.in
net home-joint-2 joint.2.home-sw-in <= hm2_7i96.0.gpio.001.in
net home-joint-0 joint.0.home-sw-in <= hm2_7i96.0.gpio.002.in

# create signals for tool loading loopback
net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
net tool-change-loop iocontrol.0.tool-change => iocontrol.0.tool-changed


.INI
# This file was created with the 7i96 Wizard on Nov 21 2019 15:52:11
# Changes to most things are ok and will be read by the wizard

[EMC]
VERSION = 1.1
MACHINE = jools
DEBUG = 0x00000000

[HOSTMOT2]
DRIVER = hm2_eth
IPADDRESS = "10.10.10.10"
BOARD = 7i96
STEPGENS = 4
ENCODERS = 1
SSERIAL_PORT = 1

[DISPLAY]
# required NativeCAM item :
NCAM_DIR = ncam

# required NativeCAM item :
PROGRAM_PREFIX = ncam/scripts/

# required NativeCAM item :
GLADEVCP = -U --catalog=mill /usr/share/linuxcnc/aux_gladevcp/NativeCAM/ncam.ui

DISPLAY = axis
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = COMMANDED
MAX_FEED_OVERRIDE = 2.0
CYCLE_TIME = 0.1
INTRO_GRAPHIC = emc2.gif
INTRO_TIME = 0
OPEN_FILE = ""
INCREMENTS = 30, 20, 10, 5, 1, .5, .05, .02, .01
DEFAULT_LINEAR_VELOCITY = 14
EDITOR = GEDIT


[KINS]
KINEMATICS = trivkins coordinates=XYZ
JOINTS = 3

[EMCIO]
EMCIO = io
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl

[RS274NGC]
# required NativeCAM item :
SUBROUTINE_PATH = ncam/my-stuff:ncam/lib/mill:ncam/lib/utilities

PARAMETER_FILE = jools.var
CENTER_ARC_RADIUS_TOLERANCE_MM = .001 

[EMCMOT]
EMCMOT = motmod
SERVO_PERIOD = 1000000

[TASK]
TASK = milltask
CYCLE_TIME = 0.010

[TRAJ]
COORDINATES = XYZ
LINEAR_UNITS = metric
ANGULAR_UNITS = degree
MAX_LINEAR_VELOCITY = 300
NO_FORCE_HOMING = 0
ARC_BLEND_ENABLE = 1
ARC_BLEND_OPTIMIZATION_DEPTH = 50


[HAL]
HALFILE = jools.hal
HALFILE = io.hal
HALFILE = custom.hal
POSTGUI_HALFILE = postgui.hal

[HALUI]

[AXIS_X]
MIN_LIMIT = 0
MAX_LIMIT = 380
MAX_VELOCITY = 50
MAX_ACCELERATION = 600

[AXIS_Y]
MIN_LIMIT = -230
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 600

[AXIS_Z]
MIN_LIMIT = -200
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 125

[JOINT_0]
AXIS = X
MIN_LIMIT = 0
MAX_LIMIT = 380
MAX_VELOCITY = 50
MAX_ACCELERATION = 400
TYPE = LINEAR
SCALE = 1600
STEPGEN_MAX_VEL = 60
STEPGEN_MAX_ACC = 720
FERROR = 0.0051
MIN_FERROR = 0.0025
DIRSETUP = 6000
DIRHOLD = 6000
STEPLEN = 3000
STEPSPACE = 3000
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0.00013
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = .1
HOME_SEARCH_VEL = -10
HOME_LATCH_VEL = -1
HOME_SEQUENCE = 1
HOME_USE_INDEX = False
HOME_IGNORE_LIMITS = False

[JOINT_1]
AXIS = Y
MIN_LIMIT = -230
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 600
TYPE = LINEAR
SCALE = 1600
STEPGEN_MAX_VEL = 60
STEPGEN_MAX_ACC = 720
FERROR = 0.0051
MIN_FERROR = 0.0025
DIRSETUP = 6000
DIRHOLD = 6000
STEPLEN = 3000
STEPSPACE = 3000
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0.00013
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = .1
HOME_SEARCH_VEL = 10
HOME_LATCH_VEL = 1
HOME_SEQUENCE = 2
HOME_USE_INDEX = False
HOME_IGNORE_LIMITS = False

[JOINT_2]
AXIS = Z
MIN_LIMIT = -200
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 125
TYPE = LINEAR
SCALE = 1000
STEPGEN_MAX_VEL = 60
STEPGEN_MAX_ACC = 150
FERROR = 0.0051
MIN_FERROR = 0.0025
DIRSETUP = 10000
DIRHOLD = 10000
STEPLEN = 10000
STEPSPACE = 10000
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0.00013
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = -.1
HOME_SEARCH_VEL = 10
HOME_LATCH_VEL = 1
HOME_SEQUENCE = 0
HOME_USE_INDEX = False
HOME_IGNORE_LIMITS = False

[SPINDLE]
SPINDLE_TYPE = closedLoop
SCALE = 10000
MAX_RPM = 2500
MIN_RPM = 0
STEPGEN_MAXVEL = 40
STEPGEN_MAX_ACCEL = 60
MAX_ERROR = .01
P = 50
I = 0.0
D = 0.0
FF0 = 0.0
FF1 = 0.0
FF2 = 0.0
BIAS = 0.0
DEADBAND = 0.0
MAX_OUTPUT = 2000.0
# these are in nanoseconds
DIRSETUP   = 5000
DIRHOLD    = 5000
STEPLEN    = 2500
STEPSPACE  = 2500


[INPUTS]
# DO NOT change the input text
INPUT_0 = Home
INPUT_JOINT_0 = 0
INPUT_1 = Home
INPUT_JOINT_1 = 1
INPUT_2 = Home
INPUT_JOINT_2 = 2
INPUT_3 = Select
INPUT_JOINT_3 = False
INPUT_4 = Select
INPUT_JOINT_4 = False
INPUT_5 = E-Stop In
INPUT_JOINT_5 = False
INPUT_6 = Home
INPUT_JOINT_6 = False
INPUT_7 = Select
INPUT_JOINT_7 = False
INPUT_8 = Select
INPUT_JOINT_8 = False
INPUT_9 = Select
INPUT_JOINT_9 = False
INPUT_10 = Select
INPUT_JOINT_10 = False

[OUTPUTS]
# DO NOT change the output text
OUTPUT_0 = Spindle CW
OUTPUT_1 = Spindle On
OUTPUT_2 = Spindle CCW
OUTPUT_3 = Select
OUTPUT_4 = Select

[OPTIONS]
MANUAL_TOOL_CHANGE = True
HALUI = False
PYVCP = False
GLADEVCP = False
LADDER = False

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

More
04 Dec 2019 17:04 #152009 by PCW
1. I don't think you can rule out the PWM control method unless you have fully tuned the control loop

2. if you are going to use a step/dir servo for a spindle, you don't really need PID at all,
you just set the stepgen velocity with commanded spindle RPM (with proper stepgen scaling)

3. You likely have a extremely high spindle RPM readout for 2 reasons, A: the encoder velocity pin is in RPS (= 60x RPM) newer LinuxCNC versions provide a velocity pin scaled in RPM, this should be used instead, lacking this the scale component would need to be used if you wanted to display encoder derived RPM

4. If you are using PWM and PID the tuning is chiefly done with FF0 = 1.00.

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

More
05 Dec 2019 16:50 #152075 by jools
Hi Peter

2. if you are going to use a step/dir servo for a spindle, you don't really need PID at all,
you just set the stepgen velocity with commanded spindle RPM (with proper stepgen scaling)


Yes you were correct. I was seeing 'scale' next to the stepgen output and abitrarily reading it as encoder scale.

I have the spindle working now in this mode and scaled correctly. I reduced the dir and pulse timings and I can get to the spindle speed I need and it seems to work fine; thanks for the pointer.

3. You likely have a extremely high spindle RPM readout for 2 reasons, A: the encoder velocity pin is in RPS (= 60x RPM) newer LinuxCNC versions provide a velocity pin scaled in RPM, this should be used instead, lacking this the scale component would need to be used if you wanted to display encoder derived RPM


I think I need to use the scale component here. I was reading the encoder pins on the HM2 in both RPS and RPM and neither was correct. Having sorted the speed and scaling though I can now say I am out by a factor of 10,000 which would seem to correspond to the quadrature count of my 2500 cpr encoder.

I tried to add the encoder but when I do again I get faults at start up. The 'loadrt' code is in my hal and references the number of encoders in my ini. This was set by the 7i96 config tool. If I addf encoder.update−counters as below from the manual then I need to add a thread for it to be sampled. Now my setup doesn't have a base thread which I would need, or something of a faster speed to the servo period, to attach this function to. I added a 'load rt' for base period just before the servo period in the hal and added 50000ns in the ini for it to reference. This threw me an error on start up.

From the manual:

FUNCTIONS

encoder.update−counters (no floating-point)

Does the actual counting, by sampling the encoder signals and decoding the quadrature waveforms. Must be called as frequently as possible, preferably twice as fast as the maximum desired count rate. Operates on all channels at once.

encoder.capture−position (uses floating point)

Captures the raw counts from update−counters and performs scaling and other necessary conversion, handles counter rollover, etc. Can (and should) be called less frequently than update−counters. Operates on all channels at once.


This is also referenced in the wiki
# --------------------------------------------------
#   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

Looking further I found in my parameters this. which says my encoder scale is 1. As it should be 10,000 then this seems the likely culprit to my ills. Looking through the hal though this parameter is not mentioned anywhere and isn't referenced in ini file either.

B)
Managed to figure it out. After a few tries of setting it and it failing I managed to figure it out and set the parameter.

To help others my failings came from adding an = sign between the setp instance name... and the value.

My encoder now reads the right speed my final hal and ini are below in case anyone else has this problem.
# This file was created with the 7i96 Wizard on Nov 21 2019 15:52:11
# If you make changes to this file DO NOT run the configuration tool again!
# This file will be replaced with a new file if you do!

# kinematics
loadrt [KINS]KINEMATICS

# motion controller
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS

# standard components
loadrt pid num_chan=4 

# hostmot2 driver
loadrt hostmot2

loadrt [HOSTMOT2](DRIVER) board_ip=[HOSTMOT2](IPADDRESS) config="num_encoders=1 num_stepgens=[HOSTMOT2](STEPGENS)"sserial_port_0=[HOSTMOT2](SSERIAL_PORT)pwm_gens=1
setp hm2_[HOSTMOT2](BOARD).0.watchdog.timeout_ns 25000000

#/////////////////////////////////
# THREADS
#///////////////////////////////

addf hm2_[HOSTMOT2](BOARD).0.read servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
setp hm2_[HOSTMOT2](BOARD).0.dpll.01.timer-us -100
setp hm2_[HOSTMOT2](BOARD).0.stepgen.timer-number 1 
addf pid.0.do-pid-calcs servo-thread
addf pid.1.do-pid-calcs servo-thread
addf pid.2.do-pid-calcs servo-thread
addf pid.3.do-pid-calcs servo-thread
addf hm2_[HOSTMOT2](BOARD).0.write servo-thread

setp hm2_7i96.0.encoder.00.scale 10000

#/////////////////////////////////////
# Joint 0
# axis enable chain
#/////////////////////////////////////

newsig emcmot.0.enable bit
sets emcmot.0.enable FALSE
net emcmot.0.enable <= joint.0.amp-enable-out
net emcmot.0.enable => hm2_[HOSTMOT2](BOARD).0.stepgen.00.enable pid.0.enable

# position command and feedback

net emcmot.0.pos-cmd joint.0.motor-pos-cmd => pid.0.command
net motor.0.pos-fb <= hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-fb joint.0.motor-pos-fb pid.0.feedback
net motor.0.command pid.0.output hm2_[HOSTMOT2](BOARD).0.stepgen.00.velocity-cmd
setp pid.0.error-previous-target true

setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.dirsetup [JOINT_0]DIRSETUP
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.dirhold [JOINT_0]DIRHOLD
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.steplen [JOINT_0]STEPLEN
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.stepspace [JOINT_0]STEPSPACE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-scale [JOINT_0]SCALE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.maxvel [JOINT_0]STEPGEN_MAX_VEL
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.maxaccel [JOINT_0]STEPGEN_MAX_ACC
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.step_type 0
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.control-type 1

setp pid.0.Pgain [JOINT_0]P
setp pid.0.Igain [JOINT_0]I
setp pid.0.Dgain [JOINT_0]D
setp pid.0.bias [JOINT_0]BIAS
setp pid.0.FF0 [JOINT_0]FF0
setp pid.0.FF1 [JOINT_0]FF1
setp pid.0.FF2 [JOINT_0]FF2
setp pid.0.deadband [JOINT_0]DEADBAND
setp pid.0.maxoutput [JOINT_0]MAX_OUTPUT
setp pid.0.maxerror [JOINT_0]MAX_ERROR

#///////////////////////////////////
# Joint 1
# axis enable chain
#////////////////////////////////////

newsig emcmot.1.enable bit
sets emcmot.1.enable FALSE
net emcmot.1.enable <= joint.1.amp-enable-out
net emcmot.1.enable => hm2_[HOSTMOT2](BOARD).0.stepgen.01.enable pid.1.enable

# position command and feedback

net emcmot.1.pos-cmd joint.1.motor-pos-cmd => pid.1.command
net motor.1.pos-fb <= hm2_[HOSTMOT2](BOARD).0.stepgen.01.position-fb joint.1.motor-pos-fb pid.1.feedback
net motor.1.command pid.1.output hm2_[HOSTMOT2](BOARD).0.stepgen.01.velocity-cmd
setp pid.1.error-previous-target true

setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.dirsetup [JOINT_1]DIRSETUP
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.dirhold [JOINT_1]DIRHOLD
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.steplen [JOINT_1]STEPLEN
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.stepspace [JOINT_1]STEPSPACE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.position-scale [JOINT_1]SCALE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.maxvel [JOINT_1]STEPGEN_MAX_VEL
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.maxaccel [JOINT_1]STEPGEN_MAX_ACC
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.step_type 0
setp hm2_[HOSTMOT2](BOARD).0.stepgen.01.control-type 1

setp pid.1.Pgain [JOINT_1]P
setp pid.1.Igain [JOINT_1]I
setp pid.1.Dgain [JOINT_1]D
setp pid.1.bias [JOINT_1]BIAS
setp pid.1.FF0 [JOINT_1]FF0
setp pid.1.FF1 [JOINT_1]FF1
setp pid.1.FF2 [JOINT_1]FF2
setp pid.1.deadband [JOINT_1]DEADBAND
setp pid.1.maxoutput [JOINT_1]MAX_OUTPUT
setp pid.1.maxerror [JOINT_1]MAX_ERROR

#//////////////////////////
# Joint 2
# axis enable chain
#////////////////////////////

newsig emcmot.2.enable bit
sets emcmot.2.enable FALSE
net emcmot.2.enable <= joint.2.amp-enable-out
net emcmot.2.enable => hm2_[HOSTMOT2](BOARD).0.stepgen.02.enable pid.2.enable

# position command and feedback

net emcmot.2.pos-cmd joint.2.motor-pos-cmd => pid.2.command
net motor.2.pos-fb <= hm2_[HOSTMOT2](BOARD).0.stepgen.02.position-fb joint.2.motor-pos-fb pid.2.feedback
net motor.2.command pid.2.output hm2_[HOSTMOT2](BOARD).0.stepgen.02.velocity-cmd
setp pid.2.error-previous-target true

setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.dirsetup [JOINT_2]DIRSETUP
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.dirhold [JOINT_2]DIRHOLD
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.steplen [JOINT_2]STEPLEN
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.stepspace [JOINT_2]STEPSPACE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.position-scale [JOINT_2]SCALE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.maxvel [JOINT_2]STEPGEN_MAX_VEL
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.maxaccel [JOINT_2]STEPGEN_MAX_ACC
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.step_type 0
setp hm2_[HOSTMOT2](BOARD).0.stepgen.02.control-type 1

setp pid.2.Pgain [JOINT_2]P
setp pid.2.Igain [JOINT_2]I
setp pid.2.Dgain [JOINT_2]D
setp pid.2.bias [JOINT_2]BIAS
setp pid.2.FF0 [JOINT_2]FF0
setp pid.2.FF1 [JOINT_2]FF1
setp pid.2.FF2 [JOINT_2]FF2
setp pid.2.deadband [JOINT_2]DEADBAND
setp pid.2.maxoutput [JOINT_2]MAX_OUTPUT
setp pid.2.maxerror [JOINT_2]MAX_ERROR

#//////////////////////
# Spindle
#/////////////////////

setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.dirsetup [SPINDLE]DIRSETUP
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.dirhold [SPINDLE]DIRHOLD
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.steplen [SPINDLE]STEPLEN
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.stepspace [SPINDLE]STEPSPACE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.position-scale [SPINDLE]SCALE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.maxvel [SPINDLE]MAX_RPM
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.maxaccel [SPINDLE]STEPGEN_MAX_ACCEL
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.step_type 0
setp hm2_[HOSTMOT2](BOARD).0.stepgen.03.control-type 1


net spindle-enable          		=>  hm2_7i96.0.stepgen.03.enable
net speedsend spindle.0.speed-out     	=>  hm2_7i96.0.stepgen.03.velocity-cmd

# ---setup spindle control signals---

net spindle-vel-cmd-rps        		<=  spindle.0.speed-out-rps
net spindle-vel-cmd-rps-abs    		<=  spindle.0.speed-out-rps-abs
net spindle-vel-cmd-rpm-abs    		<=  spindle.0.speed-out-abs
net spindle-enable             		<=  spindle.0.on
net spindle-cw                 		<=  spindle.0.forward
net spindle-ccw                		<=  spindle.0.reverse
net spindle-brake              		<=  spindle.0.brake
net spindle-revs               		=>  spindle.0.revs hm2_7i96.0.encoder.00.velocity-rpm
net spindle-at-speed           		=>  spindle.0.at-speed
net spindle-vel-fb-rps         		=>  spindle.0.speed-in
net spindle-index-enable      		<=>  spindle.0.index-enable

#///////////////////////
# Standard I/O Block - EStop, Etc
# create a signal for the estop loopback. Connect to input 5
#///////////////////////////////

net estop-loop iocontrol.0.user-enable-out => iocontrol.0.emc-enable-in
net all-fault hm2_7i96.0.gpio.005.in <= joint.0.amp-fault-in

#////////////////////////////
#Homing
#/////////////////////////

net home-joint-1 joint.1.home-sw-in <= hm2_7i96.0.gpio.000.in
net home-joint-2 joint.2.home-sw-in <= hm2_7i96.0.gpio.001.in
net home-joint-0 joint.0.home-sw-in <= hm2_7i96.0.gpio.002.in

#/////////////////////////////////////
#probe on input 3
#////////////////////////////////

net probe-trigger hm2_7i96.0.gpio.003.in => motion.probe-input

# create signals for tool loading loopback
net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
net tool-change-loop iocontrol.0.tool-change => iocontrol.0.tool-changed
# This file was created with the 7i96 Wizard on Nov 21 2019 15:52:11
# Changes to most things are ok and will be read by the wizard

[EMC]
VERSION = 1.1
MACHINE = jools
DEBUG = 0x00000000

[HOSTMOT2]
DRIVER = hm2_eth
IPADDRESS = "10.10.10.10"
BOARD = 7i96
STEPGENS = 4
ENCODERS = 1
SSERIAL_PORT = 1

[DISPLAY]
# required NativeCAM item :
NCAM_DIR = ncam

# required NativeCAM item :
PROGRAM_PREFIX = ncam/scripts/

# required NativeCAM item :
GLADEVCP = -U --catalog=mill /usr/share/linuxcnc/aux_gladevcp/NativeCAM/ncam.ui

DISPLAY = axis
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = COMMANDED
MAX_FEED_OVERRIDE = 2.0
CYCLE_TIME = 0.1
INTRO_GRAPHIC = emc2.gif
INTRO_TIME = 0
OPEN_FILE = ""
INCREMENTS = 30, 20, 10, 5, 1, .5, .05, .02, .01
DEFAULT_LINEAR_VELOCITY = 14
EDITOR = GEDIT


[KINS]
KINEMATICS = trivkins coordinates=XYZ
JOINTS = 3

[EMCIO]
EMCIO = io
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl

[RS274NGC]
# required NativeCAM item :
SUBROUTINE_PATH = ncam/my-stuff:ncam/lib/mill:ncam/lib/utilities

PARAMETER_FILE = jools.var
CENTER_ARC_RADIUS_TOLERANCE_MM = .001 

[EMCMOT]
EMCMOT = motmod
SERVO_PERIOD = 1000000
BASE_PERIOD = 50000

[TASK]
TASK = milltask
CYCLE_TIME = 0.010

[TRAJ]
COORDINATES = XYZ
LINEAR_UNITS = metric
ANGULAR_UNITS = degree
MAX_LINEAR_VELOCITY = 300
NO_FORCE_HOMING = 0
ARC_BLEND_ENABLE = 1
ARC_BLEND_OPTIMIZATION_DEPTH = 50


[HAL]
HALFILE = jools.hal
HALFILE = io.hal
HALFILE = custom.hal
POSTGUI_HALFILE = postgui.hal

[HALUI]

[AXIS_X]
MIN_LIMIT = 0
MAX_LIMIT = 380
MAX_VELOCITY = 50
MAX_ACCELERATION = 600

[AXIS_Y]
MIN_LIMIT = -230
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 600

[AXIS_Z]
MIN_LIMIT = -200
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 125

[JOINT_0]
AXIS = X
MIN_LIMIT = 0
MAX_LIMIT = 380
MAX_VELOCITY = 50
MAX_ACCELERATION = 400
TYPE = LINEAR
SCALE = 1600
STEPGEN_MAX_VEL = 60
STEPGEN_MAX_ACC = 720
FERROR = 0.0051
MIN_FERROR = 0.0025
DIRSETUP = 6000
DIRHOLD = 6000
STEPLEN = 3000
STEPSPACE = 3000
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0.00013
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = .1
HOME_SEARCH_VEL = -10
HOME_LATCH_VEL = -1
HOME_SEQUENCE = 1
HOME_USE_INDEX = False
HOME_IGNORE_LIMITS = False

[JOINT_1]
AXIS = Y
MIN_LIMIT = -230
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 600
TYPE = LINEAR
SCALE = 1600
STEPGEN_MAX_VEL = 60
STEPGEN_MAX_ACC = 720
FERROR = 0.0051
MIN_FERROR = 0.0025
DIRSETUP = 6000
DIRHOLD = 6000
STEPLEN = 3000
STEPSPACE = 3000
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0.00013
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = .1
HOME_SEARCH_VEL = 10
HOME_LATCH_VEL = 1
HOME_SEQUENCE = 2
HOME_USE_INDEX = False
HOME_IGNORE_LIMITS = False

[JOINT_2]
AXIS = Z
MIN_LIMIT = -200
MAX_LIMIT = 0.5
MAX_VELOCITY = 50
MAX_ACCELERATION = 125
TYPE = LINEAR
SCALE = 1000
STEPGEN_MAX_VEL = 60
STEPGEN_MAX_ACC = 150
FERROR = 0.0051
MIN_FERROR = 0.0025
DIRSETUP = 10000
DIRHOLD = 10000
STEPLEN = 10000
STEPSPACE = 10000
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0.00013
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = -.1
HOME_SEARCH_VEL = 10
HOME_LATCH_VEL = 1
HOME_SEQUENCE = 0
HOME_USE_INDEX = False
HOME_IGNORE_LIMITS = False

[SPINDLE]
SPINDLE_TYPE = closedLoop
SCALE = 165
MAX_RPM = 2500
MIN_RPM = 0
STEPGEN_MAXVEL = 120
STEPGEN_MAX_ACCEL = 600
MAX_ERROR = .01
P = 50
I = 0.0
D = 0.0
FF0 = 0.0
FF1 = 0.0
FF2 = 0.0
BIAS = 0.0
DEADBAND = 0.0
MAX_OUTPUT = 2000.0
# these are in nanoseconds
DIRSETUP   = 1000
DIRHOLD    = 1000
STEPLEN    = 1000
STEPSPACE  = 1000


[INPUTS]
# DO NOT change the input text
INPUT_0 = Home
INPUT_JOINT_0 = 0
INPUT_1 = Home
INPUT_JOINT_1 = 1
INPUT_2 = Home
INPUT_JOINT_2 = 2
INPUT_3 = Select
INPUT_JOINT_3 = False
INPUT_4 = Select
INPUT_JOINT_4 = False
INPUT_5 = E-Stop In
INPUT_JOINT_5 = False
INPUT_6 = Home
INPUT_JOINT_6 = False
INPUT_7 = Select
INPUT_JOINT_7 = False
INPUT_8 = Select
INPUT_JOINT_8 = False
INPUT_9 = Select
INPUT_JOINT_9 = False
INPUT_10 = Select
INPUT_JOINT_10 = False

[OUTPUTS]
# DO NOT change the output text
OUTPUT_0 = Spindle CW
OUTPUT_1 = Spindle On
OUTPUT_2 = Spindle CCW
OUTPUT_3 = Select
OUTPUT_4 = Select

[OPTIONS]
MANUAL_TOOL_CHANGE = True
HALUI = False
PYVCP = False
GLADEVCP = False
LADDER = False

Thanks again peter for pointing me in the right direction.

Jools
Attachments:

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

More
06 Dec 2019 12:38 #152152 by andypugh

I tried to add the encoder but when I do again I get faults at start up. The 'loadrt' code is in my hal and references the number of encoders in my ini. This was set by the 7i96 config tool. If I addf encoder.update−counters as below from the manual then I need to add a thread for it to be sampled.


Are you trying to use a software encoder counter or the 7i96 hardware encoder counter?

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

More
11 Dec 2019 16:48 #152487 by jools
Hi Andy
I’ve sorted it now thanks.
It was on the 7i96 but the doc’s didn’t say how to do that in the spindle section. I got there in the end though using other pncconf generated Hal’s and hunting around.

Cheers

Jools

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

Time to create page: 0.092 seconds
Powered by Kunena Forum