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 all,
I've run up against a wall with the dreaded Insta-spin Motion Lab 12b. After completing the RsRecalc estimation, the motor spins to a nearby position between two poles and locks. The motor shaft is vibrating slightly, and I can observe this with an oscilloscope on either of the A or B encoder lines. No matter where I set the value of USER_MOTOR_RES_EST_CURRENT, the locked rotor current is fixed at 2.13A, regardless of the setting for USER_MOTOR_RES_EST_CURRENT in user.h
For background's sake, I've run through the preceeding Instaspin Motion Labs and have the following parameters in the user.h file:
#elif (USER_MOTOR == Yaskawa_USASEM08FJ21_3POLE)
#define USER_MOTOR_TYPE MOTOR_Type_Pm
#define USER_MOTOR_NUM_POLE_PAIRS (3)
#define USER_MOTOR_Rr (NULL)
#define USER_MOTOR_Rs (0.6203403)
#define USER_MOTOR_Ls_d (0.003396241)
#define USER_MOTOR_Ls_q (0.003396241)
#define USER_MOTOR_RATED_FLUX (0.522265)
#define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
#define USER_MOTOR_RES_EST_CURRENT (1.0)
#define USER_MOTOR_IND_EST_CURRENT (-1.0)
#define USER_MOTOR_MAX_CURRENT (5.3)
#define USER_MOTOR_IDENT_FREQUENCY_Hz (20.0)
#define USER_MOTOR_FLUX_EST_FREQ_Hz (80.0)
#define USER_MOTOR_ENCODER_LINES (4096.0)
#define USER_MOTOR_MAX_SPEED_KRPM (3.0)
//as defined using SpinTAC
//#define USER_SYSTEM_INERTIA (0.1129943132)
//#define USER_SYSTEM_FRICTION (0.4687358737)
//as defined with Quadrature encoder in Lab 12a
#define USER_SYSTEM_INERTIA (0.09917843342)
#define USER_SYSTEM_FRICTION (0.3583653569)
#define USER_SYSTEM_BANDWIDTH_SCALE (1.0)
Where I've manually set the USER_SYSTEM_BANDWIDTH rather than using the USER_SYSTEM_BANDWIDTH_SCALE definition (it didn't seem to update anything when changed).
#define USER_SYSTEM_BANDWIDTH (140.0)
I'm using the TMS320f28069M Launchpad XL, as well as the BOOSTXL-DRV8301 REV B add-on card. The Motor is rated for 3000RPM, at 200V, with a maximum continuous current of 5.3A. I'm limited to a 30Vdc/3A bench supply for this evaluation. The servo itself is a 3-phase, permanent magnet AC Servo Motor, not a true PMSM.
As well, I've read through this forum and attempted many of the suggested fixes for this issue; including:
Increasing the value of USER_MOTOR_RES_EST_CURRENT up to 3A in 0.5A increments
Varying the USER_SYSTEM_BANDWIDTH value between 20 and 160 by increments of 10
Adjusted the value for gMotorVars.Kp_Idq from 10.61325073 (default) +/- 50% in 10% increments
The incremental encoder is an aftermarket CUI AMT113S-V programmed for 4096 counts per rotation. Care has been taken to minimize encoder noise (shielded cables, as well as proper system grounding have all helped). I've verified that both the encoder and the electric angle of the motor are working in concert in Lab 12a, by watching both the st_obj.vel.conv.Pos_erev and st_obj.vel.conv.Pos_mrev, observing 3 pole pairs in Pos_erev and a real-world mechanical rotation equate to 1 in Pos_mrev. The direction of the manual rotation was counter-clockwise (facing the motor), which is consistent with the rotation of the labs prior to this.
datasheet for the encoder: www.cui.com/.../amt11.pdf
In lab 5d, the tuned system was able to rotate the motor at speeds as low as 2 RPM with minimal cogging.
The goal for this project is a speed-controlled servo drive, where the system's higher level instructions are decoded on a separate MCU in order to leverage our company's existing IP.
Given all of these things, is it common for the motor to vibrate while conducting the electric field to encoder alignment? This doesn't seem to make sense to me. Is the disturbance rejection under-damped? Is the motor over-spec'd for the bench supply? Could there be an irregularity accross one a single phase's impedance?
What am I missing?
Jamie Mascola
I have tried changing the gMotorVars.SpeedRef_krpm value to different settings between 100 and 300 RPM with no effect. There is no mechanical load on the motor during these tests.
Torque and disturbance rejection are pretty solid during the tests at low speed, but I doubt they're anywhere near the potential for the motor at higher RPM.
How does one create an offset for the difference between the mechanical and electrical angles of the motor? Is this to be defined in the user.h file? Or is it automated by the lab code? I didn't see any mention of this step in the lab procedure manual for Instapin Motion and FOC.
A screenshot of the watch window is shown below. Here one can see the state where the process is stuck at. Measurements at the power supply are 24V and 2.16A. The Motor is locked in place and oscilating slightly.
I haven't made any changes to the source code for the lab.
JM
All done.
Yaskawa labels their phases as U, V, W.
I ran through
DRV_PHASE(MOTOR_PHASE)
A(U) B(V) C(W)
A(U) B(W) C(V)
A(V) B(U) C(W)
A(V) B(W) C(U)
A(W) B(U) C(V)
A(W) B(V) C(U)
No improvement. The relative angle where the motor would lock changed as the phases were swapped. As well, the direction of rotation changed for some of the pair swaps.
Of note: The electrical angle displayed by the st_obj.vel.conv.Pos_erev never changed from 0.3818125725 despite any of the phases being swapped. In fact, it never seems to update at all.
Hi Adam,
I was able to estimate the inertia in lab 12a. The results are shown in my first post within my motor parameters. I’ll paraphrase them below:
//as defined using SpinTAC in lab 5c
//#define USER_SYSTEM_INERTIA (0.1129943132)
//#define USER_SYSTEM_FRICTION (0.4687358737)
//as defined with Quadrature encoder in lab 12a
#define USER_SYSTEM_INERTIA (0.09917843342)
#define USER_SYSTEM_FRICTION (0.3583653569)
They not exactly the same, but they do sit within a comfortable tolerance margin with respect to those calculated in lab 5c.
I have the booster pack connected to J1 and QEPA. I’ve verified the quadrature decoder signals by watching the st_obj.vel.conv.Pos_mrev variable while manually turning the motor. Its direction of rotation and counts per revolution are consistent. As well, the general velocity given by gMotorVars.SpeedQEP_krpm seems to be correct (I can’t really tell, as my hands are less sensitive than an encoder).
Aside from putting my motor parameter definitions in user_j1.h, the only other modification that I’ve made were to the ADC offsets (as derived by lab 3b), as well as the USER_SYSTEM_BANDWIDTH (set for 140.0), since I didn’t see a change when I made changes to the USER_SYSTEM_BANDWIDTH_SCALE (set for 1.0) value in my motor definitions.
I mentioned earlier that the motor is a true AC servo, and not a PMSM. It is intended to run from a 3-phase invertor. Could this cause the vibration that I’m seeing while it attempts to align the electrical and encoder angles? Could I temporarily increase the PWM frequency to try and coax it into a fixed position?
JM
Jamie,
What is really interesting about the issue you are seeing is that lab 12a and lab 12b use the exact same encoder software. So it is strange that the system works in lab 12a but doesn't in lab 12b.
Jamie Mascola said:Does the armature need to be absolutely stationary in order to align the encoder with the electrical angle?
Ideally, if the rotor is still moving the software won't get a good fix on where the zero degree electrical angle is. So during the Rs Recalibration phase at startup, the motor should rotate to a fixed position and hold there for a second or so.
Jamie Mascola said:And how does this happen with an incremental encoder when the armature never passes through the physical location of the z pulse on the encoder?
The labs use a trick in order to quickly align to any encoder. By forcing the motor into a zero degree electrical angle (during the Rs Recalibration), the current encoder counts can be captured and established as the offset. The encoder module is setup to rollover when max count is reached instead of on an index or z-pulse. This ensures that once the encoder is aligned to the zero degree position, until power is removed it will remain aligned.
When you tried swapping phases, did you restart the lab each time and go back through the rs recalibration?
In MotorWare 14 we added input qualification, which will filter the encoder input lines. With your very high number of counts this could be causing an issue. This is setup in the HAL_setupGpios function in hal.c
// EQEP1A GPIO_setMode(obj->gpioHandle,GPIO_Number_20,GPIO_20_Mode_EQEP1A); GPIO_setQualification(obj->gpioHandle,GPIO_Number_20,GPIO_Qual_Sample_3); // EQEP1B GPIO_setMode(obj->gpioHandle,GPIO_Number_21,GPIO_21_Mode_EQEP1B); GPIO_setQualification(obj->gpioHandle,GPIO_Number_21,GPIO_Qual_Sample_3); // GPIO GPIO_setMode(obj->gpioHandle,GPIO_Number_22,GPIO_22_Mode_GeneralPurpose); // EQEP1I GPIO_setMode(obj->gpioHandle,GPIO_Number_23,GPIO_23_Mode_EQEP1I); GPIO_setQualification(obj->gpioHandle,GPIO_Number_23,GPIO_Qual_Sample_3);
Another thing to try is to watch the encoder signals when the PWMs are driving. I've seen cases where everything is fine and perfect when the PWMs are not firing, but as soon as they start switching, the encoder signal is useless. You should be able to check this in lab 12a by turning gMotorVars.Flag_enableSys and gMotorVars.Flag_Run_Identify to true, then manually rotating the motor to check the mechanical angle feedback.
When you ran lab 12a did you try running multiple inertia identifications in a row?
When running lab 12b and the motor moves to one of three locations and stops moving, does this happen immediately, or does the motor spin for a little bit first? This seems to indicate that maybe the number of encoder counts is not 100% correct. If it is close enough it will work for a time, but eventually the calibration will drift and the motor will stop working.
Hi Adam
The motor does rotate to a fixed position, but it also holds there indefinitely. To be on the safe side, I double checked the DC resistance across the pairs of phases, and everything measures out. I always leave rs_recalibration in, unless directed to do otherwise by the lab manual. I understand that it helps to account for variation in the stator coil resistance due to temperature variation.
If the calibration uses the starting point to determine the offset to electric 0, does this mean that the encoder start position is assumed to be the encoder zero position? Because this is likely not the case. The encoder was aligned by connecting the U and V phases to DC power and ground, and passing enough current through them to firmly lock the armature in place. The encoder was then zeroed over USB using CUI’s PC/GUI tool.
I restarted the lab with a hard stop on the debugger between phase-pair tests. The rs_recalibration runs by default for Lab 12b. I let it do just that.
I am using the x.14 version of Motorware. I’ll look for a shorter debouncing time constant. I imagine that it is set by the “GPIO_Qual_Sample_n” parameter.
I put the encoder to the test in Lab12a and watched the …mrev and …erev symbols in the watch window with the coils energized. Induced noise on the encoder lines has been addressed by using shielded cabling and grounding the encoder chassis, as well as the motor chassis, to a common ground point with the control circuit. There is still some slight noise on the encoder lines, it is slightly less than 100mV peak. I also watched the change in the ..erev to verify that the stator did indeed have 3 pairs of poles, and that the electric angle was in changing in agreement with the mechanical rotation (aside from the 3 0 to 1 transitions for the electric angle, which is to be expected). It confirmed what the current-limited energized U(Vdc) -> V(GND) phase test showed. There are 3 pole pairs in the armature.
There was often variation when running lab 12a repeatedly. Some results were orders of magnitude off from the results used in my parameter definitions. Others were more orthodox.
When running lab 12b, the motor does not appear to move to any other location but to the location that it locks at. Which is between any two of the points that I marked off when locking the stator with a low-current (40 mA) DC supply, running the U-phase to Vdc, and the V-phase to ground, and manually rotating the motor to count the pole pairs.
JM
Jamie,
Jamie Mascola said:If the calibration uses the starting point to determine the offset to electric 0, does this mean that the encoder start position is assumed to be the encoder zero position? Because this is likely not the case. The encoder was aligned by connecting the U and V phases to DC power and ground, and passing enough current through them to firmly lock the armature in place. The encoder was then zeroed over USB using CUI’s PC/GUI tool.
Can you describe how, from the microcontroller's perspective, your encoder is different than a traditional quadrature encoder? The software makes no assumptions about the encoder until it is recalibrating the resistance. When it is recalibrating the resistance, the microcontroller assumes that the motor is physically aligned to an electrical angle of zero. At this point, the current reading of the encoder is stored as the offset. The QEP hardware is setup to reset its counter once the maximum count has been reached, this way there is no reliance on the encoder index mark and the only dependency in the system is that the maximum count from the encoder is correct.
You can think of it as two layers, the QEP hardware layer will count until it has seen one complete rotation (via the maximum count mechanism, and the ENC software layer uses an offset to translate that QEP hardware count into a properly aligned electrical angle.
When lab 12a produces results that vary by that much, it leads me to believe that there is an issue in either the software or hardware setup of the encoder. Since it partially works, I think your encoder configuration is close, but is not 100% correct. Beyond the encoder, is it possible that the pole pairs is incorrect? This will have a major impact on sensored control and will only impact sensorless control in that the speed will be incorrect.
Hi Adam,
Aside from a relatively high position count, there' not mcuh different about the encoders that we're using than a standard optical encoder. They use a capacitive scheme, of which I'm not entirely familiar with. I added another round of noise reduction and shielded the motor wires, which were giving off a fair bit of EMI in 90kHz periodic pulses. This brought the noise level down even further on the encoder, and by having changed the value for the encoder sampling freuency
eg
// EQEP1A
GPIO_setMode(obj->gpioHandle,GPIO_Number_20,GPIO_20_Mode_EQEP1A);
GPIO_setQualification(obj->gpioHandle,GPIO_Number_20,GPIO_Qual_Sync/*GPIO_Qual_Sample_3*/);
I can now run lab 12a and get consistent results. I've logged the test results for friction and inertia from 10 consecutive tests. Half were conducted consecutively without resetting the debugger. The other half were recorded after resting the debugger between iterations.
gMotorVars.SpinTAC.InertiaEstimate_Aperkrpm gMotorVars.SpinTAC.FrictionEstimate_Aperkrpm
0.1013868451 0.5529382825
0.09907770157 0.5976477861
0.09727728367 0.5458298922
0.09592324495 0.5917863846
0.0971660614 0.5784171224
0.09847939014 0.5155105591
0.09884005785 0.5743053555
0.09735453129 0.5475302935
0.09912538528 0.5469039083
0.09912538528 0.5666786432
The issues with lab 12b have not changed. It runs through the RS recal, and then moves counter-clockwise to a fixed location and locks.
Aside from the current limited, dc coupled 2-phase test for the number of pole pairs that I performed earlier, is there another method to determine the number of pole pairs?
JM
Jamie,
I'm glad you were able to get more consistent results in lab 12a.
What speed are you trying to achieve in lab 12b?
Also what is the maximum speed you were able to achieve in any of the sensorless labs?
Jamie Mascola said:Aside from the current limited, dc coupled 2-phase test for the number of pole pairs that I performed earlier, is there another method to determine the number of pole pairs?
The other way I've used to detect the number of poles is to spin at a fixed speed in a sensorless lab, then use a tachometer to check the actual speed of the motor. If there is any misalignment (aside from a small offset) it will indicate that the number of poles is incorrect. If the true speed is greater than the setting it means the motor has less poles and if the true speed is smaller, than the motor has more poles.
Hi Adam,
I was aiming for a speed of 300 RPM in lab 12b. This is the maximum speed for our application. Typically, we'll be working at speeds below 100 RPM. I created a tachometer using a third party dev board, and it agrees with the reference speeds set in the watch window in lab 5e. I've used the same board to determine the encoder counts per revolution and confirm that we're seeing 4096 counts per z-pulse. This was something that I whipped together to help debug and eliminate the previous encoder noise issues.
I tested this with speeds ranging between 5 RPM and 446 RPM. This is the top speed we can achieve for this motor, as it is rated for 3000 RPM continuous (4k max), when fed with a 200V input voltage. I'm testing at 24 volts, which is the maximum rated voltage for this dev kit, and closer to our target application supply voltage.
The margin of error that I'm seeing from the RPM counter is +/- 1 RPM from the user-definable gMotorVars.SpeedRef_krpm value. There's some fluctuation at lower speeds, but we're within the heart of the range of values displayed by gMotorVars.Speed_krpm as well. I think that both tests agree that we have a 3 pole pair motor.
Any other ideas?
Jamie