1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
# HAL config file for MAX NC test machine
#######################################################
# first load all the HAL modules we're going to need
#######################################################
# kinematics
loadrt trivkins
# main motion controller module
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES
# using steppers....
loadrt stepgen step_type=0,0,0
# I/O thru the parport
loadrt hal_parport cfg="0x0378"
# counting the spindle counter in software
loadrt counter num_chan=1
# misc blocks needed to do fun things
loadrt ddt count=6
# spindle speed pwm
loadrt pwmgen output_type=0
# spindle speed feedback
loadrt lowpass count=1
loadrt mult2 count=1
loadrt scale count=1
#######################################################
# add realtime functions to the threads
# first the high speed thread
#######################################################
# first we read parport inputs
addf parport.0.read base-thread
# update counter
addf counter.update-counters base-thread
# generate step and dir signals
addf stepgen.make-pulses base-thread
# generate spindle pwm
addf pwmgen.make-pulses base-thread
# write to outputs
addf parport.0.write base-thread
# now the servo thread
########################################################
# capture axis and spindle positions
addf stepgen.capture-position servo-thread
addf counter.capture-position servo-thread
# process motion commands coming from user space
addf motion-command-handler servo-thread
# run main motion controller
addf motion-controller servo-thread
# differentiators to make vel and acc signals
addf ddt.0 servo-thread
addf ddt.1 servo-thread
addf ddt.2 servo-thread
addf ddt.3 servo-thread
addf ddt.4 servo-thread
addf ddt.5 servo-thread
# other misc blocks
addf scale.0 servo-thread
addf pwmgen.update servo-thread
# update output info, axis and spindle
addf stepgen.update-freq servo-thread
addf lowpass.0 servo-thread
addf mult2.0 servo-thread
#######################################################
# interconnections
#
# first, the basic stepper machine connections
#######################################################
# connect position commands from motion module to step generator
net Xpos-cmd <= axis.0.motor-pos-cmd
net Xpos-cmd => stepgen.0.position-cmd
net Ypos-cmd <= axis.1.motor-pos-cmd
net Ypos-cmd => stepgen.1.position-cmd
net Zpos-cmd <= axis.2.motor-pos-cmd
net Zpos-cmd => stepgen.2.position-cmd
# connect position feedback from step generators
# to motion module
net Xpos-fb <= stepgen.0.position-fb
net Xpos-fb => axis.0.motor-pos-fb
net Ypos-fb <= stepgen.1.position-fb
net Ypos-fb => axis.1.motor-pos-fb
net Zpos-fb <= stepgen.2.position-fb
net Zpos-fb => axis.2.motor-pos-fb
# connect enable signals for step generators
net Xen <= axis.0.amp-enable-out
net Xen => stepgen.0.enable
net Yen <= axis.1.amp-enable-out
net Yen => stepgen.1.enable
net Zen <= axis.2.amp-enable-out
net Zen => stepgen.2.enable
# connect signals to step pulse generator outputs
net Xstep <= stepgen.0.step
net Xdir <= stepgen.0.dir
net Ystep <= stepgen.1.step
net Ydir <= stepgen.1.dir
net Zstep <= stepgen.2.step
net Zdir <= stepgen.2.dir
#############################################################################
# Spindle Speed
# The spindle goes forward only
net spindle-forward <= motion.spindle-forward
net spindle-forward => pwmgen.0.enable
# PID is not used to give closed-loop spindle speed control, because at the
# highest speeds the software-based counter cannot keep up (note: with 'counter',
# it can)
# Instead, this offset and scale have been determined emperically
# -- if these numbers are accurate, then top speed at this gearing is about
# 1200 rpm
#
# gain = 1/1128 ~ .00089
# offset = .07
# PWM Measured RPM
# 25% 200
# 50% 482
# 60% 595
setp scale.0.gain .00089
setp scale.0.offset .07
net spindle-speed-cmd <= motion.spindle-speed-out
net spindle-speed-cmd => scale.0.in
net spindle-speed-pwm <= scale.0.out
net spindle-speed-pwm => pwmgen.0.value
# Spindle speed feedback -- spindle-speed-fb-rpm can be metered or scoped
# but beware that at the highest speeds the software-based counter cannot
# keep up, and the speed is estimated incorrectly
# The gain of the lowpass filter is a trade-off: Higher numbers track spindle
# speed better when the speed changes. Lower numbers give a more steady
# estimate of average spindle speed when the speed is nominally constant
setp lowpass.0.gain 0.01
net spindle-speed-fb-raw <= counter.0.velocity
net spindle-speed-fb-raw => lowpass.0.in
net spindle-speed-fb-filtered <= lowpass.0.out
setp mult2.0.in0 60
net spindle-speed-fb-filtered mult2.0.in1
net spindle-speed-fb-rpm mult2.0.out
#############################################################################
# create a signal for the estop loopback
net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
# create signals for tool loading loopback
net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared
net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed
# create a signal for "spindle on"
net spindle_on <= motion.spindle-on
# connect physical pins to the signals
net Xstep => parport.0.pin-03-out
net Xdir => parport.0.pin-02-out
net Ystep => parport.0.pin-05-out
net Ydir => parport.0.pin-04-out
net Zstep => parport.0.pin-07-out
net Zdir => parport.0.pin-06-out
# amp enable (active lo)
#linksp Xen => parport.0.pin-01-out
#setp parport.0.pin-01-out-invert 1
# spindle enable
net spindle_on => parport.0.pin-01-out
setp parport.0.pin-01-out-invert 1
net pwm pwmgen.0.pwm => parport.0.pin-14-out
#######################################################
# set scaling and other parameters of the basic machine
# set stepgen module scaling - get values from ini file
setp stepgen.0.position-scale [AXIS_0]SCALE
setp stepgen.1.position-scale [AXIS_1]SCALE
setp stepgen.2.position-scale [AXIS_2]SCALE
# set stepgen module accel limits - get values from ini file
# jmk said to set these to ini value + 5% to avoid stepgen bug
setp stepgen.0.maxaccel [AXIS_0]STEPGEN_MAXACCEL
setp stepgen.1.maxaccel [AXIS_1]STEPGEN_MAXACCEL
setp stepgen.2.maxaccel [AXIS_2]STEPGEN_MAXACCEL
# end of basic machine
net homeswitches <= parport.0.pin-10-in
net homeswitches => axis.0.home-sw-in
net homeswitches => axis.2.home-sw-in
#######################################################
# Beginning of threading-related stuff
#######################################################
# spindle counter
# connect encoder signals to counter counter
# B is not used because it is the counter module, not encoder
net spindle-phase-A => counter.0.phase-A
net spindle-phase-Z => counter.0.phase-Z
net spindle-phase-A <= parport.0.pin-11-in
net spindle-phase-B <= parport.0.pin-12-in
net spindle-phase-Z <= parport.0.pin-13-in
# (that way thread pitches can be straightforward,
# a 20 tpi thread would multiply the counter output
# by 1/20, etc)
setp counter.0.position-scale 1024
# hook up motion controller's spindle indexing pin
net spindle-index-enable <= motion.spindle-index-enable
net spindle-index-enable <=> counter.0.index-enable
# report our revolution count to the motion controller
net spindle-pos <= counter.0.position
net spindle-pos => motion.spindle-revs
#######################################################
# make vel and accel sigs for testing
#######################################################
# send the position commands thru differentiators to
# generate velocity and accel signals (for testing)
# define the signals, and hook them up
net Xpos-cmd => ddt.0.in
net Xvel <= ddt.0.out
net Xvel => ddt.1.in
net Xacc <= ddt.1.out
net Ypos-cmd => ddt.2.in
net Yvel <= ddt.2.out
net Yvel => ddt.3.in
net Yacc <= ddt.3.out
net Zpos-cmd => ddt.4.in
net Zvel <= ddt.4.out
net Zvel => ddt.5.in
net Zacc <= ddt.5.out
|