Skip to content

Commit e2113f0

Browse files
committed
carousel.comp: Add direct position control for stepgen and encoder modes.
Signed-off-by: andypugh <andy@bodgesoc.org>
1 parent f7448d6 commit e2113f0

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

src/hal/components/carousel.comp

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ When the enable pin is set to true the component will immediately set the
5252
"active" pin to true and then (for a bidirectional instance) calculate the
5353
shortest path to the requested pocket number. The appropriate motor direction
5454
output pins will then be set. Bit outputs for forward and reverse are provided
55-
as well as a three-state velocity output for driving a DC motor PWM or a
56-
velocity-mode stepgen.
55+
as well as a three-state velocity output for driving a DC motor PWM or a
56+
velocity-mode stepgen.
5757

5858
The component will monitor the carousel position and, when the correct position
5959
is reached, set the motor-control pins to 0, set "active" to 0 and set "ready"
@@ -74,7 +74,7 @@ Once the decel-time has expired the carousel will, if it was moving forwards, re
7474
to the position marker, off of the arker and then bak on to the FWD edge. If moving in reverse
7575
it will continue off the marker and then reverse slowly on to the FWD edge.
7676
This algnment is only possible with a motor-vel controlled bidirectional carousel,
77-
Other combinations will be acepted but probably won't have the desired behaviour.
77+
Other combinations will be acepted but probably won't have the desired behaviour.
7878
Some tuning will be needed of align-dc and decel-time to achieve reliable operation.
7979

8080
In the unusual case that the index and pulse signals do not align it is
@@ -89,6 +89,12 @@ To operate the component with an encoder or stepgen use mode "C". The \\fBscale\
8989
pin should be the number of steps or encoder counts between pocket centres. The
9090
\\fBwidth\\fR pin can be used to stop the motor some distance before the centre of
9191
the pocket to allow the motor time to decelerate.
92+
In mode "C" it is possible to use either the speed/direction control used in other
93+
modes or to use direct position mode using the counts-target pin. The
94+
internal scaling of the encoder or stepgen should be set to 1.0. A PID
95+
hal component will be needed for encoder applications whereas stepgen
96+
configurations can use a stepgen in position control mode or in velocity
97+
control mode with a PID.
9298

9399
For tool changers which lock the carousel against a stop the \\fBrev-pulse\\fR pin can
94100
be set to a non-zero value. The motor-rev pin will then be set for this many seconds
@@ -119,7 +125,7 @@ certainly needs decel-time setting too""";
119125
pin in float decel-time "Time to wait for carousel to stop before final alignment and position check";
120126
pin in signed counts "Connect to the rawcounts of an encoder or a stepgen in 'counts' mode";
121127
pin in signed scale = 100 "The number of stepgen or encoder counts between successive pockets";
122-
pin in signed width = 0 "How far each side of the exact scale to signal a new pocket";
128+
pin in signed width = 10 "How far each side of the exact scale to signal a new pocket";
123129
pin in signed home-offset = 0 "The offset (in counts) between the index and pocket 1";
124130
pin io bit index-enable "Used to home to an encoder index";
125131
pin in bit jog-fwd "Jog the carousel forwards one tool position";
@@ -133,11 +139,13 @@ pin out signed current-position "This pin indicates the current position feedbac
133139
pin out float motor-vel "The duty-cycle or velocity to drive a DC motor or stepgen";
134140
pin out bit homed = 0 "Shows that homing is complete. Only used in index and edge modes";
135141
pin in bit unhome = 0 "Should only really be necessary for testing";
142+
pin out float counts-target "Target position for a stepgen or external PID controller";
136143

137144
param r signed state = 0 "Current component state";
138145
param r bit homing = 0 "Shows that homing is in progress. Only used for index mode";
139146
param r float timer "Shows the value of the internal timer";
140147
param r signed motor-dir "Internal tag for search direction";
148+
param r signed counts-offset "Internal offset of index pin";
141149
param rw unsigned debounce "How many thread cycles to wait for the position to stabilise";
142150

143151
option count_function;
@@ -152,7 +160,7 @@ variable int inst_pockets;
152160
variable int inst_code;
153161
variable int inst_parity;
154162
variable int old_index = 0;
155-
variable int base_counts = 0;
163+
param r signed base_counts = 0;
156164
variable int target;
157165
variable int old_unhome = 0;
158166
function _ ;
@@ -278,7 +286,9 @@ FUNCTION(_){
278286
c = (counts - base_counts);
279287
t = floor(((float)c + w) / scale);
280288
if (c >= (t * scale - w) && c <= (t * scale + w)) {
281-
new_pos = 1 + t - inst_pockets * floor((float)t / inst_pockets);
289+
new_pos = 1 + (t % inst_pockets);
290+
// C modulus of negative numbers is inconvenient
291+
if (new_pos < 1) new_pos += inst_pockets;
282292
}
283293
align_pin = (c % scale <= 2 && c % scale >= -2); // don't try to align to an exact count.
284294
}
@@ -344,26 +354,34 @@ FUNCTION(_){
344354
motor_rev = 1;
345355
motor_vel = rev_dc;
346356
motor_dir = -1;
357+
counts_target += (mod_pocket - current_position - inst_pockets) * scale;
347358
} else {
348359
motor_fwd = 1;
349360
motor_rev = 0;
350361
motor_vel = fwd_dc;
351362
motor_dir = 1;
363+
counts_target += (mod_pocket - current_position ) * scale;
352364
}
353365
} else {
354366
if (current_position - mod_pocket > (inst_pockets / 2)) {
355367
motor_fwd = 1;
356368
motor_rev = 0;
357369
motor_vel = fwd_dc;
358370
motor_dir = 1;
371+
counts_target += (mod_pocket - current_position + inst_pockets) * scale;
359372
} else {
360373
motor_fwd = 0;
361374
motor_rev = 1;
362375
motor_vel = rev_dc;
363376
motor_dir = -1;
377+
counts_target += (mod_pocket - current_position) * scale;
364378
}
365379
}
366380
} else {
381+
counts_target += (mod_pocket - current_position) * scale;
382+
if (counts_target < counts ) {
383+
counts_target += scale * inst_pockets;
384+
}
367385
motor_fwd = 1;
368386
motor_rev = 0;
369387
motor_vel = fwd_dc;
@@ -457,6 +475,8 @@ FUNCTION(_){
457475
motor_vel = fwd_dc;
458476
motor_dir = 1;
459477
index_enable = 1;
478+
counts_target += scale * inst_pockets;
479+
old_index = 1; // ensure 0->1 cycle of home sensor
460480
state = 11;
461481
case 11: ;// waiting for index & pulse
462482
int ind = 0;
@@ -474,22 +494,23 @@ FUNCTION(_){
474494
motor_rev = 0;
475495
motor_vel = 0;
476496
base_counts = counts - home_offset;
497+
counts_target = base_counts;
477498
if ( align_dc == 0) {
478499
state = 0;
479500
} else {
480501
timer = decel_time;
481502
state = 5;
482503
}
483504
}
484-
old_index = (sense(0) && sense(1));
505+
old_index = ind;
485506
break; // So that we don't see the tool1 pulse twice
486507
case 20: //jogging fwd/rev
487508
if (current_position != target){
488-
deb = debounce;
489-
return;
490-
} else if (deb-- >0) {
491-
return;
492-
}
509+
deb = debounce;
510+
return;
511+
} else if (deb-- > 0) {
512+
return;
513+
}
493514
if (align_dc != 0 && ! align_pin) return;
494515
motor_fwd = 0;
495516
motor_rev = 0;

0 commit comments

Comments
 (0)