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.

LAUNCHXL-F28069M: Integrating an absolute rotary position magnetic encoder with InstaSpin-Motion

Part Number: LAUNCHXL-F28069M
Other Parts Discussed in Thread: BOOSTXL-DRV8305EVM, CONTROLSUITE

Hello, 

I'm trying to use an absolute position encoder (AS5048A - ams.com/.../AS5048A) with a LAUNCHXL-F28069M and the BOOSTXL-DRV8305EVM to control the position of PMS motor following labs 12x - 13x of the TI Instaspin labs. I'm using an absolute encoder because my application requires precise positioning of the motor at near 0 speeds with little/no startup motion. I've built up an SPI interface to the sensor and am successfully reading in the value (a 14 bit integer indicating the absolute mechanical angle of the motor), but am having a hard time integrating it with the SpinTAC controller in a way that works. 

Here's what I've tried:

I started by doing labs 2x to identify the resistance, inductance, etc of my motor. All seemed to work fine there. Running labs 3x also were successful in spinning the motor to the desired rpm.

I've plumbed the encoder signal into the `enc` module instead of the quadrature signal. To ensure a proper conversion, I set up the `enc` module using 2^14 / 4 as my number of encoder lines because it seems to be treating ENCODER_LINES * 4 - 1 as the maximum input value. Doing this I was able to make the `enc` module generate the electrical angle of my motor from my encoder signal. This seems to be working properly as it cycles from 0 to 1 14 times over 1 motor revolution, which is correct as I have a 14 pole-pair motor.

At this point it seems like I have properly set up my feedback loop. I ran lab 12a to identify the inertia of my system, and after changing the ramp time and target speed a bit, it seemed to be working. However, I'm seeing very strange behavior from the motor when I run lab 12b. Though the motor is trying to spin to a target rpm (100), it starts spinning up but then seems to stall and pulse back and forth a little bit. Then it will start spinning up again. This cycle is repeating over a period of a couple seconds between each set of pulses. 

Did I miss a crucial part of the encoder integration or is there some other issue that I'm missing? Thanks for the help in advance.

  • You don't need to change and use the ENC module since you get the rotor position and angle from a absolute encoder, you need to calculate the rotor angle based on the data from the absolute encoder, can convert the data to _IQ24, tor eplace ENC_getElecAngle(encHandle) in the lab12a and other projects will be used. And then use lab12a to identify the motor inertia.
    The angle is electric angle, the formula is (encoder data*2^24*pole pairs/2^14 + Angle Offset), *2^24 is for converter data to IQ24, and 2^14 is the resolution of encoder. You must do offset calibration to get the angle offset as lab12a which is using Rs re-calculation to implement calibration.
  • Thanks for the quick reply Yanming, I've taken your advice and done away with the `enc` module entirely. Here's a summary of the replacement code:

    /***** In my AS5048A library *****/
    uint16_t AS5048A_spiA_read_repeatedly(HAL_Handle handle, AS5048A_Address_e addr)
    {
        /* ... reads encoder value via spi and returns counts to user ... */
    }
    
    _iq AS5048A_getMechAngle(uint16_t encoderVal, _iq mechAngleZero)
    {
        static const _iq oneIq = (((uint32_t)1) << 24);
        static const _iq gain = oneIq / AS5048A_MAX_COUNT;
        static const _iq wrapIq = 0x00ffffff;
        return (gain * encoderVal + oneIq - mechAngleZero) & wrapIq;
    }
    
    _iq AS5048A_getElecAngle(_iq mechAngle, uint16_t polePairs)
    {
        static const _iq wrapIq = 0x00ffffff;
        return (mechAngle * polePairs) & wrapIq;
    }
    
    
    /***** in the main "while(gMotorVars.Flag_enableSys)" loop *****/
    // Read encoder value into globals
    encoderVal = AS5048A_spiA_read_repeatedly(halHandle, AS5048A_Address_Angle);
    encoderMechAngle = AS5048A_getMechAngle(encoderVal, encoderMechAngleZero);
    encoderElecAngle = AS5048A_getElecAngle(encoderMechAngle, USER_MOTOR_NUM_POLE_PAIRS);
    
    
    /***** in the main ISR *****/
    // ...
    CTRL_run(ctrlHandle, halHandle, &gAdcData, &gPwmData, encoderElecAngle);
    // ...
    if((EST_getState(obj->estHandle) == EST_State_Rs) && (USER_MOTOR_TYPE == MOTOR_Type_Pm))
    {
        encoderMechAngleZero = AS5048A_getMechAngle(encoderVal, 0);
    }
    
    
    

    I'm still running into problems doing lab 12a. I'm looking at my values of mechanical and electrical angle and they seem to be working properly (with the same sign as the rotation direction of the motor that I identified from lab 3b). Whenever I start the identification process, the motor just pulses back and forth once, instead of going through the desired ramp up to the specified rpm. If I play around with the target rpm and ramp time a bit, I can get it to sometimes go only in 1 direction, but typically it just rotates about 10 - 30 degrees and then snaps back towards where it started. Needless to say, the inertia and friction estimates that it's coming up with are illogical (often negative). Any more pointers?

  • Were you able to resolve your question here? If so, I'll mark this thread closed. Please feel free to respond or start a new thread if the situation is otherwise.

    Sean
  • Unfortunately, no, the info + questions I posted in my earlier response still represents the (unsolved) state of my problem.

    Thanks,

    Isaac
  • The lab12x~lab13x projects are using incremental encoder, you have to design or change the position sensor interface function, not use ENC module directly if you are using an absolute position encoder. You need to do offset calibration also before used it and set the offset in setup fucntion.
    You may refer to "IDDK_PM_Servo_F2837x-v2" project to design the interface module as below.
    C:\ti\controlSUITE\development_kits\TMDSIDDK_v2.0\IDDK_PM_Servo_F2837x_v2_00_00_00
  • Isacc,

    Have you have your problem taken care of? If not, I have some advice that may help you.

    The zero angle of your electrical angle must align with the magnetic axis in your motor.

    If you haven't run through lab1-3, please do so and compare the electrical angle output of your sensor to the output of EST_getAngle_pu() and see if they match. If you can match them, then you can try to replace angle_pu (ctrl.h) with your sensor output.

    After you have the sensor taken care of, you can run lab4 (with angle_pu being replaced with your sensor output) to have your current loop PI tuned.

    After having the above done, trying going back to lab12 and identify your motor parameter. Hope this will solve your problem.

    Best regards,
    Han
  • Han,

    I tried your suggestion of going back to early labs to get the encoder integrated and am happy to report that we able to get the motor to successfully achieve position control (lab 13b). Going back to labs 1 and 2 were very helpful because I was able to plot the estimator electric angle vs our encoder's electric angle, which helped us determine that we were actually using the wrong number of pole-pairs for our motor (correct value was 7 pole-pairs, we originally interpreted our spec-sheet to say that we had 14 pole-pairs, while we actually had 14 poles). After correcting this, zeroing the encoder's mechanical/electircal during the EST_STATE_RS step was adequate to line up the zeros of the encoder and the electrical angle. We were able to go through labs 2a, 12a, 12b, 13a, 13b with our encoder electrical angle used in place of the estimator / QEP electric angle.

    My primary issue is now resolved, but I have a follow up question related to some of the behaviors I was seeing in these labs. When using the encoder electric angle to drive the motor in lab 2a, we noticed that driving below about 80 rpm would produce weird behavior (periodic twitches / seizing). Do you think this could be a result of not sampling the encoder fast enough or perhaps having some lag/inaccuracy in the measurement? During labs 12b, the motor was able to spin at lower rpms (even down to ~20 rpm or so) much better, but still had some jitters in the rotation. Both modules were able to spin the motor reliably at >100 rpm.

    Thanks,

    Isaac

  • Issac,

    What frequency are you running the encoder at? When the speed is very low, the details does matter. For example, it will help a lot if you can synchronous the sensor with the control interrupt. I am not sure if that is the case now.

    One other thing you can try is to manually add some torque load by holding the motor shaft and see if it make any difference on your result. Thanks.

    Best regards,

    Han 

  • Han,

    Our encoder is being sampled via SPI the main loop (not the control ISR). I scoped the lines and can see the period of samples is about 0.3 ms. It doesn't seem like adding resistance torque to the motor does anything to improve the performance. Does 0.3 ms seem like a large enough time to cause issues with synchronization? I tried moving the sample to within the control ISR and it doesn't seem like it helps performance at low rpms much.

    Thanks,

    Isaac

  • Hi Isaac,

    Here are some hints may help you:

    1. The time you read the SPI bus is not the time the sensor samples. You can try to dig into the documentation of the sensor to see if there are any way you can control / sync the sample from MCU.

    2. Can you try to run the motor in open-loop (speed loop) at the same slow speed and see if the jitter still exist? You can isolate the speed loop and current loop issue by doing this.

    3. Since the motor is running at a slow speed, can you tell if the jerk has any pattern (for example: in relation to mechanical phase of the rotor / fixed time period)?

    Thanks.

    Han
  • Han,

    Thanks for the tips, here's what I've found : 

    3. (answering 3 first because it might better inform you on the other ones) The motor appears to momentarily come to a stop and then continues on its normal rotation. The jerks are *very* periodic -- when running at 20 rpm it seemed like they were evenly spaced with about 7 per full rotation of the motor (maybe because we have a 7 pole pair motor?). If I run even slower (10 rpm) the motor looks like it is individually stepping between pole directions -- pausing for maybe a quarter of a second at each of 14 evenly spaced locations around the motor. 

    1. I couldn't find anything on synchronizing the sampling time in the encoder specifications. I do see a specified "system propagation time" of 100 microseconds, but other than that, it's my understanding that the sensor is sampled at the time I initiate the SPI exchange.

    2. I ran lab1b to test the open loop control of the motor and it seemed to be working much better at slow speeds (even down to ~20 rpm) than when I run in with the sensor. It definitely has some vibration in the motor, but nothing like the periodic jerks described above.

    Thanks,

    Isaac

  • Isaac,

    Based on your description, it seems the ripple may have something to do with "cogging torque". You may try to measure the back-EMF waveform shape by spinning the motor with external torque at "constant speed" and measure the voltage waveform between two terminals. If this waveform is not sinusoidal signal, the torque generated with sinusoidal voltage will not be smooth.

    For the openloop test, I was suggesting open speed loop (while close current loop). You may want to try lab05a and see the response. Thanks.

    Best regards,
    Han