Vai al contenuto
PLC Forum


Implementazione controllo PID per valvola modulant


omar

Messaggi consigliati

Ho implementato il controllo di una valvola modulante tramite PID, qui di seguito ho inserito il codice. Sono graditi commenti.

Saluti

//--------------------------------------------------------------------------

//

// Author: Bedini A.

//

//--------------------------------------------------------------------------

//--------------------------------------------------------------------------

// I N C L U D E

//--------------------------------------------------------------------------

#include

#include "compiler.h"

//--------------------------------------------------------------------------

// E X T E R N A L V A R I A B L E S

//--------------------------------------------------------------------------

extern BYTE ucMemOut0; // Memoria immagine uscita 0

extern BYTE ucMemOut1; // Memoria immagine uscita 1

extern BYTE ucMemOut2; // Memoria immagine uscita 2

extern BYTE ucMemOut3; // Memoria immagine uscita 3

extern BYTE ucMemOut4; // Memoria immagine uscita 4

extern BYTE ucMemOut5; // Memoria immagine uscita 5

extern BYTE ucMemOut6; // Memoria immagine uscita 6

extern BYTE ucMemOut7; // Memoria immagine uscita 7

extern WORD uiEnbValve; // Enable gestione valvola modulante

extern WORD uiValveTime; // Tempo massimo corsa valvola modulante

extern WORD uiValveMinOn; // Tempo minimo on per comando valvola modulante

extern WORD uiKp; // K proporzionale per controllo PID

extern WORD uiKd; // K derivativo per controllo PID

extern WORD uiKi; // K integrale per controllo PID

//--------------------------------------------------------------------------

// G L O B A L V A R I A B L E S

//--------------------------------------------------------------------------

WORD uiValTemp1; // Lettura Ingresso Analogico 0 Termocoppia 1

WORD uiSetpointTemp; // Setpoint Temperatura

WORD uiBufValTemp1; // Buffer V.M.lettura Ingresso Analogico 0 Termocoppia 1

WORD uiTimeOnValve; // Durata comando valvola modulante

WORD uiCntPID; // Tempo di campionamento controllo PID

int iSumError; // Sommatoria errore per controllo PID

int iLastError; // Errore old per controllo PID

int iCommandTime; // Comando valvola modulante

int iCommandTimeOld; // Comando valvola modulante old

BYTE ucCntRead, ucCnt05s;

BOOL bOnScan, bTick01s, bClk05s, bRestartPID, bOpenValve, bCloseValve;

//--------------------------------------------------------------------------

// M A I N

//--------------------------------------------------------------------------

void main(void)

{

do {

SystemControl(); // Ciclo Macchina

WriteOutput(); // Scrittura stato uscite

bOnScan = FALSE; // Flag ON 1^scan di programma

bTick01s = FALSE; // Tick 0,1 sec

} while(TRUE);

}

/////////////////////////////////////////////////////////////////////////////

// FUNCTION: SystemControl

// Ciclo Macchina

/////////////////////////////////////////////////////////////////////////////

void SystemControl(void)

{

//-----------------------------------------------------------------------

// G E S T I O N E I N G R E S S I A N A L O G I C I

//-----------------------------------------------------------------------

// Init tempo di campionamento controllo PID

if (bOnScan) {

uiCntPID = uiValveTime;

}

// Tick di sistema da 0,1sec

if (bTick01s) {

// Cnt 0,5sec

ucCnt05s++;

if (ucCnt05s >= 5) {

ucCnt05s = 0;

// Lettura Ingresso Analogico 0 Termocoppia 1

uiBufValTemp1 += ReadTemp(0, 500);

// Contatore letture eseguite

ucCntRead++;

// Calcolo valor medio letture eseguite

if (ucCntRead >= 4) {

ucCntRead = 0;

uiValTemp1 = (uiBufValTemp1 >> 2);

uiBufValTemp1 = 0;

}

if (uiEnbValve) {

// Decremento tempo di comando valvola modulante

if (uiTimeOnValve) {

uiTimeOnValve--;

}

// Tempo di campionamento controllo PID

if (uiCntPID) {

uiCntPID--;

}

if (!uiCntPID) {

// iCommandTime compreso tra -uiValveTime e +uiValveTime (tempo corsa max della valvola)

iCommandTime = (WORD)PidControl(uiSetpointTemp, uiValTemp1, uiKp, uiKd, uiKi, uiDeadBand,uiValveTime, &iLastError, &iSumError);

// Check se il processo Š in stallo, (get a kick!)

if ((iCommandTime == iCommandTimeOld) && (uiValPrx != uiTHRegTemp)) {

iCommandTimeOld = 0;

}

if (iCommandTime >= iCommandTimeOld) {

// Calcolo tempo di comando valvola

uiTimeOnValve = abs(iCommandTime - iCommandTimeOld);

bOpenValve = TRUE;

bCloseValve = FALSE;

}

else {

// Calcolo tempo di comando valvola

uiTimeOnValve= abs(iCommandTimeOld - iCommandTime);

bOpenValve = FALSE;

bCloseValve = TRUE;

}

// Check valore tempo di comando calcolato

if (uiTimeOnValve < uiValveMinOn) {

uiTimeOnValve = 0;

}

iCommandTimeOld = iCommandTime;

bRestartPID = FALSE; // Flag restart algoritmo PID (per bumpless etc.)

uiCntPID = uiValveTime;

}

}

else {

uiCntPID = uiValveTime;

iCommandTimeOld = 0;

bOpenValve = FALSE;

bCloseValve = FALSE;

bRestartPID = FALSE; // Flag restart algoritmo PID

}

}

//-----------------------------------------------------------------------

// G E S T I O N E C O M A N D O V A L V O L A M O D U L A N T E

//-----------------------------------------------------------------------

// Comando apertura valvola

if(uiTimeOnValve && bOpenValve) {

ucMemOut4 = TRUE;

}

else {

ucMemOut4 = FALSE;

}

// Comando chiusura valvola

if(uiTimeOnValve && bCloseValve) {

ucMemOut5 = TRUE;

}

else {

ucMemOut5 = FALSE;

}

}

Link al commento
Condividi su altri siti


Prima di fare commenti bisognerebbe conoscere meglio il problema.

Una funzione PID è di per se semplice, è sufficiente che le istruzione implementate eseguano l'algoritmo previsto. I problemi semmai nascono dalle condizioni al contorno. Per esempio, io da una rapida occhiata ho notato un tic di sistema di 0.1". Questo tempo può essere valido o meno, dipende dal sistema. Poi, sempre elecando a ruota libera, come attivi la tua funzione di regoalzione? mi pare di capire che (correggimi se ho capito male, ho solo dato una rapida occhiata) la funzione viene chaimata ed esegue o meno certe funzioni se è scaduto il tempo; in questo modo è facile avere jitter, cosa che non fa mai bene.

Se vuoi dei commenti costruttivi più che un codice dovresti fornire dattagli sul sitema e sulla strategia di controllo che hai usato.

Link al commento
Condividi su altri siti

Livio Orsini+Nov 6 2002, 05:41 PM-->
CITAZIONE(Livio Orsini @ Nov 6 2002, 05:41 PM)

1) Problema:

Controllo temperatura di un liquido scaldato tramite un bruciatore, l'alimentazione al bruciatore deve essere controllata operando su una valvola motorizzata

2)E'appunto un tick di sistema e serve per gestire temporizzazioni varie.

3)La funzione viene invocata allo scadere del tempo di campionamento (CntPid con risoluzione bTick01sec)

4)Sono graditi i commenti di tutti coloro che hanno già affrontato questo tipo di problema, visto che l'implementazione da me proposta è solo una delle possibili (ne ho provate piu di un paio) per risolvere il problema descritto.

Saluti

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...