# ============================================================================ # Lagun milling machine - Main HAL configuration # Generated by PNCconf at Fri Jul 26 13:18:08 2024 # Using LinuxCNC version: Master (2.9) # If you make changes to this file, they will be # overwritten when you run PNCconf again # ============================================================================ # --- Load realtime modules --- loadrt [KINS]KINEMATICS loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS base_thread_fp=1 loadrt hostmot2 loadrt hm2_pci config="num_encoders=6 num_pwmgens=6" # mux16: used by pendant for jog increment, feed override, max velocity override, spindle override loadrt mux16 names=jogincr,foincr,mvoincr,soincr # mux2: selects ferror value based on z-override state (attempted but unused) loadrt mux2 count=1 # sum2: sums dual PID outputs for X(0), Y(1), Z(2) loadrt sum2 count=3 # logic: 2-input AND gate for z-override mechanism # personality 0x0102 = 1 output, 2 inputs, AND function loadrt logic count=1 personality=0x0102 addf logic.0 servo-thread addf mux2.0 servo-thread # weighted_sum: for ADC reading (currently unused) loadrt weighted_sum wsum_sizes=8 #wsum_sizes=[128,64,32,16,8,4,2,1] # default should do conversion?? addf process_wsums servo-thread addf sum2.0 servo-thread addf sum2.1 servo-thread addf sum2.2 servo-thread addf jogincr servo-thread addf foincr servo-thread addf mvoincr servo-thread addf soincr servo-thread # --- Mesa 5i24 global PWM/watchdog settings --- setp hm2_5i24.0.pwmgen.pwm_frequency 15500 setp hm2_5i24.0.pwmgen.pdm_frequency 15500 setp hm2_5i24.0.watchdog.timeout_ns 5000000 # --- Load PID controllers --- # pid.x / pid.xl = X motor encoder / linear scale (dual loop) # pid.y / pid.yl = Y motor encoder / linear scale (dual loop) # pid.zl = Z linear scale (single loop, no motor encoder) # pid.s = spindle (not actively used) loadrt pid names=pid.x,pid.y,pid.s,pid.xl,pid.yl,pid.zl # --- Servo thread function execution order --- addf hm2_5i24.0.read servo-thread addf motion-command-handler servo-thread addf motion-controller servo-thread addf pid.x.do-pid-calcs servo-thread addf pid.xl.do-pid-calcs servo-thread addf pid.y.do-pid-calcs servo-thread addf pid.yl.do-pid-calcs servo-thread addf pid.zl.do-pid-calcs servo-thread addf pid.s.do-pid-calcs servo-thread addf hm2_5i24.0.write servo-thread # --- GPIO relay outputs (active low / inverted) --- # GPIO 041 = spindle on/off relay # GPIO 044 = Z-axis servo enable relay # GPIO 046 = X-axis servo enable relay setp hm2_5i24.0.gpio.041.is_output true setp hm2_5i24.0.gpio.044.is_output true setp hm2_5i24.0.gpio.046.is_output true setp hm2_5i24.0.gpio.041.invert_output true setp hm2_5i24.0.gpio.044.invert_output true setp hm2_5i24.0.gpio.046.invert_output true # --- GPIO button inputs (active low, not all wired into HAL logic) --- # GPIO 029 = ESTOP, 030 = START, 031 = STOP setp hm2_5i24.0.gpio.027.is_output false setp hm2_5i24.0.gpio.028.is_output false setp hm2_5i24.0.gpio.029.is_output false # ESTOP setp hm2_5i24.0.gpio.030.is_output false # START setp hm2_5i24.0.gpio.031.is_output false # STOP # Button wiring attempts - commented out, caused machine to shut off unexpectedly #net machine_estop_out <= hm2_5i24.0.gpio.029.in_not #net machine_estop_out => halui.machine.on # This stuff should work but it seems to be shutting off the machine. # net btn-estop-out hm2_5i24.0.gpio.029.in_not => halui.machine.on # net btn-estop-in hm2_5i24.0.gpio.029.in => halui.machine.off # net btn-pause hm2_5i24.0.gpio.031.in_not => halui.program.pause # net btn-start hm2_5i24.0.gpio.030.in_not => halui.program.run # net btn-start hm2_5i24.0.gpio.030.in_not => halui.program.resume # --- ADC inputs (commented out, unused) --- # first ADC (GPIO 032-039) #setp hm2_5i24.0.gpio.032.is_output false #setp hm2_5i24.0.gpio.033.is_output false #setp hm2_5i24.0.gpio.034.is_output false #setp hm2_5i24.0.gpio.035.is_output false #setp hm2_5i24.0.gpio.036.is_output false #setp hm2_5i24.0.gpio.037.is_output false #setp hm2_5i24.0.gpio.038.is_output false #setp hm2_5i24.0.gpio.039.is_output false # second ADC (GPIO 040-047) #setp hm2_5i24.0.gpio.040.is_output false #setp hm2_5i24.0.gpio.041.is_output false #setp hm2_5i24.0.gpio.042.is_output false #setp hm2_5i24.0.gpio.043.is_output false #setp hm2_5i24.0.gpio.044.is_output false #setp hm2_5i24.0.gpio.045.is_output false #setp hm2_5i24.0.gpio.046.is_output false #setp hm2_5i24.0.gpio.047.is_output false # weighted_sum wiring for ADC (unused) #net hm2_5i24.0.gpio.032 <= wsum.0.bit.0.in #net hm2_5i24.0.gpio.033 <= wsum.0.bit.1.in #net hm2_5i24.0.gpio.034 <= wsum.0.bit.2.in #net hm2_5i24.0.gpio.035 <= wsum.0.bit.3.in #net hm2_5i24.0.gpio.036 <= wsum.0.bit.4.in #net hm2_5i24.0.gpio.037 <= wsum.0.bit.5.in #net hm2_5i24.0.gpio.038 <= wsum.0.bit.6.in #net hm2_5i24.0.gpio.039 <= wsum.0.bit.7.in # ============================================================================ # AXIS X - JOINT 0 # Dual PID: pid.x (motor encoder) + pid.xl (linear scale), summed via sum2.0 # Motor encoder: hm2 encoder 03 # Linear scale: hm2 encoder 00 # PWM output: pwmgen.00 # Enable relay: GPIO 046 (active low) # ============================================================================ # --- X motor encoder PID (velocity/damping loop) --- setp pid.x.Pgain [JOINT_0]P setp pid.x.Igain 0 setp pid.x.Dgain [JOINT_0]D setp pid.x.bias [JOINT_0]BIAS setp pid.x.FF0 [JOINT_0]FF0 setp pid.x.FF1 [JOINT_0]FF1 setp pid.x.FF2 [JOINT_0]FF2 setp pid.x.deadband [JOINT_0]DEADBAND setp pid.x.maxoutput [JOINT_0]MAX_OUTPUT setp pid.x.error-previous-target true net x-enable => pid.x.enable net x-pos-mtr => pid.x.feedback net x-output-mtr <= pid.x.output # --- X linear scale PID (position correction loop) --- setp pid.xl.Pgain [JOINT_0]P_LIN setp pid.xl.Igain [JOINT_0]I_LIN setp pid.xl.Dgain [JOINT_0]D_LIN setp pid.xl.bias 0 setp pid.xl.FF0 0 setp pid.xl.FF1 0 setp pid.xl.FF2 0 setp pid.xl.deadband [JOINT_0]DEADBAND setp pid.xl.maxoutput [JOINT_0]MAX_OUTPUT setp pid.xl.error-previous-target true net x-enable => pid.xl.enable net x-pos-lin => pid.xl.feedback net x-output-lin <= pid.xl.output # Sum motor + linear PID outputs for final X drive signal net x-output-lin => sum2.0.in0 net x-output-mtr => sum2.0.in1 net x-output <= sum2.0.out # Position command feeds both PID loops net x-pos-cmd <= joint.0.motor-pos-cmd net x-pos-cmd => pid.xl.command net x-pos-cmd => pid.x.command # ---PWM Generator signals/setup--- setp hm2_5i24.0.pwmgen.00.output-type 1 setp hm2_5i24.0.pwmgen.00.scale [JOINT_0]OUTPUT_SCALE setp hm2_5i24.0.pwmgen.00.offset-mode 1 net x-output => hm2_5i24.0.pwmgen.00.value net x-enable joint.0.amp-enable-out => hm2_5i24.0.pwmgen.00.enable # X enable also drives GPIO 046 relay net x-enable => hm2_5i24.0.gpio.046.out net x-pos-rawcounts <= hm2_5i24.0.encoder.00.rawcounts # ---Encoder feedback signals/setup--- # Motor encoder (encoder 03) setp hm2_5i24.0.encoder.03.counter-mode 0 setp hm2_5i24.0.encoder.03.filter 1 setp hm2_5i24.0.encoder.03.index-invert 0 setp hm2_5i24.0.encoder.03.index-mask 0 setp hm2_5i24.0.encoder.03.index-mask-invert 0 setp hm2_5i24.0.encoder.03.scale [JOINT_0]ENCODER_MTR_SCALE # Linear scale (encoder 00) setp hm2_5i24.0.encoder.00.counter-mode 0 setp hm2_5i24.0.encoder.00.filter 1 setp hm2_5i24.0.encoder.00.index-invert 0 setp hm2_5i24.0.encoder.00.index-mask 0 setp hm2_5i24.0.encoder.00.index-mask-invert 0 setp hm2_5i24.0.encoder.00.scale [JOINT_0]ENCODER_LIN_SCALE net x-pos-mtr <= hm2_5i24.0.encoder.03.position net x-vel-mtr <= hm2_5i24.0.encoder.03.velocity net x-index-enable joint.0.index-enable <=> hm2_5i24.0.encoder.03.index-enable #net x-pos-mtr => joint.0.motor-pos-fb # Linear scale provides the actual position feedback to the joint net x-pos-lin <= hm2_5i24.0.encoder.00.position net x-vel-lin <= hm2_5i24.0.encoder.00.velocity net x-index-enable joint.0.index-enable <=> hm2_5i24.0.encoder.00.index-enable net x-pos-lin => joint.0.motor-pos-fb # ============================================================================ # AXIS Y - JOINT 1 # Dual PID: pid.y (motor encoder) + pid.yl (linear scale), summed via sum2.1 # Motor encoder: hm2 encoder 04 # Linear scale: hm2 encoder 01 # PWM output: pwmgen.02 # ============================================================================ # --- Y motor encoder PID (velocity/damping loop) --- setp pid.y.Pgain [JOINT_1]P setp pid.y.Igain 0 setp pid.y.Dgain [JOINT_1]D setp pid.y.bias [JOINT_1]BIAS setp pid.y.FF0 [JOINT_1]FF0 setp pid.y.FF1 [JOINT_1]FF1 setp pid.y.FF2 [JOINT_1]FF2 setp pid.y.deadband [JOINT_1]DEADBAND setp pid.y.maxoutput [JOINT_1]MAX_OUTPUT setp pid.y.error-previous-target true net y-enable => pid.y.enable net y-pos-mtr => pid.y.feedback net y-output-mtr <= pid.y.output # --- Y linear scale PID (position correction loop) --- setp pid.yl.Pgain [JOINT_1]P_LIN setp pid.yl.Igain [JOINT_1]I_LIN setp pid.yl.Dgain [JOINT_1]D_LIN setp pid.yl.bias 0 setp pid.yl.FF0 0 setp pid.yl.FF1 0 setp pid.yl.FF2 0 setp pid.yl.deadband [JOINT_1]DEADBAND setp pid.yl.maxoutput [JOINT_1]MAX_OUTPUT setp pid.yl.error-previous-target true net y-enable => pid.yl.enable net y-pos-lin => pid.yl.feedback net y-output-lin <= pid.yl.output # Sum motor + linear PID outputs for final Y drive signal net y-output-lin => sum2.1.in0 net y-output-mtr => sum2.1.in1 net y-output <= sum2.1.out # Position command feeds both PID loops net y-pos-cmd <= joint.1.motor-pos-cmd net y-pos-cmd => pid.yl.command net y-pos-cmd => pid.y.command # ---PWM Generator signals/setup--- setp hm2_5i24.0.pwmgen.02.output-type 1 setp hm2_5i24.0.pwmgen.02.scale [JOINT_1]OUTPUT_SCALE setp hm2_5i24.0.pwmgen.02.offset-mode 1 net y-output => hm2_5i24.0.pwmgen.02.value net y-enable joint.1.amp-enable-out => hm2_5i24.0.pwmgen.02.enable # net y-enable => hm2_5i24.0.gpio.044.out # commented out because duplicates x axis net y-pos-rawcounts <= hm2_5i24.0.encoder.01.rawcounts # ---Encoder feedback signals/setup--- # Motor encoder (encoder 04) setp hm2_5i24.0.encoder.04.counter-mode 0 setp hm2_5i24.0.encoder.04.filter 1 setp hm2_5i24.0.encoder.04.index-invert 0 setp hm2_5i24.0.encoder.04.index-mask 0 setp hm2_5i24.0.encoder.04.index-mask-invert 0 setp hm2_5i24.0.encoder.04.scale [JOINT_1]ENCODER_MTR_SCALE # Linear scale (encoder 01) setp hm2_5i24.0.encoder.01.counter-mode 0 setp hm2_5i24.0.encoder.01.filter 1 setp hm2_5i24.0.encoder.01.index-invert 0 setp hm2_5i24.0.encoder.01.index-mask 0 setp hm2_5i24.0.encoder.01.index-mask-invert 0 setp hm2_5i24.0.encoder.01.scale [JOINT_1]ENCODER_LIN_SCALE net y-pos-mtr <= hm2_5i24.0.encoder.04.position net y-vel-mtr <= hm2_5i24.0.encoder.04.velocity net y-index-enable joint.1.index-enable <=> hm2_5i24.0.encoder.04.index-enable #net y-pos-mtr => joint.1.motor-pos-fb # Linear scale provides the actual position feedback to the joint net y-pos-lin <= hm2_5i24.0.encoder.01.position net y-vel-lin <= hm2_5i24.0.encoder.01.velocity net y-index-enable joint.1.index-enable <=> hm2_5i24.0.encoder.01.index-enable net y-pos-lin => joint.1.motor-pos-fb # ============================================================================ # AXIS Z - JOINT 2 # Single PID: pid.zl (linear scale only), output via sum2.2 # Linear scale: hm2 encoder 02 # PWM output: pwmgen.04 # Enable relay: GPIO 044 (active low), gated by z-override AND gate # # Z-OVERRIDE MECHANISM: # A HAL "logic AND" gate combines z-override (default TRUE) with z-enable. # When z-override is set FALSE (via M101), the AND output goes low, # disabling the Z servo and GPIO 044 relay. This allows manual quill use. # M102 sets z-override back to TRUE to re-enable CNC Z control. # MIN_FERROR is set to 100 in INI to prevent following errors during manual mode. # ============================================================================ # Z motor encoder PID commented out - no motor encoder on Z axis #setp pid.z.Pgain [JOINT_2]P #setp pid.z.Igain 0 #setp pid.z.Dgain [JOINT_2]D #setp pid.z.bias [JOINT_2]BIAS #setp pid.z.FF0 [JOINT_2]FF0 #setp pid.z.FF1 [JOINT_2]FF1 #setp pid.z.FF2 [JOINT_2]FF2 #setp pid.z.deadband [JOINT_2]DEADBAND #setp pid.z.maxoutput [JOINT_2]MAX_OUTPUT #setp pid.z.error-previous-target true #net z-enable => pid.z.enable #net z-pos-mtr => pid.z.feedback #net z-output-mtr <= pid.z.output # --- Z linear scale PID --- setp pid.zl.Pgain [JOINT_2]P setp pid.zl.Igain [JOINT_2]I setp pid.zl.Dgain [JOINT_2]D setp pid.zl.bias 0 setp pid.zl.FF0 0 setp pid.zl.FF1 0 setp pid.zl.FF2 0 setp pid.zl.deadband [JOINT_2]DEADBAND setp pid.zl.maxoutput [JOINT_2]MAX_OUTPUT setp pid.zl.error-previous-target true # Z-override AND gate: z-enable-comb = z-override AND z-enable # When z-override is FALSE, Z servo is disabled (manual quill mode) net z-override => logic.0.in-00 net z-enable => logic.0.in-01 net z-enable-comb <= logic.0.and # Default: z-override is TRUE (CNC controls Z) sets z-override TRUE # Attempted dynamic ferror switching (not functional - see INI workaround) # mux2 selects between 100 (disabled) and 0.2 (enabled) based on z-enable-comb net z-enable-comb => mux2.0.sel setp mux2.0.in0 100 setp mux2.0.in1 0.2 net z-ferror <= mux2.0.out #net z-ferror => ini.2.min_ferror #joint.2.f-error #ini.2.ferror net z-enable-comb => pid.zl.enable net z-pos-lin => pid.zl.feedback net z-output-lin <= pid.zl.output # Z only has linear scale PID, no motor encoder sum needed net z-output-lin => sum2.2.in0 #net z-output-mtr => sum2.2.in1 net z-output <= sum2.2.out net z-pos-cmd <= joint.2.motor-pos-cmd net z-pos-cmd => pid.zl.command #net z-pos-cmd => pid.z.command # ---PWM Generator signals/setup--- setp hm2_5i24.0.pwmgen.04.output-type 1 setp hm2_5i24.0.pwmgen.04.scale [JOINT_2]OUTPUT_SCALE setp hm2_5i24.0.pwmgen.04.offset-mode 1 net z-output => hm2_5i24.0.pwmgen.04.value net z-enable joint.2.amp-enable-out => hm2_5i24.0.pwmgen.04.enable # Z enable relay gated through AND gate (z-override mechanism) net z-enable-comb => hm2_5i24.0.gpio.044.out net z-pos-rawcounts <= hm2_5i24.0.encoder.02.rawcounts # ---Encoder feedback signals/setup--- # Motor encoder (encoder 05) - not used on Z axis #setp hm2_5i24.0.encoder.05.counter-mode 0 #setp hm2_5i24.0.encoder.05.filter 1 #setp hm2_5i24.0.encoder.05.index-invert 0 #setp hm2_5i24.0.encoder.05.index-mask 0 #setp hm2_5i24.0.encoder.05.index-mask-invert 0 #setp hm2_5i24.0.encoder.05.scale [JOINT_2]ENCODER_MTR_SCALE # Linear scale (encoder 02) setp hm2_5i24.0.encoder.02.counter-mode 0 setp hm2_5i24.0.encoder.02.filter 1 setp hm2_5i24.0.encoder.02.index-invert 0 setp hm2_5i24.0.encoder.02.index-mask 0 setp hm2_5i24.0.encoder.02.index-mask-invert 0 setp hm2_5i24.0.encoder.02.scale [JOINT_2]ENCODER_LIN_SCALE #net z-pos-mtr <= hm2_5i24.0.encoder.05.position #net z-vel-mtr <= hm2_5i24.0.encoder.05.velocity #net z-index-enable joint.2.index-enable <=> hm2_5i24.0.encoder.05.index-enable #net z-pos-mtr => joint.2.motor-pos-fb # Linear scale provides the actual position feedback to the joint net z-pos-lin <= hm2_5i24.0.encoder.02.position net z-vel-lin <= hm2_5i24.0.encoder.02.velocity net z-index-enable joint.2.index-enable <=> hm2_5i24.0.encoder.02.index-enable net z-pos-lin => joint.2.motor-pos-fb # ============================================================================ # SPINDLE # On/off relay via GPIO 041 (active low). No speed control or feedback. # ============================================================================ #net spindle.0.on spindle-enable net spindle-enable spindle.0.on => hm2_5i24.0.gpio.041.out # ============================================================================ # MISCELLANEOUS SIGNALS # ============================================================================ # ---coolant signals--- net coolant-mist <= iocontrol.0.coolant-mist net coolant-flood <= iocontrol.0.coolant-flood # ---probe signal--- net probe-in => motion.probe-input # ---motion control signals--- net in-position <= motion.in-position net machine-is-enabled <= motion.motion-enabled # ---digital in / out signals--- # ---estop signals--- # Estop loops back: user-enable-out feeds emc-enable-in (no external estop chain) net estop-out <= iocontrol.0.user-enable-out net estop-out => iocontrol.0.emc-enable-in # ---manual tool change signals--- net tool-change-request <= iocontrol.0.tool-change net tool-change-confirmed => iocontrol.0.tool-changed net tool-number <= iocontrol.0.tool-prep-number # ---Use external manual tool change dialog--- loadusr -W hal_manualtoolchange net tool-change-request => hal_manualtoolchange.change net tool-change-confirmed <= hal_manualtoolchange.changed net tool-number => hal_manualtoolchange.number # ---ignore tool prepare requests--- net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared