Vai al contenuto

Realizzare una temporizzazione in un blocco funzione

Home Forum Programmazione IEC 61131 (LogicLab) Realizzare una temporizzazione in un blocco funzione

Stai visualizzando 5 post - dal 1 a 5 (di 5 totali)
  • Autore
    Post
  • #35794
    Enzo
    Partecipante

    Stiamo provando a scrivere un paio di FB in ST che necessitano di un temporizzazione interna per ritardo di spegnimento e accensione. Provando ad utilizzare la variabile SysDateTime come riferimento, il compilatore torna l’errore di object not found.

    Provando a definire la variabile come VAR_EXTERNAL all’interno del codice, LogicLab ritorna errore di sintassi. Provando a definirla nella tab variabili locali del FB, LogicLab indica la variabile come già esistente. Quale è il corretto approccio in questi casi ?

    Comunque, come suggerito, preferiremmo mantenere il codice portabile e quindi non accedere a variabili globali. Cosa posso usare come riferimento per un timer interno ad un FB (senza istanziare altri FB) ?

    #38924
    Sergio Bertana
    Amministratore del forum

    Sicuramente per la portabilità del codice è preferibile non utilizzare riferimenti a variabili esterne all’interno di FB, ma se il FB si utilizza sempre su sistemi SlimLine in ambiente LogicLab è accettabile fare riferimenti a variabili esterne predefinite (Come SysDateTime), queste variabili sono definite nel target è sono sempre presenti.

    Diverso è il caso in cui ci si riferisca a variabile esterne definite nel programma, spostando il FB da un programma ad un altro se la variabile globale non è presente si ha un errore di compilazione. Comunque è possibile gestire temporizzazioni anche senza riferirsi a variabili esterne.

    Allego al topic un programma in cui ho realizzato un FB timer, esattamente come il FB eTON (Estratto manuale). Troverai il sorgente di un FB realizzato con una variabile esterna ed uno esattamente uguale utilizzando la funzione SysGetSysTime. Come si vede dalla stampa programma, la funzione SysGetSysTime ritorna il tempo in uS quindi per mantenere le definizioni in mS ho provveduto a dividere per 1000.

    Naturalmente essendo la variabile di appoggio riferimento tempo di tipo UDINT, utilizzando la variabile esterna che torna il tempo in mS si potranno gestire temporizzazioni massime fino a circa 1200 ore. Mentre utilizzando la funzione che torna il tempo in uS si potranno gestire temporizzazioni massime fino a circa 1.2 ore (Download programma).

    #58975
    Rubox
    Partecipante

    Parto dal fondo spiegando quello che vorrei ottenere.

    Il sistema che sto sviluppando mi manda una email se gli ingressi analogici che acquisisce vanno in Fault.
    Per non ricevere una email ad ogni ciclo di Back ho inserito un controllo su SysGetSysTime pari a 30 minuti.

    Però se per sfortuna la CPU ha appena ricominciato il conteggio del tempo da 0 e si accende il sistema, tale controllo sul valore di un timeRef non sarà veritiero fino a che il valore del tempo di sistema non raggiunge il valore di 30 minuti.

    Per ottenere una temporizzazione su tempi così lunghi è meglio usare un eTP, oppure anche SysGetSysTime c’è qualche trucco per utilizzarlo anche in questi casi?

    #58978
    Sergio Bertana
    Amministratore del forum

    Premesso che non ho ben capito cosa vuoi ottenere… ma se vuoi mandare una eMail quando gli ingressi analogici vanno in fault basterà inviarla sul fronte di attivazione errore di acquisizione così avrai una sola mail indipendentemente dal tempo in cui stà in errore.

    Per quanto riguarda le temporizzazioni io utilizzo sempre la funzione SysGetSysTime eseguendo il controllo su di un tempo di riferimento, e come detto prima la temporizzazione massima è di circa 70 minuti. Non capisco la tua perplessità sulla ripartenza del tempo, essendo un calcolo a riporto circolare funziona sempre correttamente. Certo l’unico controllo da fare è alla accensione dove dovrai memorizzare il tempo di riferimento. Il programma che ti posto sotto esegue l’inversione di BOut ogni 30 minuti.

    VAR
        TimeBf : UDINT; (* Time buffer (uS) *)
        BOut : BOOL; (* Blink output *)
    END_VAR
    
        IF (SysFirstLoop) THEN TimeBf:=SysGetSysTime(TRUE); END_IF;
        IF ((SysGetSysTime(TRUE)-TimeBf) >= 1800000000) THEN TimeBf:=SysGetSysTime(TRUE); BOut:=NOT(BOut); END_IF;
    #58987
    Rubox
    Partecipante

    Mi son spiegato male io.
    Per gli ingressi in errore ho impostato il programma in modo tale che se un ingresso va in errore, torna a funzionare, va nuovamente in errore e via così… il sistema mi manda solo una e-mail in un arco di tempo che decido io, altrimenti mi spedirebbe una email ogni volta.

    Per l’uso di SysGetSysTime ho riscontrato alcune anomalie (per mia incapacità nella programmazione). Ho sostituito SysGetSysTime con SysDateTime e con la “logica” che ho impostato adesso funziona come mi aspetto.

Stai visualizzando 5 post - dal 1 a 5 (di 5 totali)
  • Devi essere connesso per rispondere a questo topic.