Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Tunning PID using fuzzy controller

Status
Not open for further replies.

mohamed.elsabagh

Full Member level 2
Joined
Oct 27, 2010
Messages
145
Helped
7
Reputation
14
Reaction score
7
Trophy points
1,298
Activity points
2,320
I would like to design a fuzzy controller which supervises a PID controller by tuning it's parameters (P-I-D) any help please???

Any ideas about using a control algorithm which implements both fuzzy and PID to get the best results??
 

hi
i think this coad help you to implement the PID.


//this code initializes a 16 bit timer for use as a pwm and implements a pid controller
//I use this code for temperature correction, with the plant value being an adc thermistor reading,
//and the pwm hooked up to a heater (through a mosfet switch)

//this code is good for small plant values within a signed 16 bit range that require a direct pwm output

#ifndef __pid_h__
#define __pid_h__

#include <avr/io.h>
#include <inttypes.h>

//the desired plant value
const uint16_t SET_POINT = 512;

//stores the integral sum
int32_t integral;
//the previous error
int16_t prev_error;

void pid_setup(void) {
//pwm data direction
DDRB |= _BV(PB1);

//set the prescaler and wgm modes for ICR1 top fast pwm with no prescaling
TCCR1A |= _BV(COM1A1) | _BV(WGM11);
TCCR1B |= _BV(WGM13) | _BV(WGM12) | _BV(CS10);

//the higher the compare value, the longer the pulse stays high
//0 is completely off, 0xFFFF is completely on
OCR1A = 0;
ICR1 = 0xFFFF;
}

//apply a pid correction
//input the current plant value
//the gains are implemented as constants, but could easily be made global variables
void pid_correct(int16_t plant_value) {

//the plant error
//make sure error is positive when you need to apply a larger pwm value (wider positive width)
int16_t error = plant_value - SET_POINT;
//int16_t error = ((int16_t) SET_POINT) - plant_value;

//proportional * pGain
int32_t proportional = error * 200;

//integral * iGain
int32_t temp_sum = integral + ( error * 10 );
//check that the integral doesn't get out of the desired range
if ( temp_sum > 0xFFFF ) integral = 0xFFFF;
else
if (temp_sum < (-0xFFFF) ) integral = -0xFFFF;
else
integral = temp_sum;

//differential * dGain
//if you used the other error calculation, use the other differential as well
int32_t differential = ( (error - prev_error) * 20 );
//int32_t differential = ( (prev_error - error) * 20 );

//the final sum, with an overflow check
int32_t temp_pid_sum = proportional + integral + differential;
uint16_t pid_total;
//set max pwm value at ~95% of 2^16 (change this to whatever you like)
if ( temp_pid_sum > 62258 ) pid_total = 62258;
else
if ( temp_pid_sum < 0 ) pid_total = 0;
else
pid_total = (uint16_t) temp_pid_sum;

//set pwm compare value to change the duty cycle
OCR1A = pid_total;

//store the previous error
prev_error = error;
}

#endif
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top