PCOMP - Position Compare
The position compare block takes a position input and allows a regular number of threshold comparisons to take place on a position input. The normal order of operations is something like this:
If PRE_START > 0 then wait until position has passed START - PRE_START
If START > 0 then wait until position has passed START and set OUT=1
Wait until position has passed START + WIDTH and set OUT=0
Wait until position has passed START + STEP and set OUT=1
Wait until position has passed START + STEP + WIDTH and set OUT=0
Continue until PULSES have been produced
It can be used to generate a position based pulse train against an input encoder or analogue system, or to work as repeating comparator.
Fields
Name |
Type |
Description |
---|---|---|
ENABLE |
bit_mux |
Stop on falling edge, reset and enable on rising edge |
INP |
pos_mux |
Position data from position-data bus |
PRE_START |
param int |
INP must be this far from START before waiting for START |
START |
param int |
Pulse absolute/relative start position value |
WIDTH |
param int |
The relative distance between a rising and falling edge |
STEP |
param int |
The relative distance between successive rising edges |
PULSES |
param |
The number of pulses to produce, 0 means infinite |
RELATIVE |
param enum |
If 1 then START is relative to the position of INP at enable
0 Absolute
1 Relative
|
DIR |
param enum |
Direction to apply all relative offsets to
0 Positive
1 Negative
2 Either
|
ACTIVE |
bit_out |
Active output is high while block is in operation |
OUT |
bit_out |
Output pulse train |
HEALTH |
read enum |
Error details if anything goes wrong
0 OK
1 Position jumped by more than STEP
2 Can’t guess DIR when RELATIVE and PRE_START=0 and START=0
|
PRODUCED |
read |
The number of pulses produced |
STATE |
read enum |
The internal statemachine state
0 WAIT_ENABLE
1 WAIT_DIR
2 WAIT_PRE_START
3 WAIT_RISING
4 WAIT_FALLING
|
Position compare is directional
A typical example would setup the parameters, enable the block, then start moving a motor to trigger a series of pulses:
(Source code, png, hires.png, pdf)
But if we get the direction wrong, we won’t get the first pulse until we cross START in the correct direction:
(Source code, png, hires.png, pdf)
Moving in a negative direction works in a similar way. Note that WIDTH and PULSE still have positive values:
(Source code, png, hires.png, pdf)
Internal statemachine
The Block has an internal statemachine that is exposed as a parameter, allowing the user to see what the Block is currently doing:
Not generating a pulse more than once
A key part of position compare is not generating a pulse at a position more than once. This is to deal with noisy encoders:
(Source code, png, hires.png, pdf)
This means that care is needed if using direction sensing or relying on the directionality of the encoder when passing the start position. For example, if we approach START from the negative direction while doing a positive position compare, then jitter back over the start position, we will generate start at the wrong place. If you look carefully at the statemachine you will see that the Block crossed into WAIT_START when INP < 4 (START), which is too soon for this amount of jitter:
(Source code, png, hires.png, pdf)
We can fix this by adding to the PRE_START deadband which the encoder has to cross in order to advance to the WAIT_START state. Now INP < 2 (START-PRE_START) is used for the condition of crossing into WAIT_START:
(Source code, png, hires.png, pdf)
Guessing the direction
We can also ask to the Block to calculate direction for us:
(Source code, png, hires.png, pdf)
This is a one time calculation of direction at the start of operation, once the encoder has been moved enough to guess the direction then it is fixed until the Block has finished producing pulses:
(Source code, png, hires.png, pdf)
Interrupting a scan
When the ENABLE input is set low the output will cease. This will happen even if the ENABLE is set low when there are still cycles of the output pulse to generate, or if the ENABLE = 0 is set at the same time as a position match.
(Source code, png, hires.png, pdf)
(Source code, png, hires.png, pdf)
Position compare on absolute values
Doing position compare on an absolute value adds additional challenges, as we are not guaranteed to see every transition. It works in much the same way as the previous examples, but we trigger on greater than or equal rather than just greater than:
(Source code, png, hires.png, pdf)
But what should the Block do if the output is 0 and the position jumps by enough to trigger a transition to 1 and then back to 0? We handle this by setting HEALTH=”Error: Position jumped by more than STEP” and aborting the compare:
(Source code, png, hires.png, pdf)
Likewise if the output is 1 and the position causes us to need to produce a 0 then 1:
(Source code, png, hires.png, pdf)
And if we skipped a larger number of points we get the same error:
(Source code, png, hires.png, pdf)
Relative position compare
We may want to nest position compare blocks, or respond to some external event. In which case, we expose the option to a position compare relative to the latched position at the start:
(Source code, png, hires.png, pdf)
If we want it to start immediately on ENABLE then we set START and PRE_START=0:
(Source code, png, hires.png, pdf)
We can also guess the direction in relative mode:
(Source code, png, hires.png, pdf)
This works when going negative too:
(Source code, png, hires.png, pdf)
And with a PRE_START value we guess the direction to be the opposite to the direction the motor is travelling when it exceeds PRE_START:
(Source code, png, hires.png, pdf)
We cannot guess the direction when RELATIVE mode is set with no START or PRE_START though, the Block will error in this case:
(Source code, png, hires.png, pdf)
Use as a Schmitt trigger
We can also make use of a special case with STEP=0 and a negative WIDTH to create a Schmitt trigger that will always trigger at START, and turn off when INP has dipped WIDTH below START:
(Source code, png, hires.png, pdf)
We can use this same special case with a positive width to make a similar comparator that turns on at START and off at START+WIDTH, triggering again when INP <= START:
(Source code, png, hires.png, pdf)