simonegr Inserito: 3 novembre 2017 Segnala Share Inserito: 3 novembre 2017 Ciao a tutti, forse è una cavolata da fare, ma vorrei fare un contatore a tempo che quando lo richiamo mi aumenta una variabile ogni tot. secondi Grazie mille Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 3 novembre 2017 Segnala Share Inserita: 3 novembre 2017 Con quale PLC? Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 5 novembre 2017 Autore Segnala Share Inserita: 5 novembre 2017 S7 1200 Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 5 novembre 2017 Segnala Share Inserita: 5 novembre 2017 Imposti un timer con il tempo che ti necessita ed alla scadenza del timer incrementi la mtua variabile. Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 6 novembre 2017 Autore Segnala Share Inserita: 6 novembre 2017 Grazie mille, ho buttato giù questa roba IF "Tag_28" = 1 THEN #"#Avvio" := 0; GOTO fine_ciclo; ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); #"#Avvio" := 0; #"#Contatore" := #"#Contatore" + 1; fine_ciclo:; ma non funziona in quanto il Tag_28 non va mai ad 1 Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 IF "Tag_28" = 1 THEN #"#Avvio" := 0; #"#Contatore" := #"#Contatore" + 1; "Tag_29":= 1; "Tag_28":= 0; ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); IF "Tag_29" THEN "Tag_28":= 1; "Tag_29":= 0; END_IF; prova il codice qui di sopra: nel tuo codice non hai MAI un ciclo macchina con il risultato logico combinatorio = 0 per far ripartire il timer. Si potrebbe anche utilizzare l'istruzione di reset del timer Consiglio: quando ci sono i timer non saltare mai altrimenti poi cadi nell'errore che hai fatto. Io non ho testato il codice, Tieni conto che Tag_29 serve proprio a perdere quel famigerato ciclo macchina. Inoltre dopo l'istruzione del timer tu azzeri sempre il flag. In sintesi: ho notato che gli errori fatti presuppongono una programmazione di uno che pensa che l'istruzione successiva sia eseguita solamente quando quella precedente è terminata (vedi timer). NO! Il timer deve sempre ciclare e quando finisce ti troverai il flag .q vero. In alternativa potresti fare anche così: (* a fine conteggio ripristina il timer con un bel FALSE *) IF "Tag_28" = 1 THEN #"#Contatore" := #"#Contatore" + 1; "Tag_28":= 0; "IEC_Timer_0_DB".TP(IN := FALSE, // RESET TIMER ONE SHOT PT := T#40s"); ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", // TIMER CHE CICLA SEMPRE ...... PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 6 novembre 2017 Autore Segnala Share Inserita: 6 novembre 2017 Grazie mille pigroplc, ho testato il codice, ma dopo il primo ciclo non funziona più. Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 eh ho fatto casino, nel primo caso al posto di Tag_28 metti avvio E' l'istruzione prima del reset di Tag_29 così lo fai ripartire Link al commento Condividi su altri siti More sharing options...
batta Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 #TimerClock(IN:=NOT #Clock, PT:=T#10s, Q=>#Clock); IF #Clock THEN #Cnt := #Cnt + 1; END_IF; Per l'esempio ho usato una FB. Le variabili #Clock e #Cnt devono essere STAT. Usando le TEMP non può funzionare. Se si vuole usare come variabile di conteggio una variabile esterna, deve essere passata alla funzione come IN_OUT. Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 6 novembre 2017 Autore Segnala Share Inserita: 6 novembre 2017 Così lo devo modificare ? IF "Tag_28" = 1 THEN #"#Avvio" := 0; #"#Contatore" := #"#Contatore" + 1; "Tag_29" := 1; #"#Avvio" := 0; ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", PT := T#20s, Q => "Tag_28", ET => #"#Time_outti"); IF "Tag_29" THEN #"#Avvio" := 1; "Tag_29" := 0; END_IF; Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 si mentre io ho cercato di seguire parte del tuo ragionamento, Batta ti ha postato la soluzione più corta e performante. Se sei alle prime armi ti suggerisco di provarle entrambe. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 Ma cosa non ti piace del mio esempio? Perché devi, a tutti i costi, complicarti la vita con variabili #Avvio, Tag_28, Tag_29, e un inutile IF-THEN-ELSE? A cosa servono? Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 6 novembre 2017 Autore Segnala Share Inserita: 6 novembre 2017 Grazie mille a tutti, ma non riesco a capire l'esempio di batta ................ Mentre la modifica fatta da pigroplc a me non funziona correttamente Link al commento Condividi su altri siti More sharing options...
batta Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 È molto semplice: Se l'uscita del timer (la variabile #Clock) è FALSE, il timer conta (all'ingresso del timer c'è la condizione "NOT #Clock"). Quando il timer raggiunge il conteggio, #Clock diventa TRUE. Se #Clock = TRUE, viene incrementato il conteggio. Alla scansione successiva avremo #Clock = TRUE (quindi NOT #Clock = FALSE). Il timer si resetta e imposta #Clock = FALSE. Alla successiva scansione, con #Clock = FALSE, il timer ricomincia a contare. È la stessa cosa che succede nell'altro esempio, senza utilizzare le variabili "TAG" e #Avvio. Da tenere presente che il reale tempo di clock non sarà quello impostato come preset del timer, ma il valore di preset + il tempo di scansione (per una scansione il timer non conta). Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 6 novembre 2017 Segnala Share Inserita: 6 novembre 2017 Quote Ma cosa non ti piace del mio esempio?Perché devi, a tutti i costi, complicarti la vita con variabili #Avvio, Tag_28, Tag_29, e un inutile IF-THEN-ELSE? A cosa servono? Batta, premesso che io sono d'accordo con te, mi metto nei panni di uno che si approccia per la prima volta ad un linguaggio strutturato come SCL e che magari ha sempre visto solamente i contatti: ha la tendenza a rendersi la vita "difficile". Io cerco di assecondare e far digerire la soluzione, quindi quando funziona aggiungo un gradino di difficoltà ottimizzando (come nel tuo esempio). Quanto a quello che ho buttato giù io senza stare troppo a pensare, personalmente mi viene la pelle d'oca a riguardare il codice, ma spero di aver chiarito il significato di quanto fatto. simonegr: la soluzione di Batta non parametrizzata: "IEC_Timer_0_DB".TP(IN := NOT "IEC_Timer_0_DB".Q, PT := T#20); IF IEC_Timer_0_DB.Q THEN COUNTER:=COUNTER + 1; END_IF; Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 7 novembre 2017 Autore Segnala Share Inserita: 7 novembre 2017 17 ore fa, pigroplc scrisse: IF "Tag_28" = 1 THEN #"#Avvio" := 0; #"#Contatore" := #"#Contatore" + 1; "Tag_29":= 1; "Tag_28":= 0; ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); IF "Tag_29" THEN "Tag_28":= 1; "Tag_29":= 0; END_IF; prova il codice qui di sopra: nel tuo codice non hai MAI un ciclo macchina con il risultato logico combinatorio = 0 per far ripartire il timer. Si potrebbe anche utilizzare l'istruzione di reset del timer Consiglio: quando ci sono i timer non saltare mai altrimenti poi cadi nell'errore che hai fatto. Io non ho testato il codice, Tieni conto che Tag_29 serve proprio a perdere quel famigerato ciclo macchina. Inoltre dopo l'istruzione del timer tu azzeri sempre il flag. In sintesi: ho notato che gli errori fatti presuppongono una programmazione di uno che pensa che l'istruzione successiva sia eseguita solamente quando quella precedente è terminata (vedi timer). NO! Il timer deve sempre ciclare e quando finisce ti troverai il flag .q vero. In alternativa potresti fare anche così: (* a fine conteggio ripristina il timer con un bel FALSE *) IF "Tag_28" = 1 THEN #"#Contatore" := #"#Contatore" + 1; "Tag_28":= 0; "IEC_Timer_0_DB".TP(IN := FALSE, // RESET TIMER ONE SHOT PT := T#40s"); ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", // TIMER CHE CICLA SEMPRE ...... PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); 16 ore fa, batta scrisse: #TimerClock(IN:=NOT #Clock, PT:=T#10s, Q=>#Clock); IF #Clock THEN #Cnt := #Cnt + 1; END_IF; Per l'esempio ho usato una FB. Le variabili #Clock e #Cnt devono essere STAT. Usando le TEMP non può funzionare. Se si vuole usare come variabile di conteggio una variabile esterna, deve essere passata alla funzione come IN_OUT. 16 ore fa, pigroplc scrisse: eh ho fatto casino, nel primo caso al posto di Tag_28 metti avvio E' l'istruzione prima del reset di Tag_29 così lo fai ripartire Grazie mille a tutti Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 novembre 2017 Segnala Share Inserita: 7 novembre 2017 Quote Quanto a quello che ho buttato giù io senza stare troppo a pensare, personalmente mi viene la pelle d'oca a riguardare il codice, ma spero di aver chiarito il significato di quanto fatto. Guarda che la mia non era una critica, tantomeno rivolta a te. Hai idea di quante cavolate scrivo io, che quando le riguardo mi chiedo se ero ubriaco? Faccio questo lavoro da quasi trent'anni, e non c'è una sola volta che, finito un programma, non mi venga la voglia di ricominciarlo daccapo. Riguardo le difficoltà per passare da un linguaggio a contatti al strutturato, nell'esempio specifico non ho fatto altro che scrivere in strutturato quello che abitualmente si fa in ladder: un timer che si autoresetta. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 novembre 2017 Segnala Share Inserita: 7 novembre 2017 Da alcune prove fatte col simulatore, inserendo un ciclo FOR che calcola 10 mila volte una radice quadrata per allungare i tempi di scansione, sembra che ad ogni ciclo si perda non una, ma due volte il tempo di scansione. Volendo, si può migliorare nel seguente modo: #TimerClock(IN := TRUE, PT := T#10s, Q => #Clock); IF #Clock THEN #Cnt := #Cnt + 1; RESET_TIMER(#TimerClock); END_IF; In questo modo verrebbe da pensare che non si dovrebbe perdere nemmeno una scansione ma, sempre dalle prove fatte col simulatore, sembra invece che si perda una scansione anziché due. Probabilmente il timer ha comunque bisogno di una scansione per resettarsi, e in quella scansione non conta. Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 7 novembre 2017 Autore Segnala Share Inserita: 7 novembre 2017 20 ore fa, pigroplc scrisse: IF "Tag_28" = 1 THEN #"#Avvio" := 0; #"#Contatore" := #"#Contatore" + 1; "Tag_29":= 1; "Tag_28":= 0; ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); IF "Tag_29" THEN "Tag_28":= 1; "Tag_29":= 0; END_IF; prova il codice qui di sopra: nel tuo codice non hai MAI un ciclo macchina con il risultato logico combinatorio = 0 per far ripartire il timer. Si potrebbe anche utilizzare l'istruzione di reset del timer Consiglio: quando ci sono i timer non saltare mai altrimenti poi cadi nell'errore che hai fatto. Io non ho testato il codice, Tieni conto che Tag_29 serve proprio a perdere quel famigerato ciclo macchina. Inoltre dopo l'istruzione del timer tu azzeri sempre il flag. In sintesi: ho notato che gli errori fatti presuppongono una programmazione di uno che pensa che l'istruzione successiva sia eseguita solamente quando quella precedente è terminata (vedi timer). NO! Il timer deve sempre ciclare e quando finisce ti troverai il flag .q vero. In alternativa potresti fare anche così: (* a fine conteggio ripristina il timer con un bel FALSE *) IF "Tag_28" = 1 THEN #"#Contatore" := #"#Contatore" + 1; "Tag_28":= 0; "IEC_Timer_0_DB".TP(IN := FALSE, // RESET TIMER ONE SHOT PT := T#40s"); ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", // TIMER CHE CICLA SEMPRE ...... PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); 20 ore fa, batta scrisse: #TimerClock(IN:=NOT #Clock, PT:=T#10s, Q=>#Clock); IF #Clock THEN #Cnt := #Cnt + 1; END_IF; Per l'esempio ho usato una FB. Le variabili #Clock e #Cnt devono essere STAT. Usando le TEMP non può funzionare. Se si vuole usare come variabile di conteggio una variabile esterna, deve essere passata alla funzione come IN_OUT. 20 ore fa, pigroplc scrisse: eh ho fatto casino, nel primo caso al posto di Tag_28 metti avvio E' l'istruzione prima del reset di Tag_29 così lo fai ripartire Se invece dovessi incrementare ogni 10 secondi ? Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 novembre 2017 Segnala Share Inserita: 7 novembre 2017 Quote Se invece dovessi incrementare ogni 10 secondi ? Non ho capito la domanda. Il tempo lo decidi tu, impostando il preset del timer. Puoi mettere il tempo che vuoi. Ricorda che questo sistema, dato che sbaglia di una o due scansioni ad ogni ciclo (dipende dal codice che andrai ad utilizzare) va bene solo per tempi non troppo brevi, dove l'errore dovuto ai tempi di scansione è trascurabile. Se vuoi maggior precisione, utilizza gli OB a tempo. Link al commento Condividi su altri siti More sharing options...
simonegr Inserita: 7 novembre 2017 Autore Segnala Share Inserita: 7 novembre 2017 il 06/11/2017 at 15:09 , pigroplc scrisse: IF "Tag_28" = 1 THEN #"#Avvio" := 0; #"#Contatore" := #"#Contatore" + 1; "Tag_29":= 1; "Tag_28":= 0; ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); IF "Tag_29" THEN "Tag_28":= 1; "Tag_29":= 0; END_IF; prova il codice qui di sopra: nel tuo codice non hai MAI un ciclo macchina con il risultato logico combinatorio = 0 per far ripartire il timer. Si potrebbe anche utilizzare l'istruzione di reset del timer Consiglio: quando ci sono i timer non saltare mai altrimenti poi cadi nell'errore che hai fatto. Io non ho testato il codice, Tieni conto che Tag_29 serve proprio a perdere quel famigerato ciclo macchina. Inoltre dopo l'istruzione del timer tu azzeri sempre il flag. In sintesi: ho notato che gli errori fatti presuppongono una programmazione di uno che pensa che l'istruzione successiva sia eseguita solamente quando quella precedente è terminata (vedi timer). NO! Il timer deve sempre ciclare e quando finisce ti troverai il flag .q vero. In alternativa potresti fare anche così: (* a fine conteggio ripristina il timer con un bel FALSE *) IF "Tag_28" = 1 THEN #"#Contatore" := #"#Contatore" + 1; "Tag_28":= 0; "IEC_Timer_0_DB".TP(IN := FALSE, // RESET TIMER ONE SHOT PT := T#40s"); ELSE #"#Avvio" := 1; END_IF; "IEC_Timer_0_DB".TP(IN := #"#Avvio", // TIMER CHE CICLA SEMPRE ...... PT := T#40s, Q => "Tag_28", ET => #"#Time_outti"); il 06/11/2017 at 15:49 , batta scrisse: #TimerClock(IN:=NOT #Clock, PT:=T#10s, Q=>#Clock); IF #Clock THEN #Cnt := #Cnt + 1; END_IF; Per l'esempio ho usato una FB. Le variabili #Clock e #Cnt devono essere STAT. Usando le TEMP non può funzionare. Se si vuole usare come variabile di conteggio una variabile esterna, deve essere passata alla funzione come IN_OUT. il 06/11/2017 at 15:41 , pigroplc scrisse: eh ho fatto casino, nel primo caso al posto di Tag_28 metti avvio E' l'istruzione prima del reset di Tag_29 così lo fai ripartire Ciao Batta, io ho copiato il tuo programma e lo sto simulando ma non mi sembra che il conteggio aumenti di uno ogni 10 secondi ........... Link al commento Condividi su altri siti More sharing options...
batta Inserita: 7 novembre 2017 Segnala Share Inserita: 7 novembre 2017 Quote Ciao Batta, io ho copiato il tuo programma e lo sto simulando ma non mi sembra che il conteggio aumenti di uno ogni 10 secondi ........... Se hai seguito tutte le istruzioni (la variabile #Clock NON deve essere una variabile temporanea), ti posso assicurare che funziona. Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 7 novembre 2017 Segnala Share Inserita: 7 novembre 2017 Quote Guarda che la mia non era una critica, tantomeno rivolta a te. Batta, ti assicuro che non l'ho presa come una critica. Siccome ritengo che tu sia un professionista, ho solamente espresso il mio parere per uno scambio costruttivo, dicendo che io il tuo esempio l'ho capito mentre per simonegr era un po' ostico. Tutto qui. Link al commento Condividi su altri siti More sharing options...
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