This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Sensored InstaSPIN MOTION - Encoder data rate

Other Parts Discussed in Thread: MOTORWARE

Hi,

I am running a PMSM at maximum electrical frequency of ~1kHz. I was able to run Lab 12 satisfactorily using a regular A/B/I quadrature encoder.

My final application would actually be using an absolute encoder which communicates with the microcontroller via SCI. The speed of this channel is 115.2kbps and the effective rate at which I can update the position is 1.6kHz. When I tried to run the motor using this encoder, with 24kHz PWM, 12kHz ISR & CTRL, the speed regulation was very poor. I am assuming the low position update rate is the cause for this behavior. What would be the slowest update rate at which I can get a satisfactory performance?

The encoder manufacturer offers it at higher communication speeds of up to 1Mbps, but they also mention that the maximum repetition rate is 4kHz. This means that if I request position data faster than 4kHz, same date could be sent twice. I am wondering if I can use this encoder for my application. 

Due to the mechanical size and shape requirements, this is the encoder that best suits our needs, so it will be great to have it work.

Thanks,
Tamil

  • Tamil,

    I modified my lab 12 to slow down the encoder electrical angle calculation to about 1kHz and I saw good speed control performance.  The issue could be in the way that we are processing the data from your encoder.

    Are you converting the value from your absolute encoder into an electrical angle that ranges between 0 and 1?

    Have you modified the ctrlQEP.h file to accept your new electrical angle source?

    With your absolute encoder, how have you been handling the calibration to align a motor electrical zero angle with the encoder?

  • Adam,

    What do you mean by slowing down encoder electrical angle calculation? Is that the same as the speed loop ticks? I have it set at 1kHz currently.

    The raw position count data from the encoder is first converted to 0 to 1 mechanical angle, and then converted to 0 to 1 electrical angle for each pole pair.

    I have modified the call to "STPOSCONV_setElecAngle_erev" in "ST_runPosConv" of "proj_lab12.c" and the assignment of "angle_pu" in "CTRL_runOnLine_User" of "ctrlQEP.h".

    For calibration, I run my calibration function under the "if(EST_getState(obj->estHandle) == EST_State_Rs)" condition of "mainISR". Inside the calibration function, I assign the offset with this line of code:  
    "encComm->calibratedAngle = encComm->numMaxCount - encComm->positionCount - 1;" 
    where "numMaxCount" is the full scale count of the encoder and "positionCount" is the current encoder count.

    -Tamil

  • Tamil,

    In the lab 12 example, we typically calculate a new electrical angle each time the ISR is called.  I modified the code to calculate a new electrical angle at 1kHz instead of at 15kHz.  This should more closely approximate your system.  When I did this I did not have any speed control issues.    

    One thing I've noticed is that is that I get a better encoder calibration result when I increase the current that I'm using to do the Rs Recalibration.  This pushes the motor harder into alignment.  

    Can you confirm the update rate of your encoder?

  • Adam,

    So, did you test with ISR set down to 1kHz or did you change the place where the function is called? I would like to do the same test as you did with my A/B/I encoder to see if the performance is affected.

    It doesn't seem to be an alignment issue, since with the same Rs re-calibration current I get a good performance with A/B/I encoder. Also, I manually changed the calibration offset little bit and it seemed like the initial value calculated by the controller was itself good.

    The 1.6kHz update rate I mentioned is a calculated value. I have SCI FIFO interrupts that process the data and update the raw position count. Then, I call the function that calculates the electrical angle in the mainISR. Is there a way to measure the actual rate at which my electrical angle gets updated?

    Thanks,
    Tamil

  • Update:

    I changed the code to call "ENC_calcElecAngle(encHandle)" from "ST_runVelCtl", which I think makes the encoder update at the rate of my speed loop, which is currently at 1kHz. The A/B/I encoder continued to give better performance in this condition compared to the absolute encoder.

    -Tamil

  • Tamil,

    That was the test I did to reduce the update rate of the electrical encoder.  

    Could you use a CPU Timer to time how often you are getting a complete data packet and therefor how often your electrical angle is being updated?  Another option would be to create a data buffer where you store your electrical angle each isr.  You could then look at how often the value changes, and that would inform you of the true update rate.

  • Adam,

    I used a buffer in mainISR and I see that I get a new position value for every 10 or 11 counts. My ISR is running at 12kHz, so I think that would mean the update rate is little over 1kHz.

    On the other hand, I seem to be getting new position data on every count when I use the A/B/I incremental encoder.

    -Tamil

  • The absolute encoder I am using also has a fixed latency of 250 µs between the position acquisition and first start bit sent out. I wonder if this would add to the problem.

    -Tamil

  • Here is a comparison between the electrical angle generated from the A/B/I encoder(top) and that generated from the absolute encoder (bottom).

    -Tamil

  • Tamil,

    What electrical speed was the motor running when you captured that data?

    I did notice that as I increased the speed I was unable to achieve maximum motor speed with the reduced rate of angle updates and I had trouble maintaining speed if I injected disturbances.

    This is most likely a similar problem to the one that you are seeing.  It seems like we aren't able to generate enough torque because the angle is not being updated fast enough.  

    With my Anaheim BLY172 motor I can't generate good torque above 200Hz with the 1kHz angle update rate.

    I think this is the issue.

  • Hi Adam,

    When i captured the data shown in the plots in my previous post, the motor was running at 1000 RPM which is 183.33 elec. Hz. But I wasn't seeing a good response at 500 RPM either. While testing, I did not inject any disturbance, but just had a load attached. By bad response I mean the actual speed varying between SpeedRef +/- 10%.

    What I am not able to comprehend is that why would the system behave well when the A/B/I encoder feedback is used with the updates happening at 1kHz but wouldn't respond well with the feedback from absolute encoder at ~1.2khz while running at the same speed.

    -Tamil

  • Tamil,

    Do you have the ability to run both encoders in parallel?  Could we compare the data from both encoders?  

    I don't believe the issue is with the speed controller.  I think the issues is in the FOC.  

    The thing we haven't been considering is the delays associated with the absolute encoder.  You mentioned there is a fixed time-delay of 250us from when it takes a reading until it beings transmitting.  After there there is a delay until the data is fully received by the microcontroller (assuming 8 bytes of data this works out to 625us).  For a total delay of 875us.  During that time the motor is still moving.  And so the angle we are going to begin establishing in our stator is now 875us old.  And we are going to hold that old angle for about 1ms.  So when we look at the worst case of this stack-up our angle is 1.875ms old.  

    Maybe this encoder isn't fast enough to do sensored FOC.  Have you used this encoder with other motor control projects?

  • Hi Adam,

    The plot capture from the previous post was taken when both encoders were running parallel. I was computing angle from both encoders but feeding only the absolute encoder angle to the controller. In other cases, I would do the same while feeding only A/B/I encoder angle to the controller.

    I see that the delay could definitely be a problem as you explained and could probably be the reason why we are seeing the speed ripple. I talked to the encoder manufacturer's support team and they said that the 250us is a fixed latency, but that I can reduce the communication delay by switching to a faster version of the encoder which can communicate at speeds of up to 1Mbps on Asynchronous RS-422 or up to 4Mhz over SPI. Regardless of the communication speed, the fastest position update these encoders can give is 4kHz.

    With CPU at 90Mhz and InstaSPIN running at 24kHz PWM, 10kHz ISR & CTRL,1 kHz Speed & Traj., do you think I will have enough room for running Asynchronous RS-422 via SCI at 1Mbps or SPI at 4Mhz? Will the 4kHz update rate be good enough for running a motor at 1kHz elec. frequency, considering the fixed 250us latency? 

    I have never used this encoder with other motor control projects before.

    -Tamil

  • Tamil,

    I don't have enough experience with this type of encoders to be able to accurately predict if a 4kHz update rate will be enough to support motor control.  

    It seems like your worst case electrical angle would be delayed by ~500us (250us sample delay + 250us[1/4kHz] propagation delay).  

    One thing you could try in the interim, is to modify the angle advancement routine to account for the existing ~1.875ms of delay.  This might help with the control issues you are seeing with the absolute encoder.

  • Thanks for your suggestion Adam. Is there any documentation available for the angle advancement routine? I don't remember coming across it in any of the Motorware labs. 

    -Tamil

  • Tamil,

    We automatically compensate the angle feedback to feedforward in our MotorWare projects (where we are running out of user code, this is not in ROM). 

    See ctrl.h for the method

    //! \brief      Runs angle delay compensation
    //! \details    This function takes the decimation rates to calculate a phase delay,
    //!             and it compensates the delay. This allows the voltage output to do a
    //!             better correction of the error.
    //! \param[in]  handle    The controller (CTRL) handle
    //! \param[in]  angle_pu  The angle delayed
    //! \return     The phase delay compensated angle
    inline _iq CTRL_angleDelayComp(CTRL_Handle handle, const _iq angle_pu)
    {
      CTRL_Obj *obj = (CTRL_Obj *)handle;
      _iq angleDelta_pu = _IQmpy(EST_getFm_pu(obj->estHandle),_IQ(USER_IQ_FULL_SCALE_FREQ_Hz/(USER_PWM_FREQ_kHz*1000.0)));
      _iq angleUncomp_pu = angle_pu;
      _iq angleCompFactor = _IQ(1.0 + (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK * (float_t)USER_NUM_ISR_TICKS_PER_CTRL_TICK * ((float_t)USER_NUM_CTRL_TICKS_PER_EST_TICK - 0.5));
      _iq angleDeltaComp_pu = _IQmpy(angleDelta_pu, angleCompFactor);
      uint32_t angleMask = ((uint32_t)0xFFFFFFFF >> (32 - GLOBAL_Q));
      _iq angleTmp_pu;
      _iq angleComp_pu;

      // increment the angle
      angleTmp_pu = angleUncomp_pu + angleDeltaComp_pu;

      // mask the angle for wrap around
      // note: must account for the sign of the angle
      angleComp_pu = _IQabs(angleTmp_pu) & angleMask;

      // account for sign
      if(angleTmp_pu < 0)
        {
          angleComp_pu = -angleComp_pu;
        }

      return(angleComp_pu);
    }

     

    I agree this seems to be your issue, and a good proof point of why sensored isn't always better...and why encoder manufacturers are going to higher throughput serial mechanisms.