Vai al contenuto
PLC Forum


Tempo Pausa E Lavoro S7 300


Frank681

Messaggi consigliati

Salve

Avrei necessità di creare un FB , per pilotare una valvola di scarico condensa .

Il blocco dovrebbe avere un ingresso di abilitazione e due ingressi per settare i tempi di pausa e lavoro , ed un uscita per pilotare la valvola.

Sono riuscito a fare un blocco funzionante , il mio dubbio però e che ho inserito all'interno del blocco i timer da usare , nel mio caso T1 e T2 , esiste un modo per non dover dichiarare i Timer internamente ma fare si che trovi in automatico per ogni istanza del blocco un timer libero.

Cercando nel forum , in un esempio di Batta in AWL sui flip flop sembrerebbe esserci il modo ho provato ma non mi funziona, era bello perchè scrivendo povhe righe ero a posto , al fb è possibile passare che Tn usare ?

Grazie mille

Link al commento
Condividi su altri siti


Cercando nel forum , in un esempio di Batta in AWL sui flip flop sembrerebbe esserci il modo ho provato ma non mi funziona

Se metti il link all'esempio posso vedere di cosa si tratta.

Per quanto riguarda dichiarare i timer, potresti metterli come parametro della FB. Quando richiami la FB colleghi i timer da usare.

Sicuramente più elegante è l'utilizzo di SFB4-SFB5 (come suggerito da dott.cicala), soprattutto se i timer li dichiari all'interno della FB come multiistanza.

Oppure utilizzare, all'interno della FB, delle variabili STAT alle quali appoggi il valore del tempo trascorso. Tempo che andrai ad incrementare utilizzando un bit di clock (esempio, fronte salita di un merker di clock), oppure sfruttando la variabile "OB1_PREV_CYCLE" (da appoggiare ad una variabile globale), che dà il tempo in ms dell'ultima scansione.

Link al commento
Condividi su altri siti

Come detto da Batta puoi :

Oppure utilizzare, all'interno della FB, delle variabili STAT alle quali appoggi il valore del tempo trascorso. Tempo che andrai ad incrementare utilizzando un bit di clock (esempio, fronte salita di un merker di clock)

Potresti anche non dover scomodare una FB e crearti anche solo una FC (così non devi istanziare nessuna DB dedicata).

In ingresso :

Enable (Bool) Abilita la funzione

Clock (Bool) fronte di salita bit di clock 100ms (granularità della risoluzione minima)

T_on (Int) preset che potrà essere espresso in decimi di secondo , secondi o minuti

T_off (Int) come sopra

T_base_on (Int) base tempi dei preset (0=decimi - 1=secondi - 2= minuti)

T_base_off (Int) come sopra

In Ingresso/Uscita:

T_on_act (Int) conteggio attuale T_on

T_off_act (Int) conteggio attuale T_off

In Uscita :

Out_cmd (Bool)

Ti crei se vuoi una piccola UDT (per comodità nel caso hai diverse istanze) dove dichiari :

Enable (Bool) Abilita la funzione

Out_cmd (Bool)

T_on (Int) preset che potrà essere espresso in decimi di secondo , secondi o minuti

T_off (Int) come sopra

T_base_on (Int) base tempi dei preset (0=decimi - 1=secondi - 2= minuti)

T_base_off (Int) come sopra

T_on_act (Int) conteggio attuale T_on

T_off_act (Int) conteggio attuale T_off

So che esistono le FB multiistanza ma spesso mi è comodo e flessibile creare delle FC con una struttura di appoggio che poi metto dove più mi pare.

bigalex :blink:

Modificato: da bigalex
Link al commento
Condividi su altri siti

FUNCTION_BLOCK FB 5001
TITLE =PAUSE & WORK
VERSION : 0.1


VAR_INPUT
  ENABLE : BOOL ;	
  T_ON : S5TIME ;	
  T_OFF : S5TIME ;	
END_VAR

VAR_IN_OUT
  Ku : BOOL ;	
END_VAR

VAR
  TM1 : "TON";	
  TM2 : "TON";	
  BIT : BOOL ;	
  Ts1 : TIME ;	
  Ts2 : TIME ;	
END_VAR

BEGIN
NETWORK

TITLE =S5TIME TO TIME

      CALL "S5TI_TIM" (
           IN                       := #T_ON,
           RET_VAL                  := #Ts1);

      CALL "S5TI_TIM" (
           IN                       := #T_OFF,
           RET_VAL                  := #Ts2);

NETWORK
TITLE =TIMING

      U     #ENABLE; 
      UN    #Ku; 
      =     #TM1.IN; 


      CALL #TM1 (
           PT                       := #Ts1);


      CALL #TM2 (
           IN                       := #Ku,
           PT                       := #Ts2);

NETWORK
TITLE =OUTPUT

      U     #ENABLE; 
      FP    #BIT; 
      O     #TM1.Q; 
      S     #Ku; 

      U     #TM2.Q; 
      ON    #ENABLE; 
      R     #Ku; 


END_FUNCTION_BLOCK

Io lo farei così...e se non è necessario s5time si può eliminare S5TIME TO TIME....

Link al commento
Condividi su altri siti

Siamo sempre abituati ad affrontare il problema pausa/lavoro utilizzando due timer.

Ma si può anche fare qualcosa di diverso:

FUNCTION FC 135 : VOID
TITLE =Pausa/Lavoro
VERSION : 0.1


VAR_INPUT
  En : BOOL ;	
  LastScan : INT ;	
  Set_TON : TIME ;	
  Set_TOFF : TIME ;	
END_VAR
VAR_OUTPUT
  Out : BOOL ;	
END_VAR
VAR_IN_OUT
  ET : TIME ;	
END_VAR
VAR_TEMP
  T_Tot : TIME ;	
END_VAR
BEGIN
NETWORK
TITLE =Controllo abilitazione

      U     #En; 
      SPB   _000; 

//Se manca abilitazione, azzerare uscita, azzerare tempo trascorso e abbandonare blocco
      R     #Out; 

      L     T#0MS; 
      T     #ET; 

      BEA   ; 


NETWORK
TITLE =Incremento tempo trascorso e attivazione uscita

_000: L     #Set_TON; 
      L     #Set_TOFF; 
      +D    ; 
      T     #T_Tot; 

      L     #ET; 
      L     #LastScan; 
      ITD   ; 
      +D    ; 
      T     #ET; 
      L     #T_Tot; 
      <D    ; 
      SPB   _001; 
      L     T#0MS; 
      T     #ET; 

_001: L     #ET; 
      L     #Set_TON; 
      <D    ; 
      =     #Out; 


END_FUNCTION

Il risultato è una semplice FC della dimensione di 126 byte.

Non ha bisogno di DB di istanza.

Richiede solamente il tempo di scansione e una doppia word dove appoggiare il tempo trascorso.

Nell'esempio, l'uscita si attiva subito quando viene data l'abilitazione (inizia col ciclo "lavoro").

Togliendo l'abilitazione l'uscita viene immediatamente azzerata e viene azzerato anche il tempo trascorso.

L'impostazione dei tempi è fatta in formato TIME.

Per l'incremento del tempo trascorso utilizzo il tempo di scansione letto in OB1 (OB1_PREV_CYCLE).

Poi, a piacere, con poche e semplici modifiche si può utilizzare un bit di clock al posto del tempo di scansione, decidere di congelare il tempo trascorso se manca l'abilitazione, iniziare con la pausa, o altro a fantasia.

Link al commento
Condividi su altri siti

Per gli amanti dell'SCL:

FUNCTION FC136 : VOID

VAR_INPUT
    Enable:     BOOL;
    LastScan:   INT;
    Set_TON:    TIME;
    Set_TOFF:   TIME;
END_VAR

VAR_IN_OUT
    ET: TIME;
END_VAR

VAR_OUTPUT
    Out:    BOOL;
END_VAR

VAR_TEMP
    // Variabili temporanee

END_VAR


IF Enable THEN
    
    ET := ET + DINT_TO_TIME(INT_TO_DINT(LastScan));
    
    IF ET >= (Set_TON + Set_TOFF) THEN
        ET := T#0MS;
    END_IF;

    Out := (ET < Set_TON);

ELSE
    Out := false;
    ET := T#0ms;
END_IF;    

END_FUNCTION

Qualcuno piglolo (o forse sarebbe giusto dire "preciso") potrebbe far notare che, sia nella versione in AWL che in quella in SCL, sarebbe corretto fare la comparazione che attiva l'uscita prima dell'incremento del tempo trascorso.

Modificato: da batta
Link al commento
Condividi su altri siti

Ciao Batta, anch'io per un po ho usato il tempo scansione per contare il tempo, poi mi sono accorto che con tempi di scansione molto bassi, 1-5 ms il conteggio sbagliava, contava meno.

La spiegazione che mi sono dato è che il tempo scansione da un valore in millisecondi perdendo i valori più piccoli, quindi con tempi di scansione molto bassi questi errori si sommano generando un errore significativo.

Hai mai notato questo fenomeno usando questo sistema?

Da allora se devo contare il tempo trascorso utilizzo l'ora di sistema, memorizzo il valore quando devo cominciare a contare e faccio la sottrazione.

Link al commento
Condividi su altri siti

Chiaro, perchè se la cpu cicla con tempi molto bassi l'arrotondamento al valore intero più vicino produce un errore rilevante.

Fai un loop che rallenta la CPU per farla ciclare sui 100ms :P

Scherzo ovviamente :)

Link al commento
Condividi su altri siti

I bit di clock della cpu ci sono e sono comodi da utilizzare .

L'utilizzo del tempo ciclo della scansione precedente credo vada utilizzato quando effettivamente risulta una valida e più comoda/efficiente alternativa.

Poi ci sono sempre gli ob a tempo ...

bigalex :blink:

Link al commento
Condividi su altri siti

Hai mai notato questo fenomeno usando questo sistema?

Sinceramente no.

Anzi, dalle prove che ho fatto (non molte, a dire il vero) la precisione risultava ottima anche con tempi di scansione di 0-2 ms.

Nel 1500 si potrebbe utilizzare l'istruzione RT_INFO, che dà il risultato in formato LTIME (risoluzione in nanosecondi!!!), oppure RUNTIME (valia anche per il 1200) con valore di ritorno in secondi su variabile LREAL (la risoluzione penso sia sempre il nanosecondo).

RT_INFO poi può fornire anche altre interessanti informazioni sui tempi di elaborazione.

RUNTIME può essere utilizzata anche per misurare il tempo richiesto per l'elaborazione di porzioni di codice.

In ogni caso, la mia intenzione principale era quella di offrire lo spunto per un modo alternativo di gestire un pausa/lavoro, che non fosse il solito utilizzo di due timer.

Il risultato, secondo me (indipendentemente dal metodo utilizzato per il conteggio del tempo trascorso), è una funzione molto semplice e leggera.

Link al commento
Condividi su altri siti

Ciao,

Facendo mente locale su quando ho notato questo fenomeno, stavo usando una cpu 300 Vipa 7Speed per questo il tempo scansione era tra 0 e 2 ms e lo usavo per calcolare il tempo ciclo di alcune stazioni di montaggio in una linea (tempo ciclo di circa 11-12 sec).

Da quella volta, ho cambiato sistema di calcolo e non ho più fatto altre prove, per questo ho chiesto un confronto sull'argomento.

Buon Weekend

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...