Part Number: MSP430G2553
Other Parts Discussed in Thread: LM331,
Hi! I'm trying to use a discrete PID with PWM for a BLDC motor, the way I obtain the speed of the motor is via an encoder that I built my self and the frequency that is generated by the optocoupler goes to an LM331(frecuency to voltage convert), and with that voltage generated I'm trying to obtain the speed of the motor through the ADC10, but the problem is that my PID does whatever it wants, even it ignores my Set Point. I checked up other existing codes (from other microcontrollers), and they seem to work well, I want to remark that the PID is already tuned up with Ziegler-Nichols Method.
#include "io430.h"
unsigned int adc,v,out;
float sp=380; //The equivalent voltage from "x" quantity of Hz or RPM
float ak=0,ak_1=0,ek=0,ek_1=0,ek_2=0,ki=0,kp=0,kd=0,q0=0,q1=0,q2=0,ti=0,td=0;
float u=0,u_1=0;
float T=0.0002;
float thao = 1.2,theta =.5,k=.958;
int main( void )
{
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;
WDTCTL = WDTPW + WDTHOLD;
__bis_SR_register(GIE);
/*P1SEL = 0X00;
P1DIR |= BIT0;*/
TACTL = TASSEL_2+MC_1+TAIE;
TACCR0 = 10666; //Sampling Frecuency 5 Khz
TA1CTL = TASSEL_1+MC_1;
TA1CCR0 =385; //85 Hz PWM
TA1CCTL1 = OUTMOD_7;
P2SEL |= BIT1;
P2DIR |= BIT1;
kp=(1.2*thao)/(k*theta);
ti=2*theta;
td=0.5*theta;
q0=kp*(1+T/(2*ti)+td/T);
q1=-kp*(1-T/(2*ti)+(2*td)/T);
q2=(kp*td)/T;
ADC10CTL0=SREF_0+ADC10SHT_3+ADC10IE+ADC10ON;
ADC10CTL1=INCH_0+CONSEQ0;
ADC10AE0 |=BIT0;
while(1)
{
ADC10CTL0 |= ENC+ADC10SC;
}
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer0(void){
switch( TAIV ){
case 2: break; // CCR1 not used
case 4: break; // CCR2 not used
case 10:
ek=sp-v;
u = u_1 + q0*ek + q1*ek_1 + q2*ek_2;
//if (u >= 3300)u=1500;
//if (u <= 0) u=0;
out = u*385/1500;
ek_2=ek_1;
ek_1=ek;
u_1=u;
TA1CCR1 = out;
break;
}
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10(void){
adc=ADC10MEM;
v=adc*3300/1024;
__delay_cycles(500);
}
