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.
Hi
We are experiencing a problem using the TI evaluation board DRV8301-HC-EVM Rev D powering a Sonceboz motor (model 5642 - 5 pole pairs, low inductance). Our problem occurs when using lab 12b for velocity control with quadrature.
If we use a 1000 line encoder feeding into the QEP, we get one of two behaviours depending on the starting angle of the motor: either it is fine, or it runs backwards at full speed. When running backwards the problem appears to be something to do with the output – the velocity speedQEP_krpm is correctly measured as large and negative, the error signal is large and the controller is requesting (and getting) maximum current. The motor has 12 detents and starting from half of these gives the problem, the other half gives perfectly normal control. It is completely repeatable. If we use the FAST estimator instead of QEP (lab 5d), it works correctly in all start positions (although the RPM is not very smooth).
When working normally, EST_getAngle_pu() and ENC_getElecAngle() track reasonably well. When not working, the former angle rises as before but the encoder derived angle falls very slowly for about one (electrical) revolution; then both angles change so quickly that we cannot sample them.
Thanks for any help.
RsRecalc is enabled in lab 12b and I've not changed that. RES_EST_CURRENT, I thought, was used only for motor identification, nevertheless it is set to 3 amps for my 40 amp rated motor.
Do you refer to this line of code where the relationship between mech and electrical angle is created?
// if we are forcing alignment, using the Rs Recalculation, align the eQEP angle with the rotor angle
if((EST_getState(obj->estHandle) == EST_State_Rs) && (USER_MOTOR_TYPE == MOTOR_Type_Pm))
{
ENC_setZeroOffset(encHandle, (uint32_t)(HAL_getQepPosnMaximum(halHandle) - HAL_getQepPosnCounts(halHandle)));
}
Thanks
RES_EST is used in motor ID. It is also used anytime you recalibrate the Rs with the Flag discussed in lab03.
in lab12 this is mentioned:
This project will setup the calibrated angle of the encoder. This ensures that both the encoder and the motor are aligned on a zero degree electrical angle. This step is done when the FAST™ estimator is recalibrating the Rs value of the motor.
if you have a load attached you need to insure that RES_EST is large enough to move the rotor so that it will align with the D axis.
Rich,
I think Chris' answer is spot on. We need a good alignment between the motor and the encoder in order to have good control of that motor. If the encoder alignment is off by 90 degrees, it can result in the motor trying to apply positive torque but the motor rotating in the negative direction which results in the motor running away.
The trick we use for alignment in Lab 12a-13e is really not designed to be used in a final application. Ideally you would have some sort of absolute sensor or home switch in the system so that you don't need to rely on this method to align the encoder and motor at power up.
In the sensored labs, FAST is still running, but if you look at the CTRL_runOnline_User function in ctrlQEP.h file, the electrical angle comes from the encoder and not FAST. So even though FAST is generating an electrical angle it isn't being used.
Hello again Adam
Adam upon your advice I set RES_EST_CURRENT to a little higher - 10 amps - and my max current is 20 amps. Motor is rated to 40 amps. Ever since the first time I ran my lab 12b with 10 amps RES_EST, my program starts, runs about 164 ISR calls and a few background loops and then the program counter ends up at 0x3FF4FA. This is inside the bootloader. I'm not sure if it resets yet, I can find that out tomorrow morning. I suspect it is. The stack pointer interestingly is 0x000C not the 0x0400 like the manual says it should from reset. Maybe the proceeding bootloader code is modifying that.
Do you know what is/has happened here? Is my eval board damaged? Obviously reverting back to 3 amps from 10 RES_EST doesn't cure this, and other labs now fail in the same way.
Hope you can help here.
Thanks
Rich
Rich,
Since you are using the DRV8301 board, 10A should not have damaged it. I'm not 100% sure why the program counter is going back into the bootloader. Is it possible that your power supply is causing the microprocessor to go into a low power state?
Anything I suggest on this would be pure speculation. Have you tried a different evaluation board to see if the problem is hardware related or software related?
Hi Adam,
We clearly need to get the electrically aligned angle to the PARK and INV PARK routines (I'm looking at figure 3-3 of the InstaSpin manual), but do the values for Theta_Qep or the user demand angle User_PDSRef also need to have the electrical angle aligned to the motor or can they tolerate an offset? It looks to me as if they can - they are converted into a velocity demand and offsets get differentiated out. Here's why I ask.
In our application, the controlled quantity is x, the linear displacement of an actuator which is an invertible but slightly non-linear function of the motor angle. We need to have high resolution angle input to get the required position tolerance and were intending to use
<electrical angle> = 5 * <motor angle determined from linear position>
for both demand and calculated electrical angle (it’s a five pole pair motor). There is no alignment of the linear position of the actuator to the motor’s angle and this is the cause of our problem.
We need to supply at least the Park and Inverse Park routines the correctly aligned electrical angle. We have Hall effect phase sensors on the motor which tell us which 60° electrical segment we are in and can use the transitions, plus possibly the FAST initial estimate, to get better alignment; in effect the function becomes
<electrical angle> = 5 * <motor angle determined from linear position> + <angle offset estimate>
where <angle offset estimate> is the estimate of the electrical angle at x = 0.
However our knowledge of the electrical angle as a function of the linear position is not sufficiently accurate for the requirement of ±5° electrical accuracy to maintain torque, and we must modify the electrical angle estimate every time we cross a 60° electrical segment. If we feed this updated value of to the User_PDS Ref and ThetaQep, this will appear as a step change in both values with a delta like velocity. We can of course smooth the step changes, but this is disguising rather than solving the problem. It might be better to use the uncorrected angle estimate (not aligned to the rotor's electrical angle) for the control side, and just use the aligned angle for the Park and Inverse Park transforms. However I’m worried about what we don’t know!
Sorry for the length of this, couldn't make it shorter without diagrams.
Graham,
The angle ThetaQEP should be electrically aligned since that is the angle that is provided to PARK and INV PARK.
User_PosRef shouldn't be an angle. It should be the number of mechanical revolutions that you want the motor to rotate. So this is a position step command.
For SpinTAC Position Control, you only need to provide the electrical angle back into the SpinTAC Position Converter. So if you have a scheme that can be used as the electrical angle to feed into the PARK & INV PARK, that same angle should be feed into the SpinTAC Position Converter which will translate the electrical angle into the mechanical revolutions that the rest of the position solution operates on.
Rich,
Zero electrical angle should refer to aligned with the A phase of the motor.
Hi Adam
Do you have a diagram, or is there a diagram on the net that explains this?
You talk of current but most diagrams, including our motor's diagram, use voltage on the Y axis. Does this change things?
Our motor is of a delta shape, not Y - does this change things?
When you say "through phase U", between what two points would you measure that?
I think its a topic area for users of InstaSPIN who are doing slow speed control and need accurate electrical angle. Some upgrade to the documentation would be most useful. Text and diagrams.
Kind regards
Rich
Rich,
I don't have a diagram handy to explain this. Your best bet would be to do some research around vector control to understand this control methodology better.
Vector control is more concerned with current while trapezodial control is more concerned with the voltage. So when I say all of the positive current is flowing into phase U it means that half of the current is flowing out phases V & W.
Delta versus Y connected motors doesn't change anything. The controller assumes Y connected motors, so it will treat your delta motor as if it was a Y, which is a valid way to control it.
Hi Sanet
Firstly I wired up five GPIO lines to my five Hall sensors. I wrote a C function which converted five levels to an electrical angle in iq.
In mainISR I wrote code at the top to run only once; it sampled the Hall sensors, set a flag to indicate the code should not run again, then alter enc.zero_offset (or whatever it's called) after knowing the electrical angle from the Halls. You will need to do some iq math to get this angle right. Also, you need to know what InstaSPIN _wants_ as the zero electrical angle.
Altering enc.zero_offset is easier than trying to use the setter function, imho.
So i have something like enc.zero_offset = derivedElecAngleIq;
I can give you more details when I am back from holiday on Monday.
Also of help to me was having a variable which allowed me to vary the electrical angle by an offset between the ENC having its elecrical angle read and where that angle is used. I think it is sent to CTRL. I will post that when i'm back.
Rich
hi rich,
Concerning the code of the Hall sensor, do you have more details?
Regards,
My code for calculation of angle is this. Please only use this to understand what I am doing, then write your own.
---------------------------------------------------------------------------------------------------------------------------------------------------------------
#define SEGMENT_SIZE 30
#define MID_POINT_FROM_EDGE_OFFSET 15
// indexed by the bits Sa, Sb, Sc, Ha, Hb in that order, MSB first.
static const uint16_t motorSensorAngles[32] = {
65535, // 000 00
65535, // 000 01
65535, // 000 10
65535, // 000 11
8, // 001 00 F
8, // 001 01 y
9, // 001 10 F
9, // 001 11 y
0, // 010 00 F
0, // 010 01 y
1, // 010 10 F
1, // 010 11 y
11, // 011 00 y
11, // 011 01 F
10, // 011 10 y
10, // 011 11 F
4, // 100 00 F
4, // 100 01 y
5, // 100 10 F
5, // 100 11 y
7, // 101 00 y
7, // 101 01 F
6, // 101 10 y
6, // 101 11 F
3, // 110 00 y
3, // 110 01 F
2, // 110 10 y
2, // 110 11 F
65535, // 111 00
65535, // 111 01
65535, // 111 10
65535 // 111 11
};
_iq ANG_getElecAngle (uint16_t* hallBits, uint32_t* mapErrors, uint32_t* inDegrees)
{
_iq rtnElecAngle_pu;
// Grab phases:
uint32_t gpioBdata = ((GPIO_Obj*) hal.gpioHandle)->GPBDAT;
uint32_t gpioAdata = ((GPIO_Obj*) hal.gpioHandle)->GPADAT;
// Data needs to be Sa Sb Sc H1 H2:
gpioAdata >>= 7;
// H1 stored at b2
// H2 stored at b0
gpioAdata &= 0x05;
uint16_t H_12 = (gpioAdata >> 1) | (gpioAdata & 0x01);
gpioBdata >>= 8;
gpioBdata &= 0x000007; // only 3 LSBs are valid
uint16_t S_abc = ((gpioBdata & 1) << 2) | (gpioBdata & 2) | ((gpioBdata & 4) >> 2);
*hallBits = (S_abc << 2) | H_12;
if (motorSensorAngles[*hallBits] == 65535)
{
// do not update motorElecAngle
*mapErrors += 1;
}
else
{
*inDegrees = (motorSensorAngles[*hallBits] * SEGMENT_SIZE) + MID_POINT_FROM_EDGE_OFFSET;
}
rtnElecAngle_pu = (((((uint32_t) 1) << 24)) / 360) * (*inDegrees);
return rtnElecAngle_pu;
}
This code is in my lab13a main C file (copy of). It uses the above function to alter the ENC offset.
---------------------------------------------------------------------------------------------------------------------------------------
// Get angle:
gMotorElecAngle_pu = ANG_getElecAngle((uint16_t*) &gMotorSegValue, (uint32_t*) &gElecAngleMapErrors, (uint32_t*) &gMotorElecAngle_deg);
if (!gElecAngleCalibrated)
{
// Get calibrating:
static uint16_t lastH12 = 0xFFFF;
uint16_t currentH12 = 0x0003 & gMotorSegValue;
if (lastH12 != 0xFFFF)
{
// compare to current
if (lastH12 != currentH12)
{
// found an edge somewhere
gElecAngleCalibrated = true;
}
}
else
{
// update the "last" with a real value
lastH12 = currentH12;
}
gElecOffsetQep_pu = (gMotorElecAngle_pu - gElecOffsetMotorToReal_pu);
enc.enc_zero_offset = (_iq) (gElecOffsetQep_pu / 5);
enc.enc_zero_offset &= 0x00FFFFFF;
}
-----------------------------------------------------------------------------------------------------------------------------------------
That code comes just before this, in mainISR()
// compute the electrical angle
ENC_calcElecAngle(encHandle, HAL_getQepPosnCounts(halHandle));
Hi Rich,
thank you verry much for your reply.
at first I have to chew your code, then I will adapt it with my project.
Best regards,
Hi Rich,
my motor contains a hall effect sensor (3 sensors, 1 for vcc, 1 for ground), knowing in project I use dvr8312 C2-kit, I wired them into J10 (following guide steps).
how did you code this function : motorSensorAngles[32] ?
do you have diagrams or something else of organisation chart following your code?
Best regards
Ok, that array maps from 5 Hall sensor binary values to an offset into a function described in my motor datasheet. I'll attach a picture of that. This C code line then calculates an electrical angle:
*inDegrees = (motorSensorAngles[*hallBits] * SEGMENT_SIZE) + MID_POINT_FROM_EDGE_OFFSET;
Here's the angles diagram for my motor:
So five Hall sensors: Sa, Sb, Sc, and H1 and H2. Together they make 2 ^ 5 = 32 possible values. However not all of the 32 values map onto the electrical diagram, some are invalid. So 65535 represents a sensor electrical lookup error.
Firstly, are you sensors wired up correctly so that you can see the levels changing in software? I had to use pull-ups with my sensors, for example.
Secondly, if you post your datasheet maybe I can help you create a lookup table similar to mine.
Hope this helps - this part was quite a fun part of my project!
Rich
EN_7000_05016.pdfHi Rech,
waw thank you for your quick reply :)
1- yes I connect them coorectely and 'pull-ups' with resistances R56,R57, R58 are installed in my card baord drv 8312.
2- my datasheet is attached (see page 24 & 26)
Best regards,
Hi Rech,
waw thank you for your quick reply :)
1- yes I connect them coorectely and 'pull-ups' with resistances R56,R57, R58 are installed in my card baord drv 8312.
2- my datasheet is attached (see page 24 & 25)
Best regards,
Rich,
In one mechanical revolution (ie in my motor 2 electrical revolution because the motor number poles are 4), hall sensors detect the passage of a magnetic pole
witch allows switching of the coils by the control circuit.
on the page 24 is mentionned "Signal setup: The Hall signals are 120° out of phase with each other according to the phases. Due to the 4-pole version, the
switching frequency is twice as high as the speed" -----> 120 ° is mechanical one.
Can you explain more this portion of your code :
gpioAdata >>= 7; // H1 stored at b2 // H2 stored at b0 gpioAdata &= 0x05; uint16_t H_12 = (gpioAdata >> 1) | (gpioAdata & 0x01); gpioBdata >>= 8; gpioBdata &= 0x000007; // only 3 LSBs are valid uint16_t S_abc = ((gpioBdata & 1) << 2) | (gpioBdata & 2) | ((gpioBdata & 4) >> 2);
best regards,
rich,
I found this array following Hall C LSB and Hall A MSB :
65535 // 0 => error
3 // 1
1 // 2
5 // 3
4 // 4
6 // 5
2 // 6
65535 // 7
?
Rich, I don't find as your suggestion, can you clarify it more (example 0 // 6)
Regards,
Hi there Sanet
Okay each row holds a number (the offset into the angle, or state as you call it, starting at 0 to 5). Then the // is a comment of the decimal value of index of that array entry. The number derived from your three Hall bits is the index into the array.
So 0 // 6 (there should be a comma after the 0) is state 0 for array index 6.
Please put commas after each number before the comments, I forgot those!
Rich