PID pro mcu v C
Aleš Novák
ales.novak@t-email.cz
Úterý Srpen 7 00:41:23 CEST 2007
Kdysi jsem delal regulaci teploty v terariu. Teplota se reguluje PI
regulatorem, ktere ma cidlo v prostoru teraria a vystup tohoto PI
regulatoru se zavadi jako setpoint druheho regulatoru (ON-OFF), ktery
reguluje teplotu topneho kamene (uvnitr kamene je dalsi cidlo).
Fragmenty kodu vypadaji takhle:
Neni to sice uplne ciste, ale jakmile to zacalo fungovat, uz jsem do
toho nevrtal. Pro spravnou funkci integracni casti je nutne volat
funkci PIRegProcess() jednou za sekundu.
#define ITIME 600 //integrační čas v sekundách
#define PGAIN 10 //zesílení (PGAIN=10 je zesílení 1.0) rozsah 0..100
#define OPMIN 150 //minimální výstup v desetinách st. C
#define OPMAX 450 //maximální výstup v desetinách st. C
data int PIRegSP; //setpoint
data int PIRegOP; //výstup
/* provádí celočíselné dělení a kumuluje zbytky
v případě přetečení zbytku nad nebo pod Div
upraví výsledek i zbytek
Value - vstupní hodnota kterou chceme dělit
Div - čím chceme dělit
Rem - pointer na sumu zbytků
return - výsledek dělení s přihlédnutím na nastřádané zbytky z dřívějška */
int DivRemCumul(int Value, int Div, int data *Rem){
int vysl;
vysl=Value/Div; //výsledek dělení
*Rem+=Value%Div; //kumulace zbytků
if((*Rem)>=Div){
*Rem-=Div; //zbytek přetekl
vysl++;
}
if((*Rem)<=(-Div)){
*Rem+=Div; //zbytek podtekl
vysl--;
}
return vysl;
}
/* volat jednou za sekundu
PV - Process Value - skutečná hodnota
OP - Output - výstup
return - nová hodnota OP */
int PIRegProcess(int PV, int OP){
static bit Start=1;
static int OldDev=0; //minulá odchylka od SP
static int data MemoIRem=0; //paměť zbytků po dělení (I část)
static int data MemoPRem=0; //paměť zbytků po dělení (P část)
int Dev;
int DDev;
Dev=PV-PIRegSP; //aktuální odchylka
if (Start){
Start=0;
OldDev=Dev;
}
DDev=(Dev-OldDev)*PGAIN; //aktuální změna odchylky*zesílení (PGAIN=10 je zesílení 1)
OP-=DivRemCumul(DDev, 10, &MemoPRem); //proporcionální změna
OP-=DivRemCumul(Dev*PGAIN, ITIME*10, &MemoIRem); //integrační změna
if(OP>OPMAX)
OP=OPMAX;
if(OP<(PV-20)) //spodní doraz výstupu je 2°C pod skutečnou hodnotou
OP=PV-20;
OldDev=Dev;
return OP;
}
Novalex
MM> Zdravim Vas,
MM> vim, ze toto tema bylo jiz v konferenci probirano, nicmene, vysledek
MM> tehdy nepadl, proto je to tu zas :-) Chtel bych se zeptat, jestli nekde
MM> nekdo nema popis navrhu PID regulatoru pro mcu v C-ku (napr. pro Atmel),
MM> ktery funguje (tzn. probehla prakticka aplikace). Nekdy v 90. letech
MM> vyslo presne tohle v softwarovych novinach, ale Bohuzel nejsem vlastnik,
MM> takze jestli nekdo Vi, tak at prosim poradi... Preju pekny slunecny
MM> pondelek.
MM> Toz tak, Tyca.
Další informace o konferenci Hw-list