cancel
Showing results for 
Search instead for 
Did you mean: 

ADC conversion mixing channels values

GVassis1999
Associate

I'm working on a project in speed control of a pmsm and i am using ADC1 and 7 channels of the ADC to sample 7 different inputs. The ADC gets triggered from TIM2 and i'm doing the conversions every time i get a callback. At first the adc works fine with the V/F control scheme, but when i switch to the closed loop control adc starts mixing up the sampled values though the sevens channels. 

The callback code is the following: 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
 
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adc_value,7);
 
    Ia= I_coef*adc_value[1]-  I_const; 
Ib = I_coef*adc_value[0]-  I_const; 
            Ic= I_coef*adc_value[2]-  I_const; 
 
ha= Hall_Binary_Conversion(adc_value[3]); 
hb= Hall_Binary_Conversion(adc_value[4]); 
hc= Hall_Binary_Conversion(adc_value[5]); 
 
Vdc = 5.5*V_coef*adc_value[6]; 
 
wmeas =Speed_calculation(ha, hb, hc, Ts);
th = Angle_calculation(ha, hb, hc,wmeas,Ts);
 
if (Ia > 5 ||Ia < -5 ||
Ib > 5 ||Ib < -5 ||
Ic > 5 ||Ic < -5){
svm_sectors(0,0);
svm_swinst_calc(Vdc);
}
else{
 
// V/f code----------------------------------------------------------------------
if(f<15){ 
f= 0.7957* wref;
Vrms = 0.24*f ;
Va_vf = 1.4142*Vrms*cos(2*3.14159265358979*f*(cnt_i*Ts));
Vb_vf = 1.4142*Vrms*sin(2*3.14159265358979*f*(cnt_i*Ts));
svm_sectors(Va_vf,Vb_vf);
svm_swinst_calc(Vdc);
}
//--------------------------------------------------------------------------------
 
else{
 
 
Park_components_calculation(Ia,Ib,Ic,th);
PIController_Update(&p1,wref,wmeas);
Iqref_calculation(&p1);
 
PIController_Update(&p2,Iqref,Iq);
 
PIController_Update(&p3,0,Id);
 
Va_Vb_calculation(&p2, &p3,th, wmeas);
svm_sectors(Va,Vb);
svm_swinst_calc(Vdc);
 
}
}
}
2 REPLIES 2
TDK
Guru

What leads you to believe they're being mixed up? What are the values normally and what are they when they are "mixed up"?

What is your sample rate?

If you feel a post has answered your question, please click "Accept as Solution".

CubeIDE has a bunch of good examples. I've settled on a conglomeration of a couple of examples like ADC_TripleModeInterleaved and ADC_TriggerMode to come up with a chunk of code that uses a timer to trigger a bunch of ADC conversions from 1 - 3 ADCs simultaneously (depending on which processor I'm currently using). When a bunch of results are ready, I get an interrupt from the DMA system, then I can pull the data out of the ping-pong buffers, convert them to engineering units with the latest value of Vref, average and post them for consumption.

I only run my ADCs at 200Hz, but that's what I need.

The examples show how to un-"mix-up" the results. Remember, if you're using DMA without ping-pong (circular) buffers, the buffers will be updated as you are using them, that would give weird results.