Hello,
I am seeing something odd on my system. When running my system at 50Nm. I am seeing my RMS Phase current for A, B and C each around 4 amps apart from each other.
Phase A = 49
Phase B = 45
Phase C = 53
When I measure with a meter, this is not the case. The phases are pretty balanced. The duty cycles output by the SVPWM are also all pretty much identical.
With the meter:
Phase A = 51
Phase B = 48
Phase C = 48
Do you have a possible explanation on why my ADC readings would be unbalanced, when the current is actually not unbalanced? Where should I begin to look to debug this issue?
As I understand the ADC conversion, it is set up to take the average of 32 samples. My fast thread runs at 4kHz. Is it possible that I am maybe taking different sections of the AC wave for each A, B and C that could cause the 3 amp spread between each? Phase C = peak of AC wave, Phase A = a little lower on AC wave, Phase B = a little lower on AC wave? It looks like ADC0 is sampled before ADC1, and then is channel 0 sampled before channel 1 on each ADC?
I have the ADC set up to sample DC Bus on ADC0 channel 0, Phase C on ADC0 channel 1, Phase A on ADC channel 0, and Phase B on ADC1 channel 1.
I calculated the conversion time using the datasheet and it looks to be 21.7us. It looks like the code blocks in the fast thread to get the user samples, but does not block to get the phase currents and DC bus. Is the phase current and DC bus conversion happening while other threads are running - it does not look to happen in the fast thread?
This is how I calculated conversion time is this correct?
SFCAdder = 5+5
Average Num = 32
BCT = 20
HSCAdder = 2
10+32*(20+0+2) = 652 clock cycles
The bus clock for the ADC looks to be set to 30MHz, so this means the total ADC conversion takes 21.7us.
If this does not happen in the fast thread, could I slow the bus clock down for the ADC Phase current measurements, and then speed it back up for the muxed values that we block for in the fast thread? This way I am sampling a larger section of the waveform.
Derek,
The ADC only uses the 32 sample averaging in order to setup the calibration. That feature is turned off for normal operation. Else, I think your calculation is correct.
A slight imbalance is caused by the fact that one of the currents is not sampled at the exact same instant as the other two. I have ran experiments comparing the captured result to a calculated result and found no appreciable difference in the phase current values. So the timing of the samples won't have any impact on this.
The Phase Current and DC Bus sample is triggered when the PWM counter elapses. Once the ADC samples are complete, the Fast ISR is triggered. This ensures that the Fast ISR only runs after having collected updated feedback data.
You could be running into an small number problem with the RMS calculation. Since your current is only 0.12 (normalized) this is 1966 in SQ14. This squared is 235 (normalized) in SQ14. When that is combined with the low pass filter (also calculated in SQ14) I bet the calculation is coming out to be very small which is introducing errors into the RMS values you are getting. The way to look at this would be to get the value for feedback.internal.rmsIsa_halfPWM.coeff and manually run the calculation with the phase current signals to see if you are underflowing due to using an SQ14 for the calculations.
If these RMS values are important to you and your application, you could change the filters to be LQ24 and this would resolve the possible underflow issue.
Hey Adam,
In the code it looked like the Isa, Isb, and Isc currents were just in _sq. Therefore, I was converting them back to float by dividing by 16384. Is SQ14 different? I do not see sq14 in the qmath file - just sq15, sq13, and sq8.
Just want to be sure I am scaling the numbers properly. I am actually calculating my own RMS instead of using the KMS RMS (Although the KMS RMS is also unbalanced - KMS RMS actually matches my RMS - so the problem looks to be in the Isa, Isb and Isc). Therefore, I am not taking the squareroot in SQ14. I am just taking the Isa, Isb, Isc currents, converting them to float, and then taking the RMS.
_sq and SQ14 are the same. 14 bits are allocated for the decimal. So dividing by 16384 would convert to float.
How fast are you sampling the Isa, Isb, and Isc as part of your calculations? Also how long are you sampling for? My concern is that you could be getting an imbalance due to aliasing with the sampling or due to not enough data. Also how are you calculating the RMS?
I am sampling the Isa, Isb and Isc every fast tick. Then averaging the 4 values every slow tick and calculating the RMS. You can see what I am doing here - I'll share for phase A:
void PriConvManager_UpdateMotorData_FastTick()
{
motorCurrentPhaseA_Array[rms_sample_num] = inputs->feedbackOutput->Isa;
rms_sample_num++;
if(rms_sample_num >= FAST_TICK_TO_SLOW_TICK) // 4 - 4kHz fast thread
{
rms_sample_num = 0;
}
}
void PriConvManager_UpdateMotorData_SlowTick()
{
rms_sample_num = 0; // Reset RMS Sample Number
// Average Motor Currents for Past 4 250us samples
for (int i = 0; i < FAST_TICK_TO_SLOW_TICK; i++)
{
// Divides by 16384 and multiplies by the Full scale of 400A
motorCurrentPhaseA += Util_SQPerUnitToFloat(motorCurrentPhaseA_Array[i], FULL_SCALE_CURRENT);
}
motorCurrentPhaseA /= FAST_TICK_TO_SLOW_TICK;
// How I take the RMS - it is a continuous RMS - not over a specific time period - Tc (time constant) = 1
squareMotorCurrentPhaseA = ((motorCurrentPhaseA*motorCurrentPhaseA - squareMotorCurrentPhaseA)*0.001/motorCurrentTc + squareMotorCurrentPhaseA);
rmsMotorCurrentPhaseA = sqrt(fabs(squareMotorCurrentPhaseA));
}
I take the RMS this way so that I can also filter the currents.
I thought at first I had a problem with the way I was calculating the RMS so I compared it to the KMS RMS. I have compared my RMS to KMS RMS - both line up with each other (except mine is filtered) and both are just as unbalanced. It does not look like it is this RMS function that is causing the imbalance since my RMS seems to match KMS RMS.
See below - My RMS compared to KMS RMS:
Green = KMS RMS Phase C - Cyan = My RMS Phase C (Draws a line through KMS RMS)
Navy = KMS RMS Phase A - Black = My RMS Phase A (Draws a line through KMS RMS)
Red = KMS RMS Phase B - Bright Blue = My RMS Phase B (Draws a line through KMS RMS)
Also Adam, I see that the PDB thread in which the currents are sampled is a lower priority (13) than the ADC thread (12). This seems wrong to me. Should this be flipped?
I'm not sure exactly what you mean. Are you referring to the priority of the interrupts? PDB0_IRQHandler is only used when the PDB0 goes into error. ADC1_IRQHandler fires when ADC1 completes the conversion.
The ADC1_IRQHandler is the important ISR since this is called when all of the ADC samples have been collected.
Also, it looks like the time between the SVPWM and the ADC sampling is tdeadtime/2. In my case this is 3us/2 = 1.5us. This is too short for my system. How do I change this time without changing the deadtime? What is this parameter?
The deadtime has nothing to do with the PDB delay. The ADC A samples are done when the FlexTimer counter resets and the ADC B samples are collected 2.7us later. This 2.7us was calculated based on the ADC conversion time.
Thanks Adam. This 45 that relates to 2.7us is this in clock cycles? That means the PDB clock would have a frequency of 16.67MHz?
The PDB clock is 30MHz. It uses the bus clock divided by 2. So 45 ticks at 30MHz is 1.5us. I believe the comment in the file is incorrect. The delay is set to be slightly longer than the conversion time. You should be able to calculate the conversion time using the ADC config and the datasheet.
Hey Adam,
The problem is also on the ADC input. After investigation it looks like we may have a layout issue. Thanks for the help, and I'll let you know if I have anything else!
What is the maximum value of the phase current sensors in your system? It could be a minimum resolution problem.
Hey Adam,
I don't believe it is a resolution problem. I have a Full Scale of 400. This would be 0.2A per Raw ADC Count.