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