OT: Absolute Position Wraparound

kamenges

Member
Join Date
Nov 2002
Location
Green Bay, WI
Posts
4,332
I probably should know how to approach this but I've gone into brainlock.

I have an application where I am using a 12-bit absolute encoder. I want to be able to stop at any point and adjust my accel/decel rate to anything I want. One thing that makes my life a little easier is I only need to move in one direction so I will always be crossing zero from one direction.

My problem comes in when I have to cross over the zero point. For example, assume I always rotate in a positive direction. I have a 12-bit encoder, which will give me 8192 discrete positions. Assume I want to stop at position 1 and I am starting at 6000. My position feedback will progess in a positive direction through 8191 then jump down to zero and progress to 1.

Ultimately I am looking for instantaneous distance left. Typically this would simply be Desired_Pos - Actual_Pos. But if my Actual_Pos starts out greater than my Desired_Pos and I can only move in a positive direction this falls apart. I can't seem to come up with a good way to give me this that will work in all cases without a significant amount of protection logic. Any ideas?

Keith
 
Something as simple as this will work in the world of theory...
wrap.JPG



But, in the real world, if your device overshoots the target by one count (POS=002), then suddenly your POS_ERR (decel distance) becomes 8191, and, in the real world, if you are deriving a speed reference from that value, it can cause an uh-oh in the math.

Many years ago I handled a situation like yours by using a separate DINT without the rollover restriction. It allowed me to count multiple revolutions, and handle any direction, or resolver backlash very cleanly.

I was working with controllogix processors and had plenty of DINT resolution to keep the math clean and bulletproof for many hundreds of revolutions more than I needed.

Instead of working with the raw resolver value, I calculated the distance travelled each scan, and summed it with my internally adjusted position, and then calculated the targets, position error, "in position" window limits and decel distances from that internal value.

The only other requirement in my application was that the internal position register be prevented from rolling over which I accomplished by "centering" it when the machine was at a known stopped state. I think I set my position DINT to something like 819200+raw_value (100 revolutions plus the raw count).

I did that for my previous employer and no longer have access the raw code, but I hope you get the idea...

Paul
 
Instead of working with the raw resolver value, I calculated the distance travelled each scan, and summed it with my internally adjusted position, and then calculated the targets, position error, "in position" window limits and decel distances from that internal value.
This is a good way to do it

Keith
1. Do you only need to keep track of positions within a turn or do you need to keep track of turns too?
2. What PLC or motion controller is doing this calculation?
3. Does the range of motion go beyond half a turn?
4. What is the range of motion?
5. How to the upper four bits returned to the computer. Do they float and are random? Are the 12 bits sign extend. Are the 12 bits 0 extended?

One thing I like to do know is make all encoders with 16 or less bits look like 16 bit encoders. This simplifies 16 bit math. 12 bit encoder data must be shifted left by 4 or mulitplied by 16. 13 bit encoders will be shifted left by 3 or multiplied by 8
NewCounts=16*Count
DifCounts=NewCounts-OldCounts
OldCounts=NewCounts;

Use the carry bit to count to set the most significant 16 bits of a 32 bit DifCounts regiester to 0 or -1.

Now you can subtract DifCounts from ToGoCounts. This part is similar to OkiePC's suggestion.

This method has an advantage in that it makes no difference if the encoder is 10 to 16 bits when scaling EXCEPT the low resolution encoders see their counts change in powers of 2. The scale position will there change in bigger jumps but that will happen anyway.
 
Thanks for the replies, guys.

I need to keep track of the position within a single turn. I don't need to keep track of multiple turns.

The calculations are being done in an AB Compactlogix plc.

In the ideal case the motion range would be exactly one-half a turn. It will be close to that, plus/minus a few degrees.

The absolule encoder is a Gray Code device and is wired into a digital input module. I currently have it wired into the lowest 12 bits.

You have me thinking enough that I need to do some testing tomorrow. I have done some tests to see how a DINT will act as the highest bit is set but I haven't done the same with an INT. If it handles this correctly, as Peter said I can simply multiply my decoded value by 8 and everything else should take care of itself.

If that doesn't work as expected, Okie's idea will get me roughly 60 years of turret rotations before I roll over a DINT, which wouldn't matter anyway. That should cover me pretty well.

Keith
 
Something along these lines?

PosDiffPerScan := CurrentScanPos - PrevScanPos;
PrevScanPos := CurrentScanPos;
if PosDiffPerScan >= 4096 then
RotCounter := RotCounter - 1;
end_if;
if PosDiffPerScan <= -4096 then
RotCounter := RotCounter + 1;
end_if;
CurrentAbsPos := RotCounter * 8192 + CurrentScanPos;

(sorry, Peter, I am trying to hone my STL skills here :) )

Here CurrentScanPos is the actual encoder input value. 4096 is an arbitrary value (half a rotation); the idea is to detect a "large enough" change of position readout over one scan and to use it as rollover indicator. CurrentAbsPos should be a 32-bit value, of course.
 
Sorry about that. I didn't answer your question correctly.

This is a dual spindle turret rewind. In normal operation it will turn in one direction as it moves from one winding spindle to the next. So an index will be about one half of a revolution. But the next index will be in the same direction as the fist, taking me to the original spindle and about the position I started with after the encoder value wraps. I need to always index in the same direction in order to keep the web path correct. The positioning accurracy isn't all that critical. It's just that it wraps around. I could set this up so the normal winding positions are at 90o and 270o so I stay away from zero when I expect to be looking at position closely. But what fun is that? :) Ultimately there must be a 'right way' to approach this.

I definitely like the idea of shifting the active bits as high as necessary to let the processor take care of the wrap. That way can use fixed positions for my targets. We'll see how this works out.

Keith
 
kamenges said:
My problem comes in when I have to cross over the zero point. For example, assume I always rotate in a positive direction. I have a 12-bit encoder, which will give me 8192 discrete positions.

Am I missing something? A 12 bit encoder will only go up to 4095 counts (starting from 0).

It's late, and I'm about to head for the house, so forgive the VB-like code. :)


This assumes that you will only run in one direction.

'Calculate Distance_to_Target assuming no rollover. This keeps
'us from having to add an Else condition.

Distance_to_Target = Target_Pos - Current_Pos


If Current_Pos > Target_Pos then
Distance_to_Target = Target_Pos + 4096 - Current_Pos



End If





For reverse direction:

'Calculate Distance_to_Target assuming no rollunder. This keeps
'us from having to add a Else condition.

Distance_to_Target = Current_Pos - Target_Pos




If Target_Pos > Current_Pos Then
Distance_to_Target = Current_Pos + 4096 - Target_Pos



End If





For both directions, you can condition which calculation you will use based on the direction bit.

And I don't see why you would need anything larger than an INT (unsigned would do fine).
 
Peter Nachtwey said:
The compares and adding and subtracting is not necessary.

Sure, if you use an unsigned INT and bit shift your numbers left by 4 bits (or like you said, multiply by 16). Then it's just a matter of subtraction.

But then you have to bit shift your result right by 4 (or divide by 16) to get the "normalized" result.

I guess that if you document it really well it would be okay...


But I think that my way would be easier to follow for the average joe, and I know better than to do any trick programming when I'm going to be the one answering the 24/7 service call (and the one who will be receiving the butt chewing that will follow the next morning).


BTW, since we are talking about bit-banging and all, I'd like to plug a really nice HP16c emulator:

http://www.hp16c.net/
 
rootboy said:
But then you have to bit shift your result right by 4 (or divide by 16) to get the "normalized" result.
There is know need to divide by 16 or shift right. Just treat all encoders as a 16 bit encoder. Normally one multiplies the counts to get engineering units anyway.

I guess that if you document it really well it would be okay...
Yes, and you might as well pertuate the best way. It isn't like the method you are using is obvious to bubba either.

BTW, since we are talking about bit-banging and all, I'd like to plug a really nice HP16c emulator:

http://www.hp16c.net/
I have a real one at work. At home I guess I am stuck in the dark ages. I did my taxes on a HP35. It is 36 years old and it still works but the batteries have been long dead.
http://en.wikipedia.org/wiki/HP-35. Both cost a lot for their time but after all these years I think I have got my monies worth.
 

Similar Topics

Hello, First thank for all the help i've gotten through this forum over the years reading others threads. I'm having an issue with Kinetix 5700...
Replies
15
Views
5,991
I've never really thought about these before, but a potential use in knowing the angle of a table has me looking at them. I don't really konow...
Replies
20
Views
11,772
Hello All, I'm using a Schneider ATV32 and absolute encoder for positioning a linear motion. "Sometimes" after a power cycle or estop I have to...
Replies
2
Views
3,502
Hello. An absolute encoder on a rotary axis gives values in range -2147483648 to 2147483648. When value is > 2147483648 , the encoder value is...
Replies
20
Views
2,341
I have 2 Absolute Encoders 8192 steps per Rev. (Model TR Electronic CEV65m-11003) These Encoders communicate to the PLC5-60 via Parallel push/pull...
Replies
3
Views
1,538
Back
Top Bottom