Vai al contenuto
PLC Forum


Funzionamento Accumulatore Im151-8


luca_82

Messaggi consigliati

Ciao a tutti, qualcuno di voi sa darmi delucidazioni riguardo al funzionamento degli accumulatori, ho letto i manuali ma evidentemente qualcosa mi è sfuggito...

Nel mio Main richiamo una FC scritta in AWL in cui ho scritto le seguenti istruzioni:

A I1.2

L MB108

INC 1

T MB108

Per quello che avevo capito io ogni volta che l'ingresso I1.2 va alto il byte 108 viene incrementato di un unità, mentre io lo vedo aggiornarsi di continuo, ed ho controllato che i bit di quel byte non vengono scritti in altri punti di programma ma solamente dentro questa FC....

Ciao e grazie in anticipo.

Link al commento
Condividi su altri siti


Le tre istruzioni dell'incremento se vengono incontrate sono sempre eseguite. Per ottenere quello che dici devi saltarle

A I1.2
SPBN salt // passa a "salt" se I1.2 è falso
L MB108
INC 1
T MB108
salt: NOP 0

Link al commento
Condividi su altri siti

Sono "fresco" di awl ma penso sia bene precisare che nel periodo in cui l'ingresso è alto, se non fai un controllo sul fronte di salita (FP), il conteggio aumenta comunque in maniera imprecisata a seconda del tempo di ciclo (il che può essere voluto ma non ho idea a cosa possa servire). Ovviamente sempre che non si tratti di impulsi di durata inferiore al tempo di ciclo (è possibile esserne sicuri a priori?). Magari potrebbe farti comodo anche un contatore se riesci ad adattarlo allo scopo.

Modificato: da pomat
Link al commento
Condividi su altri siti

Ciao,

Pomat dice bene, secondo me, e questo vale a prescindere dal linguaggio utilizzato: ci vuole sempre il rilevamento del fronte di salita, quando conti e/o incrementi una variabile, altrimenti corri il rischio, se l'ingresso rimane attivo più del ciclo di scansione (cosa molto facile) di contare / incrementare più del desiderato.

E, sempre secondo me, anche rguaresc ha centrato l'altro problema, il più gravoso: in AWL le istruzioni LD, INC e T sono sempre eseguite (ce ne sono altre ...), a meno di non effettuare un salto.

Link al commento
Condividi su altri siti

A dire il vero Drugo io ho anche provato a scrivere così:

A I1.2

FP M1.0

LB 108

INC 1

T 108

Però il risultato non cambia, stavo facendo queste prove in realtà solo per capire come lavorano gli accumulatori, in questa Cpu non ho il Byte di clock, ma ho provato a crearlo copiando di pari passo il programma che è scritto nel manuale solo che non mi andava e non capivo perchè.... Il programma era questo:

U T1

L S5T#250ms

SV T1

NOT

BEB

L MB108

INC 1

T MB108

Questo programma dovrebbe ogni 250ms incrementare di un unità la Mb108, solo che in realtà il temporizzatore non parte mai, poi ho provato a modificarlo un pò solo che l'accumulatore si aggiornava ma non con una frequenza costante e da lì mi è venuto il dubbio che stavo sbagliando qualcosa con gli accumulatori!!

Link al commento
Condividi su altri siti

L'operazione di carico viene sempre eseguita, ma questo a prescindere dall'RLC che ho in precedenza?

Se io scrivo:

U E1.2

FP M1.0

L MB108

INC 1

T MB108

Lui la prima volta vede il fronte sull' ingresso 1.2, poi il fronte non lo legge più ma lui esegue comunque il carico di MB108 nell'accumulatore?

So che il programma che mi avete scritto in precedenza funziona ma era per capire il perchè!!

Link al commento
Condividi su altri siti

Ciao Luca,

come ti hanno scritto gli altri le operazioni L e T non sono influenzate da RLC, per cui puoi mettere prima tutte le operazioni che vuoi ma se non fai un salto condizionato saranno sempre eseguite.

Se vuoi eseguire un incremento solo sul fronte devi scrivere così:

U E1.2

FP M1.0

SPBN M001

L MB108

INC 1

T MB108

M001: NOP 0 (o qualsiasi altra istruzione ti serva)

Io poi personalmente non userei l'istruzione INC perchè lavora a 8 bit e non fa riporto dal byte basso al byte alto; la riscriverei così:

U E1.2

FP M1.0

SPBN M001

L MB108

L 1

+, I

T MB108

M001: NOP 0 (o qualsiasi altra istruzione ti serva)

Per quanto riguarda l'altro pezzo di programma secondo me non parte perchè usi T1 per far partire T1: in questo modo, supponendo che T1 parta sempre da uno stato basso, la sequenza non si avvia mai.

Ciao.

Massimo

P.S.: mi sono accorto dopo che lavori già comunque solo su un byte e quindi anche INC 1 va bene... ariciao

Modificato: da bleny
Link al commento
Condividi su altri siti

Ok grazie,domani da buon programmatore faccio qualche prova fino a che riesco a tenere l'impianto fermo senza essere sbranato....

Grazie ancora dei consigli, sempre utilissimi!!

Link al commento
Condividi su altri siti

Per quanto riguarda il conteggio, ti ha già risposto correttamente, almeno secondo me, Bleny, che ti ha scritto anche un pezzo di codice funzionante.

Per il timer l'esempio dovrebbe essere questo, copiato dal manuale (AWL per S7-300/400):

UN  T1          // Se non è scaduto il temporizzatore T1
L  S5T#250ms    // carica il valore di tempo 250ms in T1
SV T1           // ed avvia T1 come un generatore di impulso prolungato
NOT             // Nega (inverte) il risultato logico combinatorio (RLC)
BEB             // Se il tempo è in corso, termina il blocco attuale (BEB=Fine blocco condizionato)

L MB100         // Se il temporizzatore è scaduto, carica il contenuto del byte del
INC 1           // merker MB100, incrementa il contenuto di 1 e
T MB100         // trasferisce il risultato al byte di merker MB100

Non l'ho provato, ma dovrebbe andare; il timer non lo vedrai mai andare a uno, perchè dura solo una scansione, essendo attivato da se stesso: quindi, quando T1 è zero, il timer conta, il NOT inverte RLC ed il blocco termina lì (BEB); quando il timer termina di contare si attiva, quindi dopo il NOT RLC è uno (vero), quindi esegue l'incremento; poi ritorna ad eseguire il blocco dall'inizio ed essendo T1 a uno, resetta se stesso e tutto ricomincia.

Onestamente è un modo di scrivere che non mi piace molto: avrei preferito usare una variabile di appoggio, quindi:

UN  M0.0         // Controllo la variabile di appoggio
L  S5T#250ms
SE T1            // Ritardo all'inserzione
U  T1
S  M0.0          // Setto la variabile scaduto il tempo
NOT
BEB

L MB100
INC 1
T MB100
R M0.0           // Resetto la variabile una volta incrementato

Con l'AWL sono un po' arrugginito, ma così lo preferisco e dovrebbe anche funzionare.

Modificato: da drugo66
Link al commento
Condividi su altri siti

Ciao drugo, in merito all'ultima tua risposta ho provato il programmino che mi hai scritto ma ci sto un po impazzendo e non va. Il problema è che una volta scaduto il temporizzatore lui setta M0.0 che poi però non viene più resettata e sulla riga U T1 io ho sempre un valore 1.

L'accumulatore continua ad aggiornarsi ed il programma rimane piantato li...

Però è strano perchè quando resetto M0.0, ed una volta la resetto per forza, T1 non dovrebbe cadere?

Link al commento
Condividi su altri siti

in questa Cpu non ho il Byte di clock

Se vuoi capire come funzionano gli accumulatori OK, ma il byte di clock c'è anche nella IM151-8

fe791665c6dc4e7ee3d5f381c6430f07.png

Link al commento
Condividi su altri siti

Sono al lavoro e non ho molto tempo; a naso puo' darsi che RLC nel punto in cui c'è R M0.0 non sia uno; verifica che M0.0 non sia mai resettato e prova a scrivere:

L MB100
INC 1
T MB100
SET              // Imposta RLC incondizionatamente a uno
R M0.0           // Resetto la variabile una volta incrementato

altrimenti rimandiamo a stasera.

P.S.: ... con l'AWL sono proprio arrugginito :wacko:

Modificato: da drugo66
Link al commento
Condividi su altri siti

Se comprendo bene, penso che l'arcano sia semplicemente dovuto ad un'inversione della semantica: i T nelle espressioni logiche valgono 1 se in corso e 0 se scaduti (come i contatori valgono 0 solo quando sono azzerati), mentre qui è stato considerato l'opposto. Quindi nel codice sopra, UN T1 abilita quando T1 è scaduto, mentre U T1 abilita quando T1 è in corso. Infatti l'incremento dovrebbe avvenire (sempre se capisco bene) ogni volta che T1 scade, cioè BEB non deve essere eseguita quando UN T1 abilita (da qui il NOT). Datemi conferma, sono curioso :)

Link al commento
Condividi su altri siti

Probabilmente Dan la tua schermata è quella del vecchio Step 7, io vado con Tia-portal V13.

Sulla configurazione Hardware mi fa impostare un Byte di clock, poi però se vado a guardare i singoli bit rimangono alti!!

In realtà si era anche per capire come funzionano gli acumulatori ma se trovo un altra soluzione ben venga, ci stò impazzendo!! :wacko::wacko:

Link al commento
Condividi su altri siti

A parte che impazzire ci fa bene :D nel senso che le soluzioni "sudate" sono quelle che rimangono.

E' senz'altro un problema di TIA Portal non della CPU.

Io lo uso solo per 1200/1500, a quanto pare le incompatibilità con la serie 300/400 sono parecchie :wacko:

E' scandaloso che alla versione 13 stiamo ancora a fare i beta testers.

Modificato: da dan64100
Link al commento
Condividi su altri siti

Livio Orsini

E' scandaloso che alla versione 13 stiamo ancora a fare i beta testers.

Rientra nelle tradizioni della casa, anche se qui sembra stiano andando oltre le perverse abitudini. ;)

Link al commento
Condividi su altri siti

i T nelle espressioni logiche valgono 1 se in corso e 0 se scaduti

No.

Lo stato del timer è alto quando è scaduto il tempo.

Sulla configurazione Hardware mi fa impostare un Byte di clock, poi però se vado a guardare i singoli bit rimangono alti!!

Controlla bene. Questa cosa funziona. Hai trasferito la configurazione modificata alla CPU?

Link al commento
Condividi su altri siti

Sono cotto come una pera ed ho una fame da lupo, ma sono riuscito a mettere insieme qualcosa che funziona; ho creato un clock ogni 2 secondi, della durata di 100 mS, anche se la CPU ha il suo bel byte di clock; al fronte di salita del clock, parte l'incremento, quindi ogni 2 secondi; con l'esempio fornito da Siemens, il conteggio avveniva indipendetemente dal valore del timer, mentre quello che avevo postato io non vuole saperne di andare (lo ripeto: sono proprio arrugginito con l'AWL ...).

      UN    M     18.0
      L     S5T#2S
      SE    T     20
      NOP   0
      U     M     18.0
      L     S5T#100MS
      SE    T     21
      NOP   0
      U     T     20
      S     M     18.0
      NOP   0
      U     T     21
      R     M     18.0
      NOP   0
      U     M     18.0
      FP    M     18.1
      SPB   LBL2
      SPA   LBL1
LBL2: NOP   0
      L     MB   200
      INC   1
      T     MB   200
LBL1: NOP   0

Provato con il simulatore e funziona; sicuramente esisterà un sistema più semplice, ma il tempo è tiranno, questo è un periodo infernale e ormai l'AWL lo uso ben poco: volendo basta sostituire M18.0 con il clock della CPU desiderato.

Vado a mangiare qualcosa, altrimenti svengo ...

Modificato: da drugo66
Link al commento
Condividi su altri siti

Lo stato del timer è alto quando è scaduto il tempo.

Intendevo l'impulso, non il ritardo all'inserzione (non avevo notato che drugo nel suo aveva usato quest'ultimo). Spero di aver capito almeno la temporizzazione a impulso :(

Modificato: da pomat
Link al commento
Condividi su altri siti

Per il temporizzatore SV riporto quanto scritto nei manuali:

SV avvia il temporizzatore indirizzato quando RLC passa da "0" a "1". Il count-down del tempo programmato prosegue anche se nel frattempo RLC ritorna a "0". Il passaggio di RLC da "0" a "1" prima della scadenza del tempo programmato determina il riavvio della durata di tempo programmata. Per eseguire l'operazione di avviamento del temporizzatore, il valore e la base di tempo devono essere stati memorizzati in formato BCD nell'accumulatore 1-L.

Infatti il mio errore era proprio nel fatto di aver cambiato il tipo di timer (chissà perchè l'ho fatto poi ... :senzasperanza: ); adesso che ho mangiato e mi sono rilassato per un po', rettifico anche quanto ho sostenuto sopra: l'esempio di Siemens con il timer SV funziona benissimo e, aumentando il tempo, l'incremento diventa più lento.

Riepilogando, questo funziona:

UN    T     24
L     S5T#2S
SV    T     24
NOT   
BEB   
L     MB   300
INC   1
T     MB   300

mentre, se si vuole utilizzare un clock di sistema ed ammettendo che M0.5 sia appunto questo clock:

      U     M     0.5
      FP    M     18.0
      SPB   LBL2
      SPA   LBL1
LBL2: NOP   0
      L     MB   200
      INC   1
      T     MB   200
LBL1: NOP   0

In questo caso si deve per forza utilizzare il rilevamento del fronte, perchè il clock di sistema dura lo stesso tempo per lo stato attivo che disattivo (duty cycle 50%), quindi senza fronte si incrementerebbe la variabile per tutto il tempo che il clock è attivo; occorre anche effettuare i salti perchè le istruzioni L, T e INC avvengono anche con RLC uguale 0: SPA è un salto incodizionato, mentre SPB è un salto condizionato.

Link al commento
Condividi su altri siti

Piccola semplificazione:

      U     M     0.5
      FP    M     18.0
      SPBN   LBL1
      L     MB   200
      INC   1
      T     MB   200
LBL1: NOP   0

Attenzione poi all'uso dell'istruzione INC, che va bene solo per operazioni con byte.

Quindi, nel caso specifico che si desidera incrementare MB200 va tutto bene. Se si volesse incrementare MW200 o MD200 non andrebbe più bene.

Meglio usare l'istruzione + 1 al posto di INC 1

Link al commento
Condividi su altri siti

Velocissima risposta a Pomat.

I timer che valgono 1 durante il conteggio e 0 quando sono scaduti (cioè quando è passato il tempo impostato) sono quelli comandati da SI e SV.

Quelli comandati da SE e SS, invece si comportano esattamente al contrario, cioè valgono 0 durante il conteggio e 1 quando è passato il tempo impostato.

Poi ovviamente tra SI-SV e tra SE-SS ci sono le differenze dovute al comportamento quando viene levato il comando di attivazione.

Ciao.

Massimo

Link al commento
Condividi su altri siti

Ciao a tutti, effettivamente si, non avevo ricaricato la configurazione Hardware.....!!

Ora la sto facendo lavorare con il byte di clock, per quanto riguarda l'AWL ci rimetterò le mani quando avrò un pò più calma ed esperienza soprattutto!!

Per quanto riguarda il software devo dire che è abbastanza scandaloso, passando alla professional V13 ho ancora il problema che il PC si pianta all'improvviso e mi chiede di chiudere il programma, logicamente se non salvo ogni tanto rischio di perdere tutto!! :angry::angry: :angry:

E se pensi che questo problema ce l'ho avuto passando per mla licenza Basic V12,0 V11 e V12, ritrovarselo alla professional con quello che costa non è il Max..... :thumbdown::thumbdown:

Link al commento
Condividi su altri siti

@bleny Grazie per la conferma, infatti io mi riferivo all'esempio estratto dal manuale AWL, e al fatto che nella spiegazione di drugo la semantica di SV era invertita (cioè al contrario del manuale).

Più in generale direi che il valore di un T in un'espressione logica in un dato momento dipende da tre fattori:

- modalità di temporizzazione (SI, SV, SE, SS, SA)
- stato del conteggio: in corso, scaduto o cancellato (istruzione R)
- valore RLC rispetto al merker del fronte interno (influenzato eventualmente dall'istruzione FR)

gli ultimi due riferiti sempre all'ultima esecuzione dell'istruzione Sx (x = I, V, E, S, A) precedente la valutazione di T nell'espressione logica.


Dall'ultimo punto può nascere un problema subdolo che ho riscontrato ad esempio nel vecchio codice di Drugo:

UN  M0.0
L   S5T#250ms
SE  T1
U   T1
S   M0.0
NOT
BEB

L   MB100
INC 1
T   MB100
SET
R   M0.0

Dato che il bit di appoggio M0.0 viene eventualmente settato e resettato nello stesso ciclo di scansione, e non "a cavallo" dell'istruzione SE, quest'ultima non se ne accorge (vede RLC sempre uguale al merker del fronte interno) e il timer non riparte.

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