On Friday 05 March 2021 18:35:19 andy pugh wrote:

> On Fri, 5 Mar 2021 at 23:31, Feral Engineer 
<theferalengin...@gmail.com> wrote:
> > Can someone send me a copypasta of their spindle hal stuff? Pid,
> > ff0,1,2 encoder feedback, all that?
>
> I don't actually run PID on my lathe spindle. I have some moderately
> complex gear selection stuff going on, but otherwise I just trust the
> VFD to do the job.
I don't have a pid loaded in either of my machines that are running a 
vfd. The vfd is stiff enough it doesn't need fawncy controls.

The only reason I have an encoder on the sheldon lathe is for G33.1 and 
G76 support. Both of those slave the z travel to the spindle, what ever 
its running at doesn't change more than 2% under cutting load for G76, 
and maybe 5% for a big tap doing rigid taping. G76 also slaves the x to 
the programmed G76 cutting depth. On the sheldon, a pwmgen feeds a 
spinx1 which controls the vfd. Not even an d/a except the spinx1 because 
I run the pwmgen at a rate thats above the bandwidth of the spinx1.

You get far better results by properly tuning the vfd.  OOTB they suck 
huge dead toads thru soda straws. With a pwmgen getting the speed 
signals from motions spindle output, that pwm fed to the spinx1 along 
with the dir signal, and a bit of hal sequencing, my Sheldon, turning at 
100 revs in high backgear, and low belt position/speed, I can do a rigid 
tap move, and measuring the overshoot at the bottom of the G33.1 move, 
is .25 turns.  That's with a nearly 40 lb 8" 4 jaw chuck mounted.  Who 
needs a pid?

That .hal file is attached. Cherry pick with my blessing.  Sure its a 
rpi4 file, but its running a Sheldon lathe that after stripping the 
stuff linuxcnc doesn't need, and putting in decent ball screws,
still weighs around 1350 lbs.

Stay safe and well, John.

Cheers, Gene Heskett
-- 
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
If we desire respect for the law, we must first make the law respectable.
 - Louis D. Brandeis
Genes Web page <http://geneslinuxbox.net:6309/gene>
###########################################################
# WORKING DOWN FROM THE TOP, THE LAST GPIO IN USE AS OF THIS DATE IS 063 FOR 
VFD-RESET!
# hm2-7i90-stepper.hal version 1.005 a/o above date
# because the 7i90 is damaged, everything is enabled.
# HAL file for HostMot2 with 4 steppers, 4 encoders, 2 pwmgen
# Apparently a blown gpio.00 so x ,is dead, bring up another stepgen
# and use it. 2 was dead also, so 3 is now x Damn the static electricity
# Derived from Ted Hyde's original hm2-servo config
#
# Based up work and discussion with Seb & Peter & Jeff
# GNU license references - insert here. www.linuxcnc.org
# ########################################
# See also:
# 
<http://www.linuxcnc.org/docs/devel/html/man/man9/hostmot2.9.html#config%20modparam>
# and http://wiki.linuxcnc.org/cgi-bin/emcinfo.pl?HostMot2
#
####################
# Core EMC/HAL Loads
####################
# kinematics
loadrt [KINS]KINEMATICS

# motion controller, get name and thread periods from ini file
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD 
num_joints=[KINS]JOINTS

##########################################
# extra, slower thread for jogwheel stuffs at 200Hz
loadrt          threads name1=jog-thread period1=20000000 fp1=1
##########################################
# hostmot2 driver
loadrt hostmot2

# load low-level driver
loadrt  [HOSTMOT2](DRIVER) config=[HOSTMOT2](CONFIG) spi_debug=3 
spiclk_rate=41666 spiclk_rate_rd=25000

# load estop latch component
loadrt  estop_latch count=1

loadusr -W /home/pi/linuxcnc/configs/sheldon-lathe/units.py

# loadrt stuff for g33.1 ovrtrvl
loadrt  sample_hold names=sample-dirchg,sample-spndlchg

# Now my stuff for a steady tach reading
loadrt  lowpass names=spindle-tach-filter,spindle-steady
loadrt  abs 
names=spindle-abs,spindle-tach-unidir,abs.0,abs.1,gear_abs,abs_encdir
loadrt  minmax names=spindle-track,X-axis-track,Z-axis-track
loadrt  scale   names=scale-tach,scale-ovrtrvl
loadrt  near    names=close-enough
loadrt  tristate_bit names=watchdog-reset
loadrt  updown names=updownxcounter,updownzcounter
loadrt  conv_s32_u32    count=2
loadrt  conv_s32_float  names=s32floatx,s32floatz,s32_float_cmd,s32_float_spndl
loadrt  conv_float_s32  names=floats32x,floats32z
loadrt  bitslice names=mux8addrx,mux8addrz personality=3,3
loadrt  mux8 names=mux8jogspeedx,mux8jogspeedz
loadrt  wcomp   names=jogsteerx,jogsteerz
# here I need the module name as its leading portion
loadrt  and2    
names=and2xgainup,and2xgaindown,and2xgate,and2zgainup,and2zgaindown,and2zgate,and2xtoggle,and2ztoggle,Flt-and2-estop
loadrt  mult2   
names=mult2x1,mult2x2,mult2z1,mult2z2,mult2gear,mult2pwm,mult2turns,mult2distance
loadrt  not     names=notjogx,notjogz,FaultXnot,FaultZnot,FHomeNot
# need a jog-disable when adjusting stepsize
loadrt  mux2    names=jogmux2x,jogmux2z,ovrtvl-frz,ovrtrvl-scaler-mux
loadrt  oneshot names=timex,timez,reset-vfd,trig-frz,Fault-kill
loadrt  or2     names=or2xretrig,or2zretrig,FaultorZ,FaultorX
loadrt  edge     names=edgextrig,edgeztrig,wd-bite-reset
loadrt  lut5     
names=lut5xup,lut5xdown,lut5jogx,lut5zup,lut5zdown,lut5jogz,lut5timex,lut5timez
# now track G33.1 overshoot
loadrt  sum2     names=sum2.ovrtrvl
loadrt  lincurve count=2 personality=16
loadrt  offset   count=1
loadrt  limit3   count=1
loadrt  message  names="FaultXmsg","FaultZmsg" messages="Axis X Fault rehome X 
required","Axis Z Fault rehome Z required"
# ################################################
# THREADS
# ################################################

addf    hm2_[HOSTMOT2](BOARD).0.read    servo-thread
addf    wd-bite-reset                   servo-thread
addf    watchdog-reset                  servo-thread
addf    abs_encdir                              servo-thread
addf    s32_float_cmd                   servo-thread
addf    s32_float_spndl                 servo-thread
addf    offset.0.update-feedback servo-thread
addf    motion-command-handler  servo-thread
addf    motion-controller       servo-thread

# for handling faults from 3 phase steppers #
addf    Fault-kill              servo-thread # is a oneshot
addf    FaultorX                                jog-thread # is an or2
addf    FaultorZ                                jog-thread # is an or2
addf    FaultZnot               jog-thread # is a not
addf    FaultXnot                               jog-thread # is a not
addf    Flt-and2-estop                  jog-thread # to combine fasults
addf    FHomeNot                                jog-thread # make the above a 
nand
addf    FaultZmsg                               jog-thread # logic 1 delivers 
msg
addf    FaultXmsg                               jog-thread # ditto

##############################################

addf    spindle-abs                             servo-thread
addf    spindle-tach-unidir             servo-thread
addf    estop-latch.0           servo-thread
addf    scale-tach                              servo-thread
addf    spindle-track                   servo-thread
addf    spindle-tach-filter             servo-thread
addf    X-axis-track                    servo-thread
addf    Z-axis-track                    servo-thread
addf    spindle-steady                  servo-thread
addf    close-enough                    servo-thread
addf    reset-vfd                               servo-thread
# now track spindle overshoot for g33.1
addf    sample-dirchg                   servo-thread
addf    sample-spndlchg                 servo-thread
addf    sum2.ovrtrvl                    servo-thread
addf    trig-frz                                servo-thread
addf    ovrtvl-frz                              servo-thread
addf    mult2turns                              servo-thread
addf    mult2distance                   servo-thread
# offset.0  needs fastest thread
addf    offset.0.update-output  servo-thread
# while a lincurve can be slower
addf    limit3.0                                jog-thread
addf    lincurve.0                              jog-thread
addf    lincurve.1                              jog-thread
# jogwheel stuff
addf    jogsteerx                               jog-thread #j1x
addf    jogsteerz                               jog-thread #j1z
addf    and2xtoggle                             jog-thread #j2x
addf    and2ztoggle                             jog-thread #j2z
addf    edgextrig                               jog-thread #j3x
addf    edgeztrig                               jog-thread #j3z
addf    or2xretrig                              jog-thread #j4x
addf    or2zretrig                              jog-thread #j4z
addf    lut5timex                               jog-thread #j6x
addf    lut5timez                               jog-thread #j6z
addf    timex                                   jog-thread #j5x
addf    timez                                   jog-thread #j5z
addf    lut5xup                                 jog-thread #j6x
addf    lut5zup                                 jog-thread #j6z
addf    lut5xdown                               jog-thread #j6x
addf    lut5zdown                               jog-thread #j6z
addf    lut5jogx                                jog-thread #j6x
addf    lut5jogz                                jog-thread #j6z
addf    and2xgate                               jog-thread #j7x
addf    and2zgate                               jog-thread #j7z
addf    and2xgainup                             jog-thread #j8x
addf    and2xgaindown                   jog-thread #J8x
addf    and2zgainup                             jog-thread #j9z
addf    and2zgaindown                   jog-thread #j9z
addf    notjogx                                 jog-thread #j10x
addf    notjogz                                 jog-thread #j10z
addf    updownxcounter                  jog-thread
addf    updownzcounter                  jog-thread
addf    conv-s32-u32.0                  jog-thread
addf    conv-s32-u32.1                  jog-thread
addf    mux8addrx                               jog-thread
addf    mux8addrz                               jog-thread
addf    mux8jogspeedx                   jog-thread
addf    mux8jogspeedz                   jog-thread
addf    s32floatx                               jog-thread
addf    s32floatz                               jog-thread
addf    mult2x1                                 jog-thread
addf    mult2x2                                 jog-thread
addf    mult2z1                                 jog-thread
addf    mult2z2                                 jog-thread
addf    mult2gear                               jog-thread
addf    mult2pwm                                jog-thread
addf    floats32x                               jog-thread
addf    floats32z                               jog-thread
addf    jogmux2x                                jog-thread
addf    jogmux2z                                jog-thread
addf    scale-ovrtrvl                   jog-thread
addf    ovrtrvl-scaler-mux              jog-thread
# revel in the free time here from not having to run PID's
# every bit of the processing as set by addf order MUST BE DONE
# between the above read, and the below write.
addf hm2_[HOSTMOT2](BOARD).0.write   servo-thread

########################################################
# setup 7i90  board
########################################################
# Turn pulses to true low, opendrain for outputs driving opto's
# stepgen 01 BLOWN
# stepgen 02 BLOWN
# stepgen 00 is Z drive
# stepgen 03 is X drive
setp hm2_[HOSTMOT2](BOARD).0.gpio.000.is_opendrain 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.000.invert_output 0
setp hm2_[HOSTMOT2](BOARD).0.gpio.001.is_opendrain 1
# but resverse dirction of a 3 phase motor now moving Z
setp hm2_[HOSTMOT2](BOARD).0.gpio.001.invert_output 1

setp hm2_[HOSTMOT2](BOARD).0.gpio.018.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.018.is_opendrain 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.019.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.019.is_opendrain 1

# pdmgen outs are also driving opto's
# pwmgen.0
setp hm2_[HOSTMOT2](BOARD).0.gpio.020.invert_output 0 # pdmgen.0 output
setp hm2_[HOSTMOT2](BOARD).0.gpio.020.is_opendrain 1 
setp hm2_[HOSTMOT2](BOARD).0.gpio.021.invert_output 1 # pdmgen.0.dir
setp hm2_[HOSTMOT2](BOARD).0.gpio.021.is_opendrain 1

#################
# home switches #
#################
net     homex   <= hm2_[HOSTMOT2](BOARD).0.gpio.065.in  => joint.0.home-sw-in 
#P3-35
net     homez   <= hm2_[HOSTMOT2](BOARD).0.gpio.064.in  => joint.1.home-sw-in 
#P3-33

########################################################################
# SPINDLE/SpinX1's dir, configure GPIO pin 71, IS P3-47,MARKED i/o-O23 #
########################################################################
setp hm2_[HOSTMOT2](BOARD).0.gpio.071.is_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.071.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.071.is_opendrain 1
# handle'S vfd direction

######################
# more spinx1 inputs #
######################
# Setup vfd drive enable yadda yadda, building down from top down forward first 
#
# The SpinX1 only needs pwm and dir I thought, but needs an ena(ble) too.       
#
# so setup gpio.070 for that, IS P3-45, I/O-022
setp hm2_[HOSTMOT2](BOARD).0.gpio.070.is_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.070.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.070.is_opendrain 1
####################################################
# hook up the SSR's for power, and status buttons etc
####################################################
# need two outputs for the SSR's, assume low enables
# setup the pins for output at P3-43-I/O 021
setp hm2_[HOSTMOT2](BOARD).0.gpio.069.is_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.069.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.069.is_opendrain 1
# and at p3-43, i/o 020
setp hm2_[HOSTMOT2](BOARD).0.gpio.068.is_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.068.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.068.is_opendrain 1

###################################
# gpio.067 is X pushbutton status #
# gpio.066 is Z pushbutton status #
# gpio.064 is Z home, ps-33       #
# gpio's ARE USED FROM TOP DOWN   #
# This, according to the hostmot2 #
# man page, reduceS following errors
# and applies to stepgens enabled #
###################################
setp hm2_[HOSTMOT2](BOARD).0.stepgen.timer-number 1

# with the horrible latency of the rpi, this might need raised
setp hm2_[HOSTMOT2](BOARD).0.dpll.01.timer-us -50
 
#######################################################
# need a place to change jog mode
setp axis.x.jog-vel-mode true
setp axis.z.jog-vel-mode true
# Axis-of-motion Specific Configs (not the GUI)
# X [joint 0] Axis
#######################################################
# axis enable chain
# stepgens 01 AND 02 are damaged
net emcmot.00.enable <= joint.0.amp-enable-out # is X
net emcmot.00.enable => hm2_[HOSTMOT2](BOARD).0.stepgen.03.enable
net emcmot.01.enable <= joint.1.amp-enable-out # is Z
net emcmot.01.enable => hm2_[HOSTMOT2](BOARD).0.stepgen.00.enable


########################################################
# display msg, unhome if either drive in fault 
# hm2_7i90.0:     IO Pin 061 (P3-31): IOPort for FaultZ
# hm2_7i90.0:     IO Pin 060 (P3-29): IOPort for FaultX
# is lowest numbered gpio used yet a/o 9/13/20
setp Fault-kill.width  0.750000000  # cover powerup glitch. it takes
# driver a half second to kill the fail output after power up
setp FaultZmsg.edge true
setp FaultXmsg.edge true
net motor-power <= motion.motion-enabled => Fault-kill.in #triggers oneshot to 
cover powerup glitch
net Fault-killer <= Fault-kill.out => FaultorZ.in0 FaultorX.in0 # are an or2
net FaultZ-in   <= hm2_[HOSTMOT2](BOARD).0.gpio.061.in => FaultorZ.in1 # is the 
other input of an or2
net FaultX-in   <= hm2_[HOSTMOT2](BOARD).0.gpio.060.in => FaultorX.in1 # is the 
other input of an or2
net FaultZ-trip         <= FaultorZ.out  => FaultZnot.in Flt-and2-estop.in0
net FaultZrst       <= FaultZnot.out => FaultZmsg.trigger
net FaultX-trip         <= FaultorX.out  => FaultXnot.in Flt-and2-estop.in1
net FaultXrst           <= FaultXnot.out => FaultXmsg.trigger
net FrstHome            <= Flt-and2-estop.out => FHomeNot.in
net EStopAll            <= FHomeNot.out => halui.estop.activate


#######################################################
# X position command and feedback, x is on stepgen #3 #
# due to prev card failure, not moved back, config &  #
# wiring not corrected when board replaced. GH.       #
#######################################################
# do bedwear hookups     #
# Z=joint.1 = stepgen.00 #
# X=joint.0 = stepgen.03 #
##########################
# lincurve needs input from Z position
# 1st, drive the Z motor from motion.0.joint.1.pos-cmd
net     Zdrive  <= joint.1.motor-pos-cmd  => 
hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-cmd
# watch bwZ to see if it moves DOES
# now route feedback back to motion
net             bwZ             <=      
hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-fb => joint.1.motor-pos-fb
# now send real Z position to lincurve.0.in
net     Zactual <= joint.1.pos-cmd => lincurve.0.in Z-axis-track.in 
#limit3.0.in 
#net ZactualSlow        limit3.0.out lincurve.0.in Z-axis-track.in
# lincurve.0.in is Z's position, slowed to make it subject to speed 
# limits when Z offset is applied
# so now send lincurve.0.out to X via offset.0.offset
#setp offset.0.offset 0.00000
setp limit3.0.maxa .015
setp limit3.0.smooth-steps 3 
net     bwX0    <=      lincurve.0.out  => limit3.0.in # to speed limit it for 
following error control 
net     bwx1    <=  limit3.0.out   => offset.0.offset # is desired offset, 
slowed
# that gets us the X correction factor out of Z's position
# motor-pos-cmd dummy!
net             bwX2    <=      joint.0.motor-pos-cmd   => offset.0.in
# send the offset diddled x to driver cmd 
net     bwX3    <=  offset.0.out        =>  
hm2_[HOSTMOT2](BOARD).0.stepgen.03.position-cmd
# now get its resultant position & send it to offset0,fb-pin
net     bwX4    <=  hm2_[HOSTMOT2](BOARD).0.stepgen.03.position-fb  =>  
offset.0.fb-in
# feed offset removed motor postion back to motion
net     bwX5    <=      offset.0.fb-out =>      joint.0.motor-pos-fb # result 
from motion
net             bwX6    =>      X-axis-track.in # and to X-track.in
###################################################
# X axis jogwheel setup, this is X jog step size! #
# X encoder A is brn of brn/white pair
# X encoder B is brn/white of same pair.
# X pushbutton, gpio 066 contact to ground, when pushed is blu of blu/white pair
# but separate this stuff so I can track it with my fading mind
# so lets do ALL the jog button pressed stuff first to drive the axis(x|z).scale
#####################################################
setp    hm2_[HOSTMOT2](BOARD).0.encoder.01.scale 4 # what for, doesn't seem to 
work!
# jogsteerx is a wcomp, detects wheel direction
net             jogwcomp-x      <= hm2_[HOSTMOT2](BOARD).0.encoder.01.velocity  
=> jogsteerx.in
# set a small deadband in the wcomp since one click shows 20+ at velocity output
setp    jogsteerx.min -0.5
setp    jogsteerx.max  0.5
# now we have direction at jogsteerx.over and jogsteerx.under
net     pulsexup        <= jogsteerx.over # establish these signals
net             pulsexdown      <= jogsteerx.under
# first, an and2 to detect rising edge of and2 overlap
net             xAtoggle        <= hm2_[HOSTMOT2](BOARD).0.encoder.01.input-a 
=> and2xtoggle.in0
net             xBtoggle        <= hm2_[HOSTMOT2](BOARD).0.encoder.01.input-b 
=> and2xtoggle.in1
net             xtoggleout      <= and2xtoggle.out # want rising edge!
# now I have, at xtoggleout, a nominally 25% duty cycle high, pulse, we trigger 
on rising edge
# now collect button status and make initial trigger pulse out of it on rising 
edge.

net     buttonxdown     <= hm2_[HOSTMOT2](BOARD).0.gpio.066.in => edgextrig.in
net     timexreset      <=      hm2_[HOSTMOT2](BOARD).0.gpio.066.in_not =>      
timex.reset
 
setp    edgextrig.in-edge false
setp    edgextrig.out-width-ns 10000
net             xtrig0          <=  edgextrig.out  => or2xretrig.in0 # true 
pulse as released
######################################
# set up the oneshot for dial timeout
######################################
setp    timex.rising    true #default
setp    timex.falling   false #default
setp    timex.width             300.0 #hm2_[JOINT_0]JOG_TIMEOUT
# setup a lut5 to retrigger timex or timez
setp    lut5timex.function 0x80 # 5 input gate using 3, 0 invertd
net             xtoggleout      => lut5timex.in-0 # string of + pulses as dial 
turns
net             buttonxdown     => lut5timex.in-1 # true when released
net             xtimedout       <= timex.out => lut5timex.in-2 # true while 
oneshot running, kills retrig path when timed out
net             buttontimex     <= lut5timex.out  => or2xretrig.in1 # s/b train 
of + pulses, retriggers on rising edge
net             xretrigger      <= or2xretrig.out => timex.in # combined 
initial + pulse trigger to retrigger timex
######################### Jog size, up ###########################
# now lets use a couple lut5's to establish the jogsize (x/z) pulses 
upcount,downcount
setp    lut5xup.function 0x400          # 5 input and gate using 4
net             xtimedout       => lut5xup.in-0 # true while oneshot running
net             pulsexup        => lut5xup.in-1 # true if upcount
net             buttonxdown     => lut5xup.in-2 # false for this
net             xtoggleout      => lut5xup.in-3 # train of pulses while dial 
turns
###################################################################
# should give a true pulse to upcounterx when input is 1,1,0,1 are true, do 
same for downcount
############ Jog size, down #######################################
setp    lut5xdown.function 0x400 # 5 input # and gate 2 inverted
net             xtimedout       => lut5xdown.in-0
net             pulsexdown      => lut5xdown.in-1
net             buttonxdown     => lut5xdown.in-2 # false for this
net             xtoggleout      => lut5xdown.in-3
##################################################################
# should give a downcount true pulse for the updownxcounter when button is 
pushed
################### Drive the X counter ##########################
setp    updownxcounter.min      0
setp    updownxcounter.max      5
setp    updownxcounter.clamp    1 # so it cannot zero wrap
net             xgaindirup              <= lut5xup.out          => 
updownxcounter.countup
net             xgaindirdown    <= lut5xdown.out        => 
updownxcounter.countdown
############### works to here, both x and z ###############
net             xtimedout               => axis.x.jog-enable joint.0.jog-enable 
# needs logic high IIRC
net             no-xjog                 <= timex.out-not => 
hm2_[HOSTMOT2](BOARD).0.encoder.01.reset  #true=active reset after timeout
# now updown's output is an s32, so we make a u32 out of it, feed a bitslice 
and call its mux8addrx
# and feed the updowns s32 to it, clamp so it will not wrap.
setp    conv-s32-u32.0.clamp    1 # belt and suspenders approach, updown is 
also limited
net             xaddrdecode0    <= updownxcounter.count => conv-s32-u32.0.in
# this mux8addr is actually a bitslice
net     xaddrdecode1    <= conv-s32-u32.0.out   => mux8addrx.in
# now we have 3 address lines to drive the 3 sel's of a mux8
net             mux8x0  mux8addrx.out-00        mux8jogspeedx.sel0
net             mux8x1  mux8addrx.out-01        mux8jogspeedx.sel1
net             mux8x2  mux8addrx.out-02        mux8jogspeedx.sel2
# addresses delivered. now set gain steps
# doing the scaling here, and the output can be displayed by pyvcp
setp    mux8jogspeedx.in0       .0001
setp    mux8jogspeedx.in1       .0002
setp    mux8jogspeedx.in2       .0005
setp    mux8jogspeedx.in3       .0010
setp    mux8jogspeedx.in4       .0020
setp    mux8jogspeedx.in5       .0050
setp    mux8jogspeedx.in6       .0100
setp    mux8jogspeedx.in7       .0200
# now, check mux8jogspeedx.out, good, now send mux8jogspeedx.out to multx1.in1
# but still needs a 2nd mult2, one to scale to mux8jogspeedx.out,
# and one to apply the scale to the encoder.count
# is the button pushed? figure this out for gpio pin assign later
# for now, use halshow to setp the 2 ands
# and finally, if button not pushed
net             jogxsize   <=  mux8jogspeedx.out => axis.x.jog-scale 
joint.0.jog-scale
################################
# now do the actual X jog stuffs #
################################
net             xjogdials32    <=  hm2_[HOSTMOT2](BOARD).0.encoder.01.count => 
s32floatx.in
net             xjogdialflt    <=  s32floatx.out  => mult2x1.in0
# times .250000000 to get one count/click
setp    mult2x1.in1 0.25000000
net     jogx2axis               <= mult2x1.out    => jogmux2x.in1
setp    jogmux2x.in0    0.00000000000
net             xtimedout               => jogmux2x.sel # this net got lost too
net             jog-mux2x0      <= jogmux2x.out  => floats32x.in
net             jog-mux2x1      <= floats32x.out => joint.0.jog-counts 
axis.x.jog-counts
##########################################################################
# end of z copy source above
##########################################################################
# X timing parameters
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.dirhold      [JOINT_0]DIRHOLD
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.dirsetup     [JOINT_0]DIRSETUP
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.steplen      [JOINT_0]STEPLEN
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.stepspace    [JOINT_0]STEPSPACE
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.position-scale  [JOINT_0]SCALE
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.maxvel               
[JOINT_0]STEPGEN_MAX_VEL
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.maxaccel     [JOINT_0]STEPGEN_MAX_ACC
setp    hm2_[HOSTMOT2](BOARD).0.stepgen.03.step_type    0

###################################################
# Z [1] Axis is now on stepgen #00 as I couldn't see steps from #01
###################################################
# Z position command, feedback and bedwearcmd's Z pos reference
# net emcmot.01.pos-cmd         <= joint.1.motor-pos-cmd
# net emcmot.01.pos-cmd         => 
hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-cmd
# net motor.01.pos-fb   <= hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-fb
# net motor.01.pos-fb           => joint.1.motor-pos-fb Z-axis-track.in
# axis enable chain
# newsig emcmot.01.enable bit
net emcmot.01.enable    <= joint.1.amp-enable-out
net emcmot.01.enable    => hm2_[HOSTMOT2](BOARD).0.stepgen.00.enable
###########################################################
# Z jog dial
###########################################################
# Z axis jogwheel setup, this is jog step size!
# Z encoder A is brn of brn/white pair
# Z encoder B is brn/white of same pair.
# Z pushbutton, gpio 067 contact to ground, when pushed is blu of blu/white pair
# but separate this stuff so I can track it with my fading mind
# so lets do ALL the jog button pressed stuff first to drive the axis(x|z).scale
###########################################################
setp    hm2_[HOSTMOT2](BOARD).0.encoder.03.scale 4 # what for, doesn't seem to 
work!
# jogsteerz is a wcomp, detects wheel direction
net             jogwcomp-z      <= hm2_[HOSTMOT2](BOARD).0.encoder.03.velocity  
=> jogsteerz.in
# set a small deadband in the wcomp since one click shows 20+ at velocity output
setp    jogsteerz.min -0.5
setp    jogsteerz.max  0.5
# now we have direction at jogsteerz.over and jogsteerz.under which is the 
first thing we need
# first, an and2 to detect falling edge of and2
net             zAtoggle        <= hm2_[HOSTMOT2](BOARD).0.encoder.03.input-a 
=> and2ztoggle.in0
net             zBtoggle        <= hm2_[HOSTMOT2](BOARD).0.encoder.03.input-b 
=> and2ztoggle.in1
net             ztoggleout      <= and2ztoggle.out # want falling edge!
# now I have, at ztoggleout, a nominally 25% duty cycle high, pulse, we trigger 
on falling edge
# now collect button status mand make initial trigger edge out of it on rising 
edge
setp    edgeztrig.in-edge       false

net     buttonzdown     <= hm2_[HOSTMOT2](BOARD).0.gpio.067.in => edgeztrig.in
net             timezreset      <=      hm2_[HOSTMOT2](BOARD).0.gpio.067.in_not 
=>      timez.reset

setp    edgeztrig.out-width-ns 10000
net             ztrig0          <= edgeztrig.out => or2zretrig.in0 # true when 
released
##########################################################
# set up the oneshot for dial timeout
setp    timez.rising    false
setp    timez.falling   true
setp    timez.width             300.0 #hm2_[JOINT_1]JOG_TIMEOUT
# setup a lut5 to retrigger timex or timez
setp    lut5timez.function      0x80
net     ztoggleout      => lut5timez.in-0
net             buttonzdown     => lut5timez.in-1
net             ztimedout       <= timez.out            => lut5timez.in-2
net             buttontimez     <= lut5timez.out        => or2zretrig.in1
net             zretrigger      <= or2zretrig.out       => timez.in # combined 
retriggers

############ Jog size, up ###########################
# now lets use a couple lut5's to establish the jogsize (x/z) pulses 
upcount,downcount
setp    lut5zup.function 0x400 # 5 input and gate using 4
net             ztimedout       => lut5zup.in-0
net             pulsezup        <= jogsteerz.over => lut5zup.in-1
net             buttonzdown     => lut5zup.in-2 # false for this
net             ztoggleout      => lut5zup.in-3
# should give a true pulse to upcounterx when input is 1,1,0,1 are true, do 
same for downcount
############ Jog size, down #########################
setp    lut5zdown.function 0x400 # 5 input # and gate 2 inverted
net             ztimedout       => lut5zdown.in-0
net             pulsezdown      <= jogsteerz.under => lut5zdown.in-1
net             buttonzdown     => lut5zdown.in-2 # false for this
net             ztoggleout      => lut5zdown.in-3

# should give a downcount true pulse for the updownzcounter when button is 
pushed
################### Drive the counter ##########################
setp    updownzcounter.min      0
setp    updownzcounter.max      5
setp    updownzcounter.clamp    1
net             zgaindirup              <= lut5zup.out          => 
updownzcounter.countup
net             zgaindirdown    <= lut5zdown.out        => 
updownzcounter.countdown

# works to here, both x and z.
net             ztimedout       => axis.z.jog-enable joint.1.jog-enable # needs 
logic high IIRC
net     no-zjog <= timez.out-not        => 
hm2_[HOSTMOT2](BOARD).0.encoder.03.reset # true is reset after timez ending
# now updown's output is an s32, so we make a u32 out of it, feed a bitslice 
and call its mux8ddrz
# and feed the updowns s32 to it, clamp so it will not wrap.
setp    conv-s32-u32.1.clamp    1
net             zaddrdecode0    <= updownzcounter.count => conv-s32-u32.1.in
# this mux8addrz is actually a bitslice
net     zaddrdecode1    <= conv-s32-u32.1.out   => mux8addrz.in
# now we have 3 address lines to drive the 3 sel's of a mux8
net             mux8z0  mux8addrz.out-00        mux8jogspeedz.sel0
net             mux8z1  mux8addrz.out-01        mux8jogspeedz.sel1
net             mux8z2  mux8addrz.out-02        mux8jogspeedz.sel2
# addresses delivered. now set gain steps
# doing the scaling here, and the output can be displayed by pyvcp
setp    mux8jogspeedz.in0       .0001
setp    mux8jogspeedz.in1       .0002
setp    mux8jogspeedz.in2       .0005
setp    mux8jogspeedz.in3       .0010
setp    mux8jogspeedz.in4       .0020
setp    mux8jogspeedz.in5       .0050
setp    mux8jogspeedz.in6       .0100
setp    mux8jogspeedz.in7       .0200
# now, check mux8jogspeedz.out, good, now send mux8jogspeedz.out to mult2z1.in1
# but still needs a 2nd mult2, one to scale to mux8jogspeedz.out,
# and one to apply the scale to the encoder.count
# is the button pushed? figure this out for gpio pin assign later
# for now, use halshow to setp the 2 ands
# and finally, if button not pushed
net             jogzsize   <=  mux8jogspeedz.out => axis.z.jog-scale 
joint.1.jog-scale
# measure here
##########################################################
# now do the actual jog stuffs
##########################################################
net             zjogdials32    <=  hm2_[HOSTMOT2](BOARD).0.encoder.03.count => 
s32floatz.in
net             zlogdialflt    <=  s32floatz.out   => mult2z1.in0
# times .250000000 to get one count/click
setp    mult2z1.in1 0.25000000
net     jogz2axis  <= mult2z1.out    => jogmux2z.in1
setp    jogmux2z.in0 0.00000000000
net             ztimedout       => jogmux2z.sel
net             jog-mux2z0  <= jogmux2z.out => floats32z.in
net             jog-mux2z1  <= floats32z.out => joint.1.jog-counts 
axis.z.jog-counts
############ End of z jog ############################

# Z timing parameters now on stepgen #00
########################################
# stepgen 00 is Z drive
setp hm2_[HOSTMOT2](BOARD).0.gpio.000.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.000.is_opendrain  1
setp hm2_[HOSTMOT2](BOARD).0.gpio.001.invert_output 1
setp hm2_[HOSTMOT2](BOARD).0.gpio.001.is_opendrain  1
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.dirsetup        [JOINT_1]DIRSETUP
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.dirhold         [JOINT_1]DIRHOLD
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.steplen         [JOINT_1]STEPLEN
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.stepspace       [JOINT_1]STEPSPACE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.position-scale  [JOINT_1]SCALE
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.maxvel          [JOINT_1]STEPGEN_MAX_VEL
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.maxaccel        [JOINT_1]STEPGEN_MAX_ACC
setp hm2_[HOSTMOT2](BOARD).0.stepgen.00.step_type       0


# this is the green jumper wire from the SpinX1, to 7i90-p3-47
net reverse-vfd <= spindle.0.reverse => hm2_[HOSTMOT2](BOARD).0.gpio.071.out 
sample-dirchg.hold

# net line moved to be combined with enable_vfd below

##############################################################
# Hook pwmgen.00  and 01 to the spindle speed and set for PDM output #
##############################################################
setp    hm2_[HOSTMOT2](BOARD).0.pwmgen.00.scale                 
[SPINDLE_9]PWMGEN_S_SCALE
setp    hm2_[HOSTMOT2](BOARD).0.pwmgen.pwm_frequency    [SPINDLE_9]PWMGEN_S_FREQ
setp    hm2_[HOSTMOT2](BOARD).0.pwmgen.00.output-type   
[SPINDLE_9]PWMGEN_OUTPUT_TYPE
setp    hm2_[HOSTMOT2](BOARD).0.pwmgen.pdm_frequency    
[SPINDLE_9]PDMGEN_PDM_FREQUENCY

#################################################################
# make vfd pwm drive unidirectional, fwd/rev handles that       #
# but the SpinX1 needs a DIR, which is now on P1-43             #
#################################################################
net     spindle-vel-cmd-rps <=  spindle.0.speed-out-rps  =>     spindle-abs.in
# this comes out on P1-41 as the pulse Duration Modulated signal to the SpinX1, 
red jumper
net             spindle-unispeed        <=      spindle-abs.out
net             spindle-unispeed        =>      
hm2_[HOSTMOT2](BOARD).0.pwmgen.00.value

# SpinX1 enable is P3 pin 45 purple jumper from ENA on SpinX1
# feed both pwmgens to see if one is good in this 7i90
net     enable_vfd      <=  spindle.0.on
net     enable_vfd  =>  hm2_[HOSTMOT2](BOARD).0.pwmgen.00.enable
net     enable_vfd  =>  hm2_[HOSTMOT2](BOARD).0.gpio.070.out # works!

#################################################
# setup encoder to make sense                                   #
#################################################
# I think it s/b showing rps now
setp    hm2_[HOSTMOT2](BOARD).0.encoder.00.scale [SPINDLE_9]ENCODER_S_SCALE
# for g33.1, spindle.0.revs needs to be hooked to encoder.0.position.out
# this isn't right but whats wrong? Works
net     gee33dot1       <= hm2_[HOSTMOT2](BOARD).0.encoder.00.position  =>      
spindle.0.revs

# and index-enable needs to be enabled
setp    hm2_[HOSTMOT2](BOARD).0.encoder.00.index-enable      true
# and then hooked up bidirectional to spindle.0.index-enable
net             spndl_index_enable      <=      
hm2_[HOSTMOT2](BOARD).0.encoder.00.index-enable <=> spindle.0.index-enable

####################################################
# hook up the spindle minmax, first make rpms then an at-speed signal
####################################################
setp    scale-tach.gain 60
net             spindle-RPS <= hm2_[HOSTMOT2](BOARD).0.encoder.00.velocity => 
scale-tach.in

# But we need an RPS feed to spindle.0.speed-in for G33
net     spindle-RPS => spindle.0.speed-in abs_encdir.in
# and it took a while to find the missing abs_encdir.in link above
# now we have rpms at scale-tach.out
net             track-spindle-var1 <= scale-tach.out => spindle-tach-unidir.in
net             spindle-tach-unidir <= spindle-tach-unidir.out => 
spindle-track.in spindle-tach-filter.in
# still have rpms. next is 2 lowpass's
setp    spindle-tach-filter.gain        .050
setp    spindle-steady.gain             .050
# this is a near module
setp    close-enough.scale              1.000
setp    close-enough.difference  10.0
net             motion-spindle-speed    <= spindle-tach-filter.out => 
spindle-steady.in 
net spindle.0.at-speed-in  <= spindle.0.speed-out => close-enough.in1
net             steady-spindle-speed    <= spindle-steady.out => 
close-enough.in2
net             spindle-at-speed        <= close-enough.out  => 
spindle.0.at-speed
# Look at results with two halmeters this stuff is temporary
# and lets use the flood pin to reset the minmax. This does not zero it,
# but makes it a pass-thru when the flood is on
net     spindle-minmax <= iocontrol.0.coolant-flood
net             spindle-minmax => spindle-track.reset X-axis-track.reset 
Z-axis-track.reset

# X HIGH LIMIT IS SOFT LIMIT set 10 THOU INWARD FROM HOME SWITCH
# X LOW LIMIT IS A SOFT LIMIT set to try & keep slot in saddle covered
# THEN GPIO .066 FOR Z HOME at p3-37
# THEN GPIO .065 FOR Z HIGH LIMIT at p3-35

#net    motor-power     <=      motion.motion-enabled
# This is the yellow and green wires in the trailer wire to the 6x6x box on top
# the corresponding wire of the pair is +5 to the SSR + terminals, fed 5 volts
# from terminal strip just under the entry hole in the box, which has 5 volts 
and grounds on it.
# and to the - control terminals of the SSR's in it. To P3-41 and 43
net     motor-power =>  hm2_[HOSTMOT2](BOARD).0.gpio.069.out
net     motor-power     =>      hm2_[HOSTMOT2](BOARD).0.gpio.068.out
# Now, lets reset the vfd too.
setp    reset-vfd.width 0.4 #seconds
setp    reset-vfd.falling false
setp    reset-vfd.rising true
net     motor-power     =>      reset-vfd.in
net     vfd-reset       <=  reset-vfd.out-not
# I lost track, 064 is an input for z-home so move down to 063 for this
setp    hm2_[HOSTMOT2](BOARD).0.gpio.063.is_output 1
setp    hm2_[HOSTMOT2](BOARD).0.gpio.063.is_opendrain 1
net     vfd-reset   => hm2_[HOSTMOT2](BOARD).0.gpio.063.out #p3-031
# should enable motor power, everything hooked up in postgui.hal

# calculate spindle reversal overshoot
setp    sum2.ovrtrvl.gain0      -1.000000000 # make sub2 out of sum2
# feed accumulated counts to both sample-holds
net     ovrtrvl1        <=      hm2_[HOSTMOT2](BOARD).0.encoder.00.count
# Feed both sample-holds
net             ovrtrvl1        =>      sample-dirchg.in   #checks
net     ovrtrvl1        =>      sample-spndlchg.in #checks

net     spindle-is-reversed     <=      abs_encdir.is-negative  =>      
sample-spndlchg.hold # checks
# that takes care of measuring reversal distance, HOWEVER, it also measures the 
other end
# of the travel, so the halmeter jumps to a higher value at the end of the 
retract move as it
# reverses to fwd again. SO KEEP THAT IN MIND! Better yet, make a held value 
thats updated
net             ovrtrvl2                        <=      sample-dirchg.out       
        =>      s32_float_cmd.in # checks
net             ovrtrvl3                        <=      s32_float_cmd.out       
        =>      sum2.ovrtrvl.in0 # checks
net             ovrtrvl4                        <=      sample-spndlchg.out     
        =>      s32_float_spndl.in # checks
net             ovrtrvl5                        <=      s32_float_spndl.out     
        =>      sum2.ovrtrvl.in1 # checks
# make a sample-hold out of a mux2
net     ovrtrvl6                        <=      sum2.ovrtrvl.out        =>      
ovrtvl-frz.in1
net             ovrtrvl6a                       <=      ovrtvl-frz.out  =>      
ovrtvl-frz.in0
# now we need a ovrtvl-frz.sel <= trig.frz signal
net             spindle-is-reversed     => trig-frz.in
setp    trig-frz.width          0.25
net             holdovrtvl                      <= trig-frz.out ovrtvl-frz.sel

# ovrtvl-frz.out can be watched with a halmeter, is in encoder counts, works
# next we need a mult2 to make turns of spindle out of this
# first, feed reciprical of encoder counts to in0
# this is hard coded reciprical of encoder scale
setp    mult2turns.in0 0.0041666666666666667
net     ovrtrvl6a => mult2turns.in1
# now mult2turns.out s/b spindle turns
net     makedist0       <= motion.analog-out-00 => mult2distance.in0
net     makedist1       <= mult2turns.out mult2distance.in1
net     showdist        <= mult2distance.out # should feed pyvcp.ovrtvldist 
does and works
net             showdist    => motion.analog-in-01
# the above net doesn't work
setp    hm2_7i90.0.watchdog.timeout_ns 20000000
net     clearwd hm2_7i90.0.watchdog.has_bit
sets    clearwd false 

##########################
# now do bedwear offsets #
##########################

# this will need a zero point -n the - territory, incrementing by 2.25" per step
setp    lincurve.0.x-val-00     -3.500 #  way off don't try until nut moved
setp    lincurve.0.x-val-01     -1.0   #0
setp    lincurve.0.x-val-02     -0.50
setp    lincurve.0.x-val-03              0.00
setp    lincurve.0.x-val-04      0.50
setp    lincurve.0.x-val-05      1.00000
setp    lincurve.0.x-val-06              1.50000
setp    lincurve.0.x-val-07              2.00000
setp    lincurve.0.x-val-08              2.50000 
setp    lincurve.0.x-val-09              3.00000
setp    lincurve.0.x-val-10              4.00000
setp    lincurve.0.x-val-11              6.00000
setp    lincurve.0.x-val-12              9.00000
setp    lincurve.0.x-val-13             12.00000
setp    lincurve.0.x-val-14             15.000
setp    lincurve.0.x-val-15             24.500   # tailstock face
# The above is longer than my calibration rod!
# now do output corrections
setp    lincurve.0.y-val-00             -0.00000000 #-3.5000
setp    lincurve.0.y-val-01      0.00080000 #-1.0000
setp    lincurve.0.y-val-02      0.00000000 #-0.5000
setp    lincurve.0.y-val-03     -0.00020000 # 0.0000
setp    lincurve.0.y-val-04          0.00000000 #+0.5000
setp    lincurve.0.y-val-05             -0.00060000 #+1.0000
setp    lincurve.0.y-val-06      0.00030000 #+1.5000
setp    lincurve.0.y-val-07     -0.00000000 #+2.0000
setp    lincurve.0.y-val-08      0.00220000 #+2.5000
setp    lincurve.0.y-val-09             -0.00190000 #+3.0000
setp    lincurve.0.y-val-10             -0.00260000 #+4.0000
setp    lincurve.0.y-val-11      0.00060000 #+6.0000
setp    lincurve.0.y-val-12      0.00050000 #+9.0000
setp    lincurve.0.y-val-13      0.00030000 #+12.000
setp    lincurve.0.y-val-14              0.00000000 #+15.000
setp    lincurve.0.y-val-15     -0.00140000 #+24.000
#add more steps as needed above
# ##################################################
# Standard I/O Block - EStop, Etc
# ##################################################
setp    estop-latch.0.ok-in true
#setp watchdog-reset.in false
# A basic estop loop that only includes the hostmot watchdog.
# reset from machine-enable button
net     user-enable     <=      iocontrol.0.user-request-enable =>      
estop-latch.0.reset
net     enable-latch    <=      estop-latch.0.ok-out    =>      
iocontrol.0.emc-enable-in

################################################
# create signals for tool loading loopback
################################################
unlinkp iocontrol.0.tool-change
unlinkp iocontrol.0.tool-changed

loadusr -W hal_manualtoolchange
net     tool-change-request     iocontrol.0.tool-change       =>  
hal_manualtoolchange.change
net     tool-change-confirmed   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
_______________________________________________
Emc-users mailing list
Emc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/emc-users

Reply via email to