|
楼主 |
发表于 2011-5-18 06:35:08
|
显示全部楼层
here is an example of using the pid controller on two distinct processes:
=============main.c================
#include <avr/io.h>
#include "gpio.h"
#include "pid.h" //we use pid control (multi-controller version)
//hardware configuration
#define OUT_PORT PORTD
#define OUT_DDR DDRD
#define OUTs 0xff
#define OUT(val) OUT_PORT = (val)
#define OUT1_PORT PORTE
#define OUT1_DDR DDRE
#define OUT1s 0xff
#define OUT1(val) OUT1_PORT = (val)
//end hardware configuration
//simulate a heater / temperature relationship 0
float temp_read(float heater) {
unsigned int t_mass=200; //thermal mass
unsigned int t_decay=25; //thermal decay
//unsigned int t_energy=50; //energy input per sample period. it must be greater than t_decay
float temp=0; //current temperature
static float energy_sum=0; //cumulative energy input
//simulate a pot beign heated
temp = energy_sum / t_mass;
energy_sum += heater - temp * t_decay;
return temp;
}
//simulate a heater / temperature relationship 0
float temp_read1(float heater) {
unsigned int t_mass=20*5; //thermal mass
unsigned int t_decay=10; //thermal decay
//unsigned int t_energy=50; //energy input per sample period. it must be greater than t_decay
float temp=0; //current temperature
static float energy_sum=0; //cumulative energy input
//simulate a pot beign heated
temp = energy_sum / t_mass;
energy_sum += heater - temp * t_decay;
return temp;
}
void mcu_init(void) {
IO_CLR(OUT_PORT, OUTs); //outs cleared
IO_OUT(OUT_DDR, OUTs); //outs as output
IO_CLR(OUT1_PORT, OUT1s); //outs cleared
IO_OUT(OUT1_DDR, OUT1s); //outs as output
}
int main(void) {
//for heater 0
float temp=0;
float heater=100; //header opening
PID_T pid; //pid struct - you can use multiple pid controllers on the same routine
//for heater 1
float temp1=0;
float heater1=10; //header opening
PID_T pid1; //pid struct - you can use multiple pid controllers on the same routine
mcu_init(); //reset the chip
//set up pid
pid_set(&pid); //set up the pid controller - not used for multi-controller version
//pid_gain(&pid, 6, 10, 2.34); //initialize the pid
pid_tuning_zn(&pid, 10, 3.30/1000); //ziegler - nichols tuning: time constant = 10s, sloep = 3.3c per 1000s
pid_limits(&pid, 5000, 10); //set the limits
pid_target(&pid, 25); //set the target to 25c
//set up pid1
pid_set(&pid1); //set up the pid controller - not used for multi-controller version
//pid_gain(&pid, 6, 10, 2.34); //initialize the pid
pid_tuning_zn(&pid1, 10, 2.6/1000); //ziegler - nichols tuning: time constant = 10s, sloep = 2.6c per 1000s
pid_limits(&pid1, 500, 0); //set the limits
pid_target(&pid1, 25); //set the target to 25c
while (1) {
temp=temp_read(heater); //read the temperature for heater
heater = pid_output(&pid, temp); //calculate heater power levels
OUT(temp);
temp1=temp_read1(heater1); //read the temperature for heater
heater1 = pid_output(&pid1, temp1); //calculate heater power levels
OUT1(temp1);
}
return 0;
}
=================================
read_temp() and read_temp1() are two simulated heaters, each with its own thermal mass and decay parameters.
we are outputing the temperature of read_temp() on PORTD, and temperature of read_temp1() on PORTE. In both cases, the temperature targets are set to 25c so we expect an output of 0x19 on portd and porte. |
|