Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Magnetic Levitation/Suspension. PID control Help.

Status
Not open for further replies.

PICMICRO

New Member
I am trying to make a magnetic Suspension Device, very similar looking to this. Image
The objects position is sensed via IR-diode and buffered before feeding to ADC.
The PWM is setup at around 4Khz.
I am using PIC16f877A and also using LCD to display various diagnostic datas if required.
This is my first PID project, so, I may be missing the very basics.
Please, Have a look at this code, and teach me something. :)
Feel free to ask anything.
Code:
void main()
{
        	setup_ad();
	init_LCD();
	init_PWM(); //intialize PWM
	set_duty(514U); // set PWM dutycyle = 514. ( 512 means 50%)
	init_Compare(); // Use CCP2 compare module to set CCP2IF flag at 256Hz rate
                                          // used to trigger PID loop

GIE = 0;
PEIE = 1;
TMR1IE=0;

unsigned int voltage = 0; // variable for the ADC value (gives the object position)
unsigned int ref = 512;  // refrence postion (middle)
unsigned int K = 2;       // some constant
signed int error = 0;   
signed int Iterm,Dterm,Pterm;
signed int net_error=0;
signed int old_error=0;
signed int correction;
signed int new_duty=0;

		while(1)
        {
			
			if(CCP2IF){  // wait for PID Sampling trigger(done at 256 Hz)			              
                         CCP2IF = 0;
			// GoDone set automatically
			while(GODONE);
			voltage = ADRESH*256+ADRESL; // Objects Position Value
			error = ref - voltage;
			net_error += error;
			if(net_error > 1023) net_error = 1023;
			if(net_error < -1023) net_error = -1023;
			Iterm = net_error/4;
			Dterm = (error-old_error)*4;
			Pterm = error/4;
			correction = K*(Pterm + Iterm + Dterm);
			new_duty = 512 - correction;
			if(new_duty>1023) new_duty = 1023;
			if(new_duty<0) new_duty = 0;
			set_duty(new_duty);
			LCD_Goto(2,9);
			LCD_Write_Num(new_duty);
			old_error = error;
			}
		}
}
 
Last edited:
Should I be clipping the net_error within +-1023 or should I allow it more room?
To tune the circuit, I am varying the constants, K, Kd, and Ki at powers of 2 (to make multiplication fast). Should I need more smooth control?
(the Ki and Kd are 4 in above code)
Also, how do I determine, what Sampling frequency I require?
Thanks.
 
have u read up any PID theory?

D is never a big factor, too much d makes it unstable.

A lot of control just needs PI tuned alone. D comes after PI is tuned.

A custom PID control means u experiment to determine the parameters. It has a lot do do with the speed of iteration based on the rate of I accumulation. A faster loop makes I accumulate faster. Therefore i suggest u standardise your loop speed with an interrupt and then tune with different values for P I.
 
i was given one of theese machines for christmas! its realy cool, when i get better at electronics i would like to have a go at building one. good luck for your project
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top