Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Unable to configure Position-Compare to start at desired starting point
#1
I need some help computing the correct CompA register value on my Power PMAC and ACC-24E3 Card. Using my current calculation method, the PowerPMAC "misses" what I think the starting point should be and starts at another point. After it starts at the unexpected point, everything that follows is as I expect, meaning I get pulses at the desired regular intervals based on encoder position as configured (via CompAdd, etc.). From this I conclude that I am not specifying the starting point where I think I am, but that scaling is correct.

Power PMAC CPU
ACC24E3 Card

Motor is 2000 cnts / rev
Gate3[0].Chan[0].EncCtrl=7
Gate3[0].Chan[0].AtanEna = 0

If I power up the unit so that the PhaseCapt is at (or nearly 0), the following works nicely. This puts CompA one rev. into the positive future and CompB two revs. into the positive future and then sets the CompAdd for 2 revs. and suppresses the first autoincrement (new feature of PowerPMAC)

I wish to have Equ change state once per revolution.
Gate3[0].Chan[0].CompA = 2000 cnts * 4096 (register scaling) = 8,192,000
Gate3[0].Chan[0].CompB = 2 * 2000 cnts * 4096 (register scaling) = 16,834,000
Gate3[0].Chan[0].CompAdd = 2 * 2000 cnts * 4096 (register scaling) = 16,384,000
Gate3[0].Chan[0].EquWrite=1 // put Equ at zero and suppress first autoinc

If I attempt to start somewhere after power-up and start from a present location, this code gives unexpected results:

Gate3[0].Chan[0].CompA = Gate3[0].Chan[0].PhaseCapt + Gate3[0].Chan[0].CompAdd/2
Gate3[0].Chan[0].CompB = Gate3[0].Chan[0].PhaseCapt + Gate3[0].Chan[0].CompAdd
Gate3[0].Chan[0].CompAdd = 2 * 2000 * 4096 (register scaling)
Gate3[0].Chan[0].EquWrite=1 // put Equ at zero and suppress first autoinc

Instead of changing the state of the Equ line on the next revolution, this above configuration started changing the output line, once per revolution after 374 revs. :( I stopped the motor, rotated the axis by about 90 degrees, re-executed the above 4 lines of code (the ones which include .PhaseCapt) and jogged the motor. This time the toggling of the output began after 430 revs.

Please let me know how to make use of the current position when configuring my CompA & B registers. I expect that there is some other scaling going on that I am not aware of. I do note that .PhaseCapt appears to be +/- 2.147e9 while CompA appears to be 0 - 4.295e9, but they do not move 1:1 but differ by a factor of 16. 16*PhaseCapt = CompA at the point of "equality" and Equ line toggle.

Thank you for your help.
Reply
#2
I have used this code for my testing. It has been awhile so a few bugs may exist but it has all the major ideas. Hopefully it helps show you what has maybe been left out on your side.


/* Setup position compare for Motors 1 and 3 */

global m1CompDist = 100
global m3CompDist = 100
global bracketed = 0

open plc 3

Local tmp;

// motor 3 setup
tmp = Gate3[0].Chan[2].ServoCapt * 16; // has 8-bits of subcounts extend to 12-bit subcounts
Gate3[0].Chan[2].CompAdd = m3CompDist*4096 // has 12-bits of subcounts units of 1/4096 cts

if(bracketed == 0)
{
Gate3[0].Chan[2].CompA = tmp + Gate3[0].Chan[2].CompAdd * 1.5;
Gate3[0].Chan[2].CompB = tmp + Gate3[0].Chan[2].CompAdd;
Gate3[0].Chan[2].EquWrite=$3; // non-bracketed must set bit-1 to skip first increment
}
else
{
Gate3[0].Chan[2].CompA = tmp + Gate3[0].Chan[2].CompAdd*0.25;
Gate3[0].Chan[2].CompB = tmp - Gate3[0].Chan[2].CompAdd*0.25;
}

// motor 1 setup
tmp = Gate3[0].Chan[0].ServoCapt * 16; // has 8-bits of subcounts extend to 12-bit subcounts
Gate3[0].Chan[0].CompAdd = m1CompDist*4096 // has 12-bits of subcounts units of 1/4096 cts

if(bracketed == 0)
{
Gate3[0].Chan[0].CompA = tmp + Gate3[0].Chan[0].CompAdd * 1.5;
Gate3[0].Chan[0].CompB = tmp + Gate3[0].Chan[0].CompAdd;
Gate3[0].Chan[0].EquWrite=$3; // non-bracketed must set bit-1 to skip first increment
}
else
{
Gate3[0].Chan[0].CompA = tmp + Gate3[0].Chan[0].CompAdd*0.25;
Gate3[0].Chan[0].CompB = tmp - Gate3[0].Chan[0].CompAdd*0.25;
}

disable plc 3
close
/****************************************/
Reply
#3
I have used this code for my testing. It has been awhile so a few bugs may exist but it has all the major ideas. Hopefully it helps show you what has maybe been left out on your side.


/* Setup position compare for Motors 1 and 3 */

global m1CompDist = 100
global m3CompDist = 100
global bracketed = 0

open plc 3

Local tmp;

// motor 3 setup
tmp = Gate3[0].Chan[2].ServoCapt * 16; // has 8-bits of subcounts extend to 12-bit subcounts
Gate3[0].Chan[2].CompAdd = m3CompDist*4096 // has 12-bits of subcounts units of 1/4096 cts

if(bracketed == 0)
{
Gate3[0].Chan[2].CompA = tmp + Gate3[0].Chan[2].CompAdd * 1.5;
Gate3[0].Chan[2].CompB = tmp + Gate3[0].Chan[2].CompAdd;
Gate3[0].Chan[2].EquWrite=$3; // non-bracketed must set bit-1 to skip first increment
}
else
{
Gate3[0].Chan[2].CompA = tmp + Gate3[0].Chan[2].CompAdd*0.25;
Gate3[0].Chan[2].CompB = tmp - Gate3[0].Chan[2].CompAdd*0.25;
}

// motor 1 setup
tmp = Gate3[0].Chan[0].ServoCapt * 16; // has 8-bits of subcounts extend to 12-bit subcounts
Gate3[0].Chan[0].CompAdd = m1CompDist*4096 // has 12-bits of subcounts units of 1/4096 cts

if(bracketed == 0)
{
Gate3[0].Chan[0].CompA = tmp + Gate3[0].Chan[0].CompAdd * 1.5;
Gate3[0].Chan[0].CompB = tmp + Gate3[0].Chan[0].CompAdd;
Gate3[0].Chan[0].EquWrite=$3; // non-bracketed must set bit-1 to skip first increment
}
else
{
Gate3[0].Chan[0].CompA = tmp + Gate3[0].Chan[0].CompAdd*0.25;
Gate3[0].Chan[0].CompB = tmp - Gate3[0].Chan[0].CompAdd*0.25;
}

disable plc 3
close
/****************************************/
Reply
#4
AccurateMovements,

As bradp has mentioned, the PhaseCapt register in Gate3 has 8 bits of 1/T sub-count resolution in TimerMode=0 (Hardware 1/T), but the CompA, CompB and CompAdd always have 12-bits of 1/T sub-count resolution. This is why when your PhaseCapt is close to zero you can set the CompA, CompB and CompAdd without any problems, but as soon as you move away from zero you can't get the edge properly calculated. Please make sure to multiply PhaseCapt value by 2^4 (16) to calculate and set the CompA and CompB registers.

Regards,
Sina Sattari
Hardware Engineering Manager
Delta Tau Data Systems, Inc.
Reply
#5
Page 26 of the "Synchronizing Power PMAC to External Events" needs to be updated to reflect that the ACC24E3 comp registers have 12 bits (not 8 bits) fractional count value.

Also, while you are in there, bottom of pg 27 should be corrected to read "setting EquWrite to 1 forces the channel's internal compare state to 0"

Reply
#6
Brad and Sina,
Thank you gentlemen, after working out this offset, I have successfully configured my position-compare to start at the location I desired.
Thank You, and yes, as andyf indicates in his last post, kindly update the Synchronizing Power PMAC to External Events document to reflect the correct fractional count information.
Thank you.
Reply
#7
Hello Bradp,
Thank you for your code. I did make a modification to account for rollover of the CompA register, since, if a value which is too large for the CompA register is computed from PhaseCapt*16, the CompA register is filled with its max value of 2^32, instead of the actual value desired. (perform a % pow(2,32) before assigning to CompA or B).

I am now unable to deal effectively with negative values of PhaseCapt. Gate3[0].Chan[0].PhaseCapt seems to have a range of +/- 2^32-1. This gives my calculations trouble, esp. when attempting to put a negative value into CompA. Manual states expected range to be positive values, but this is not what I am seeing on my demo box.

What should I do to effectively deal with negative values of PhaseCapt?
Reply
#8
Looks like I worked out a possible solution, although I would like to hear if there is a better solution.

If PhaseCapt is < 0 then add 2* pow(2,32) which puts it back to a positive relative number and then the modulo operator discussed earlier, takes care of the CompA value being too big.

Code:
if (Gate3[0].Chan[0].ServoCapt < 0)
{
   tmp = (Gate3[0].Chan[0].ServoCapt + (2* pow(2,32)))* 16;
}
else
{
   tmp = Gate3[0].Chan[0].ServoCapt * 16; // has 8-bits of subcounts extend to 12-bit subcounts
}
Reply
#9
I have written a subprogram for using the DSPGate3 Position compare.

Argument Description:
GateIndex: DSPGate3 Index
ChanIndex: Channel index
CompareAdd: Pulse Period in units of quadrature (X4) counts
minimum value of 0.125 for supporting sub-count periods (no zero-velocity nor velocity reversal support)
minimum value of 2 for reliable support for 0 velocity or velocity reversal
StartPoint: Starting Edge distance from current position in units of quadrature (X4) counts
Set to 0 for bracketing the current position to support pulse generation in either direction
Set to + or - non-zero values for placing starting pulse edge to right or left of current position.

Code:
open subprog EquSetup(GateIndex, ChanIndex, CompareAdd, StartPoint)

if ( StartPoint == 0)
{
// Bracketting
Gate3[GateIndex].Chan[ChanIndex].EquWrite = 1;
Gate3[GateIndex].Chan[ChanIndex].CompAdd = 0;      
Gate3[GateIndex].Chan[ChanIndex].CompB = Gate3[GateIndex].Chan[ChanIndex].PhaseCapt*16;
Gate3[GateIndex].Chan[ChanIndex].CompA = Gate3[GateIndex].Chan[ChanIndex].PhaseCapt*16 + CompareAdd/4*4096 ;
Gate3[GateIndex].Chan[ChanIndex].CompB = Gate3[GateIndex].Chan[ChanIndex].PhaseCapt*16 - CompareAdd/4*4096 ;
Gate3[GateIndex].Chan[ChanIndex].CompAdd = CompareAdd*4096;
}
else
{
//// Positive & Negative Start Point
Gate3[GateIndex].Chan[0].EquWrite = 1;
Gate3[GateIndex].Chan[0].CompAdd = CompareAdd*4096;
Gate3[GateIndex].Chan[0].CompA = Gate3[GateIndex].Chan[ChanIndex].PhaseCapt*16 + StartPoint * 4096 + CompareAdd/4*4096 ;
Gate3[GateIndex].Chan[0].CompB = Gate3[GateIndex].Chan[ChanIndex].PhaseCapt*16 + StartPoint * 4096 + CompareAdd*3/4*4096 ;
}
  
close
Sina Sattari
Hardware Engineering Manager
Delta Tau Data Systems, Inc.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)