iclim Posted March 27, 2014 Posted March 27, 2014 Hi, I have found some strange behaviour with the Motor[x].PrevPhaseEnc when implementing a User_Phase routine. To simplify my concerns and confirm that it was not my code, I made a simple counter which counts to 1000 void user_counters(struct MotorData *Mptr) { Mptr->PhasePos += 1; if(Mptr->PhasePos > 1000) { Mptr->PhasePos = 0; } return; } Now at the same time I setup my pointer pPhaseEnc to Gate3[0].MacroIn[9][0] i.e. Motor[8].pPhaseEnc=Acc5E3[0].MacroInA[9][0].a Now as you can see from the user code, at no point do I ever write to the Motor[x].PrevPhaseEnc register i.e. Mptr->PrevPhaseEnc = (int)blah; However upon enabling the Motor[8].PhaseCtrl=4. Here is a trace of the behaviour of PrevPhaseEnc From my investigations it looks like the content of Acc5E3[0].MacroInA[9][0].a is being copied into Motor[x].PrevPhaseEnc Hence when you implement a user phase routine the phase position delta is always zero. I currently have circum-navigated this issue by using a different memory address, however is there something that I need to change to stop this from occurring? Thanks
curtwilson Posted March 27, 2014 Posted March 27, 2014 Looking carefully at the internal code, the phase interrupt service routine reads the value at pPhaseEnc, uses it to update the value of PhasePos, and stores the value it read in PrevPhaseEnc for the next cycle, all before deciding whether to execute the built-in or a custom phase algorithm. The example in the manual redoes these steps -- it works, but is redundant. This will be updated. Your test routine overwrote the value of PhasePos that had been written in the preparatory algorithm. Note that the value of PhasePos is incremented by the change in the source position before a user algorithm, but it is not rolled over into the 0 - 2048 range.
iclim Posted April 4, 2014 Author Posted April 4, 2014 Curt, Thanks for the reply. I still am a little confused about what you said. If the internal code reads the value of pPhaseEnc and then stores that value in the PrevPhaseEnc before the user phase function is even called, then how can the user phase function calculate a delta phase position? I will illustrate my point with psuedo code //Delta Tau internal code does something like this PresentEnc = *Mptr->pPhaseEnc; //For example PresentEnc = 10 DeltaEnc = PresentEnc - Mptr->PrevPhaseEnc; //Lets say the previous was 5, so DeltaEnc = 5 PrevPhaseEnc = PresentEnc; //Now PrevPhase = 10 //Now the user code is called PresentEnc = *Mptr->pPhaseEnc; //Which is still 10 DeltaEnc = PresentEnc - Mptr->PrevPhaseEnc; //However since PrevPhaseEnc was already update to 10. The Delta is 0 PrevPhaseEnc = PresentEnc; //Redundant step Hence I am still a little confused by this. The reason why I am asking is that we have implemented a user phase function and the only means to get it to work is to store the prev enc in a different memory location. I would like to use PrevPhaseEnc
curtwilson Posted April 7, 2014 Posted April 7, 2014 It does appear that the built-in preparatory routine does the steps that you infer, and so the PrevPhaseEnc is written to each phase cycle, and therefore unavailable for separate use. The sample routine was written several years ago, so I'm not sure about the details of what it was doing or trying to do. The recently released V1.6 firmware has a new "PhaseLoadEnc" functionality for dual feedback when closing the servo loop inside the phase. If you are not using this functionality, then Motor[x].PrevPhaseLoadEnc can be used to store a value from cycle to cycle. (This element is write-protected in Script, but can be written to in C.)
Recommended Posts