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.

RsRecalc : inject a DC current to the D-axis?

Other Parts Discussed in Thread: MOTORWARE

I understand that when the Flag_enableRsRecalc is true, The estimator will inject a DC current to the D-axis to recalibrate the stator resistance before the motor rotates. when this happens it also causes aligning of the eQEP angle with the rotor angle. But, I am not sure how do we set the amount of DC current that gets injected. Is there a Variable that defines this value?

  • Did i understand it right if I say USER_MOTOR_RES_EST_CURRENT is the DC current that gets injected?
  • correct. the -motion projects use the built-in RsRecalc function to inject the Id current (as defined in user.h value noted). if this works for your application, fine. other customers have simply created their own alignment logic without using RsRecalc.

    you do need to use enough current to insure the rotor moves with any load that may be present.
  • Yes. It's for very short period so I could  push a lot of dc during Rs recalculate step to align.

    I am curious if you are aware of other alignmentioned logics because this method is relative  and  not absolote.

  • for absolute you would need a sensor with an absolute based signal or at least an index

    both are used in servo drives
  • Thankd Chris.

    Rs recalculate only aligns to one of the many points on one revolutiom, that line up with zero electrical angle. But with many pole pairs, i dont know which point it aligned to.

    My encoder has an index. So, I was planning to use the rs recalculate alignment to get started and then find the index and re-intialize when it finds the index. What do you think about this approach?

    Mounting an encoder such that the index lines up with the nearest point of zero electrical angle would be magical but it could also be pretty tough.

    If you can point me to other alignment logics / docs for bldc pmsm motor, i would love to learn
  • Subrat,

    You can do that, but I think you will end up running into more issues with ensuring that your motor is aligned once you "rezero" to the index line.  Depending on the alignment of the motor and encoder during manufacturing this could be very different from motor to motor.

    I think you would be better served by using the index line as a mechanical "home" switch in your application.  This way you will be aligning your application and not worrying about disrupting the functional motor control part of the software.  SpinTAC Position Move is all relative position moves, so once you have your application home it becomes easy to track the application position relative to that.

  • Hi Adam. 

    Good suggestion. 

    Right the problem is that every time the encoder is mounted /aligned to the motor, the index position wont be at the exact same spot and it will be different from motor to motor.

    If i need to make my rotor move to a desired mechanical angle which is relative to a fixed home position.  For example, in my application the motor is attached to a prop with two blades and while the plane is landing the blades need to be aligned such that they stay horizontal to the ground. I guess this is much simple than most position control applications because the horizontal position doesn't have to be super accurate to the order of micro degrees. 

    First, Thing about RsRecalc alignment is that it needs to push enough DC to make the rotor move to the nearest point where electrical angle is zero. what if the motor on powerup cant rotate. But in my application I think its ok for the prop's on the plane to twitch a bit, given that its has lots of poles the angle it needs to rotate during RsRecalc alignment will be small and not as high as in case of a 2 or a 4 pole motor. So, I can totally use RsRecalc alignment.

    Second, since you guys are not using the index, if due to noise or EMI, the encoder misses or distorts an edge on A or B channels, the counter will register erratic counts and the error will keep growing over time and revolutions, it wont get reset until the system is power cycled. Having an index helps re-set the accumulated error once in every revolution. I agree that I could use the A and B of the quadrature encoder like you guys have used to find electrical angle so the motor controller knows how to commutate. Yet, I still want to be able to reset the counter with an index if possible once in every revolution. 

    Now, if we assume that the position counter always keeps reading accurate position using just signals A and B but no Index, then the commutation can keep working fine. It starts wherever it wants to start and then when it hits index, i can log the count number as home, then everything will be relative to this home position. so i see your point, the index position wont zero the encoder counter but it will just be used by the SpinTAC Position Move. I just got through lab 13b and i can command new desired position relative to current position but i want to be able to command desired absolute position relative to home position..   

  • Subrat,

    subrat nayak said:
    Second, since you guys are not using the index, if due to noise or EMI, the encoder misses or distorts an edge on A or B channels, the counter will register erratic counts and the error will keep growing over time and revolutions, it wont get reset until the system is power cycled.

    The eQEP module on the MCU is configured so that it will reset the count after is has reached the maximum count.  So the count is reset each mechanical cycle.  If there is a missed edge it will only shift the angle by 3/<total encoder count> * 360 degrees, which is very small.  

    If you want to rezero the encoder on the index that would probably be fine, it would just be tricky to make sure everything stayed aligned.

    subrat nayak said:
    but i want to be able to command desired absolute position relative to home position..   

    When we designed SpinTAC Position Move, we started thinking about how to handle absolute positions and we determined that the large variety of ways that customers would want to do absolute positioning plus the ranges of positions made it too difficult to cover all cases.  So we decided that making SpinTAC Position Move only handle relative position movements and relying on the customer to handle converting their absolute system to command relative steps was the easiest way to enable the most people.

  • HI Adam,
    In response to your statement : "The eQEP module on the MCU is configured so that it will reset the count after is has reached the maximum count. So the count is reset each mechanical cycle. If there is a missed edge it will only shift the angle by 3/<total encoder count> * 360 degrees, which is very small. "
    Lets say the counts per rev is 1024, so every time the encoder count reaches 1024, and wants to increase it gets reset to 0 and counts up to 1 next. Now, if it missed an edge then at 1025 counts it will register it as 1024 and then for any increase it gets reset to 0. What happened here? the real mechanical position is off by 1 tick but the system thinks its not off by 1 tick. so resenting the count doesn't really make up for the missed edge. If it misses 1 tick every rev, after 10 revs it has actually missed 10 ticks and off by 10 ticks in mechanical position so it think that its at the right desired mechanical position.
    But if the count was reset at index pules rather than when it reached max count, the advantage is that lets say after 1 rev, the enc count should be 1024 but some how its 1023 because it missed 1 tick its still reset which means the real mechanical position and perceived mechanical position got realigned. So even if it misses some ticks per rev, after every rev the re-synch makes sure that over time the error in mechanical position never adds up. That's why they have an index, without an index the error keeps adding up.
  • I managed to get my spintac position controller working with a 11 pole pair motor with a encoder with 8192 ticks per rev ( i entered 2048 in the user.h). And both spintac position and velocity control works fine. In lab 12b i see the rpm due to FAST and encoder look the same.

    But i am struggling with another motor with 42 pole pairs and same encoder. In lab 12a, it starts up  and speeds up to max speed during Intertia estimation but the rpm due to Enccoder stays at 0 so i get error 2004. In lab 12b, i see the rpm due to FAST goes up to 1k rpm when its supposed to be 0.1 rpm while the rpm due to Encoder stays at zero. the encoder signals are coming in fine, i can see the encoder counter goes from 0 to 8192 and then back to 0. Any clues what might be going wrong?

  • It sounds like SpinTAC Position Convert is not running.  Check and see if there are any error code form that component.  A list of error codes is available in the User Guide.

  • Hi Adam,

    I tested lasb 12b with two motors
    1) PM motor with
    USER_MOTOR_NUM_POLE_PAIRS (11)
    USER_MOTOR_ENCODER_LINES (2048.0)
    USER_IQ_FULL_SCALE_FREQ_Hz (403.3)

    2) PM motor with
    USER_MOTOR_NUM_POLE_PAIRS (42)
    USER_MOTOR_ENCODER_LINES (2048.0)
    #define USER_IQ_FULL_SCALE_FREQ_Hz (1155.0)

    Everything works great with Motor 1) with the same encoder but with Motor 2), as soon as i make VelIdRun = 1, the motor starts fine,
    and speeds up to max rpm and just keeps spinning but the Interia Identification process fails with an error VelIdErrorID 2004. I looked at the variables :
    gMotorVars.Speed_krpm which looks perfectly fine but gMotorVars.SpeedQEP_krpm stays at ZERO while the motor is spinning as fast as it can.
    In case of Motor 1) the gMotorVars.SpeedQEP_krpm values matches that of gMotorVars.Speed_krpm in lab 12b)

    When you said error code, did you mean in the usere guide?
    12.2.5 Troubleshooting SpinTAC Velocity Control
    12.2.5.1 ERR_ID
    and
    12.4.5 Troubleshooting SpinTAC Position Control
    12.4.5.1 ERR_ID

    I am not sure what variable should I look for to know ERR_ID? I didnt see any variable named ERR_ID in the various header files. Please advise.


    I also did some digging around the code and variable values

    HAL_getQepPosnCounts(halHandle)
    seems to work fine, I can rotate the Rotor by hand the result of this function seem to be fine , changes from 0 to 4*USER_MOTOR_ENCODER_LINES

    ENC_calcElecAngle(encHandle, HAL_getQepPosnCounts(halHandle));
    seem to be working fine too, the Electrical Angle seems to change form 0 to 1 and then down to 0. I didnt know what to expect. what do you think?
    The variables are all 32bit and the code works for other motors with same encoder but 11 number of porl pairs rather than 42, so my guess is that there is
    nothing wrong happening in this function

    My guess that some thing is not working in these 4 functions for Motor 2) though it works fine for Motor 1).
    // setup the SpinTAC Components
    ST_setupVelId(stHandle);
    ST_setupPosConv(stHandle);

    ST_runPosConv(stHandle, encHandle, ctrlHandle);
    ST_runVelId(stHandle, ctrlHandle);

    I would really appreciate some guidance to figure this out.

  • Subrat,

    subrat nayak said:
    but gMotorVars.SpeedQEP_krpm stays at ZERO while the motor is spinning as fast as it can.

    The issue is with SpinTAC Position Convert.  This component converts electrical angle into speed feedback.  Look for the ERR_ID or Error Code for this component.

    subrat nayak said:
    When you said error code, did you mean in the usere guide?

    Yes, every SpinTAC component has error codes that are provided via ERR_ID.  In the lab look for the function STPOSCONV_getErrorID.

    Once you have found the error code look in section 18.3.2 Troubleshooting SpinTAC Position Convert in the User's Guide.

  • Hi Adam,

    In lab 12(a) code, 

    the function :

    void updateGlobalVariables_motor(CTRL_Handle handle, ST_Handle sthandle)

    has the line 

    // get the Position Converter error
    gMotorVars.SpinTAC.PosConvErrorID = STPOSCONV_getErrorID(stObj->posConvHandle);

    So, in the variable window I looked for variable gMotorVars.SpinTAC.PosConvErrorID, it never changed , stayed at 0.

    while the gMotorVars.SpeedQEP_krpm value stayed at 0,

    the gMotorVars.Speed_krpm went upto 1.2krpm 

    I made a variable

    // get encoder count
    gMotorVars.EncCount = HAL_getQepPosnCounts(halHandle);

    whose value changes fine from 0 to 4 x USER_MOTOR_ENCODER_LINES

    Any more suggestions?

    thanks

    subrat

  • Subrat,

    Have you made any code modifications to the lab?

    What is the value for the variable st_obj.vel.conv.STATUS?


  • Hi Adam,

    Lab 12(a) code is untouched. exactly what was in Motorware 15.

    It works fine for 

    1) PM motor with 
    USER_MOTOR_NUM_POLE_PAIRS (11)
    USER_MOTOR_ENCODER_LINES (2048.0)
    USER_IQ_FULL_SCALE_FREQ_Hz (403.3)

    but doesn't work for

    2) PM motor with 
    USER_MOTOR_NUM_POLE_PAIRS (42)
    USER_MOTOR_ENCODER_LINES (2048.0)
    #define USER_IQ_FULL_SCALE_FREQ_Hz (1155.0)

    For lab 12(a) when I made gMotorVars.SpinTAC.VelIdRun = 1, the motor speeds up to max rpm and then it stops with gMotorVars.SpinTAC.VelIdErrorID = 2004. 

    st_obj.vel.conv.STATUS stays ST_POS_CONV_IDLE this whole time.

    But with the 11 pole motor, the st_obj.vel.conv.STATUS stays ST_POS_CONV_BUSY the whole time.

  • Subrat,

    subrat nayak said:
    st_obj.vel.conv.STATUS stays ST_POS_CONV_IDLE this whole time.

    This is the issue.  If SpinTAC Position Convert is in IDLE is it not converting the motor electrical angle into speed feedback.  My guess is that it has some sort of configuration error.  You can also check st_obj.vel.conv.ERR_ID to see what the error is.  This is especially true since the same configuration works for your 11 pole motor.

  • Hi Adam, 

    I looked at st_obj.vel.conv.ERR_ID and the value stays at 0 all the time.

    I have the same guess that its some sort of configuration error given that i have much higher numbers for

    USER_MOTOR_NUM_POLE_PAIRS

    and 

    USER_IQ_FULL_SCALE_FREQ_Hz.

    You think some number is overflowing?

  • Subrat,

    I'm surprised that the error code is not showing up correctly. I had a chance to look inside the code that makes up SpinTAC Position Convert with your settings in mind and the issue is that the pole pairs are too large. InstaSPIN-MOTION will support up to 32 pole pairs. This is to prevent overflows due to working with fixed point numbers.

    A workaround could be to tell SpinTAC Position Convert that the pole pairs are half of the true value. This will have the effect of all commands will be halved from the input value. So if you command 10 revolutions, the motor will only do 5. Similarly with the velocity limit. a limit of 4000 rpm will be seen on the motor shaft as 2000 rpm. I would not recommend changing the pole pairs to other components in the system aside from SpinTAC Position Convert. I tested this on a 4 pp motor and didn't see any issues.
  • Great! thanks for finding this.

    All of instaspin works fine with 42 pole pairs.

    I think its ok to try the workaround and enter half the number of pole pairs.

    But I didnt get the " I would not recommend changing the pole pairs to other components in the system aside from SpinTAC Position Convert. " .Did you mean i should not change the
    USER_MOTOR_NUM_POLE_PAIRS (42) to
    USER_MOTOR_NUM_POLE_PAIRS (21)

    If not then, Where else should I change it?

    thanks
    Subrat

  • You can try changing that number. It should work ok.

    I changed the number of pole pairs provided to STPOSCONV_setUnitConversion in the ST_setupPosConv function inside spintac_position.h
  • Can this pole pair limit of 32 be fixed and raised to much higher numbers in Motorware 16 that is about to be released?

    thanks

    subrat

  • We are discussing. We have essentially locked the release already. While this is a minor change we should still do more thorough testing. Not sure if we will be able to do that in time.

  • Was the fix for the 32 pole pair limit in spitach position convert got added in Motoware 16?
  • I believe that did make it into MotorWare 16.
  • it is included in the release notes
  • Hi Adam and Chris,

    I really wanted to thank you guys for squeezing in the fix in such short time. It works great.

    thanks a lot. BTW, instaspin is driving the motors on the Facebook's solar powered drone . Details here : www.wired.com/.../

    We made the motors and controllers for the drone at Joby Aviation and I wrote wrapper code on top of Instaspin for my controllers. Its operating at 60v dc bus, 5 kw and we are very happy with Instaspin and spintac.

    thanks
    subrat
  • Subrat,

    I'm glad it worked well and you were able to get the motor spinning!
  • Now that is really cool! Thanks for letting us know, and thanks for using InstaSPIN!
  • Hi Adam,

    I am still having some issues with holding position.

    In Lab 13b, When i command number of rev in gMotorVars.PosStepInt_MRev, the Motor spins and then hold the end position pretty well.

    But for input values in gMotorVars.PosStepFrac_MRev, for some values the Motor spins and holds end position pretty well while for some values, it spins but cannot hold the end position very well and just keeps twitching forever.

    I have
    #define USER_MOTOR_NUM_POLE_PAIRS (42)
    #define USER_MOTOR_ENCODER_LINES (2048.0) // the encoder has 8192 ticks per rev, so (number of ticks on encoder per rev) / 4 = 2048

    My guess is there is some sort of fraction/decimal precision error happening so the motor has tough time holding position for certain inputs.

    Increasing the gMotorVars.SpinTAC.PosCtlBwScale doesn't do much, it just reduces the oscillation amplitude to a certain min value of about 0.01 degrees and then it doesn't further reduce the oscillation amplitude , the oscillation keeps going on for ever with much higher frequency for higher values gMotorVars.SpinTAC.PosCtlBwScale. If the min value of oscillation amplitude was very very low, the high-frequency oscillation will probably not be visible but its not low enough so the rotor seems to be constantly twitching forever.

    But for certain inputs values for gMotorVars.PosStepFrac_MRev like 0.5 or 0.25 or just inputs numbers for gMotorVars.PosStepInt_MRev, there is no twitching for ever, it holds the end position pretty well.

    Any idea what's going on?

    Any ways to provide an allowable error in position parameter to the spintac controller so that if the position is within certain range from the desired position, the rotor can just stop trying to be perfect and just hold that position?

    PS : I cant increase the USER_MOTOR_ENCODER_LINES because I am using the highest resolution that i can find in the encoder model/footprint that the motor was designed for. The reason I say this is that when i used an encoder of same footprint and model with much lower resolution at 1024 rather than 8192, the problem was much worse. So the only way to increase encoder resolution would be to re-design the motor for a different model of encoder with much higher resolution and that is tough to do right now. Maybe we can do that in future revisions.

  • Any updates Adam? 

  • Subrat,

    My guess is that the commanded position is in between two discreet positions on the encoder.  So in this case the controller cannot ever achieve the desired goal position.  With your encoder you have a minimum possible resolution of 0.044 (360/8192) mechanical degrees.

    You could look at increasing the update rate of the position controller.  This can help increase the performance of the controller.  The parameter to adjust is the USER_NUM_CTRL_TICKS_PER_TRAJ_TICK.  By decreasing this value it will increase the update rate of the controller.