omar Inserito: 6 novembre 2002 Segnala Inserito: 6 novembre 2002 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 0extern BYTE ucMemOut1; // Memoria immagine uscita 1extern BYTE ucMemOut2; // Memoria immagine uscita 2extern BYTE ucMemOut3; // Memoria immagine uscita 3extern BYTE ucMemOut4; // Memoria immagine uscita 4extern BYTE ucMemOut5; // Memoria immagine uscita 5extern BYTE ucMemOut6; // Memoria immagine uscita 6extern BYTE ucMemOut7; // Memoria immagine uscita 7extern WORD uiEnbValve; // Enable gestione valvola modulanteextern WORD uiValveTime; // Tempo massimo corsa valvola modulanteextern WORD uiValveMinOn; // Tempo minimo on per comando valvola modulanteextern WORD uiKp; // K proporzionale per controllo PIDextern WORD uiKd; // K derivativo per controllo PIDextern 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 1WORD uiSetpointTemp; // Setpoint TemperaturaWORD uiBufValTemp1; // Buffer V.M.lettura Ingresso Analogico 0 Termocoppia 1WORD uiTimeOnValve; // Durata comando valvola modulanteWORD uiCntPID; // Tempo di campionamento controllo PIDint iSumError; // Sommatoria errore per controllo PIDint iLastError; // Errore old per controllo PIDint iCommandTime; // Comando valvola modulanteint iCommandTimeOld; // Comando valvola modulante oldBYTE 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; }}
Livio Orsini Inserita: 6 novembre 2002 Segnala Inserita: 6 novembre 2002 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.
omar Inserita: 7 novembre 2002 Autore Segnala Inserita: 7 novembre 2002 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 motorizzata2)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
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora