Vai al contenuto
PLC Forum


Move vs Reset


TheOutSideR

Messaggi consigliati

Si può utilizzare la funzione move come reset impostando il valore di 0 e indirizzandolo ad un merker? Se si potrebbe essere più vantaggioso o svantaggioso secondo voi?

Link al commento
Condividi su altri siti


Credo l'esempio sia ;  ho un contatore cicli parziali di un macchinario....e sono arrivato che so .. a 530....inizio un ciclo nuovo, voglio azzerare il contatore per contare  la produzione ...associo  un fronte ad un pulsante   anche Hmi    al fronte  scrivo move 0 nella variabile, e questa viene azzerata     forse il termo e resettata  non è  corretto

 

Reset sa di 0

 

Move  , potrei ad esempio forzare un valore anche diverso da 0 , che so   10  come  0 come 5557464

Link al commento
Condividi su altri siti

21 ore fa, luigi69 ha scritto:

Credo l'esempio sia ;  ho un contatore cicli parziali di un macchinario....e sono arrivato che so .. a 530....inizio un ciclo nuovo, voglio azzerare il contatore per contare  la produzione ...associo  un fronte ad un pulsante   anche Hmi    al fronte  scrivo move 0 nella variabile, e questa viene azzerata     forse il termo e resettata  non è  corretto

 

Reset sa di 0

 

Move  , potrei ad esempio forzare un valore anche diverso da 0 , che so   10  come  0 come 5557464

intendevo qualcosa appunto del genere dove il move riporta a zero un valore di un blocco (non sottoforma di bit).  però io vedo le due finzioni molto simili (almeno in questo caso).

Link al commento
Condividi su altri siti

Il 26/1/2020 alle 16:30 , TheOutSideR ha scritto:

intendevo qualcosa appunto del genere dove il move riporta a zero un valore di un blocco (non sottoforma di bit).  però io vedo le due finzioni molto simili (almeno in questo caso).

Non ho capito bene ma come dice batta il move parte dai byte e quindi non può mettere a zero un bit.

Quindi: 

Se devi mettere a zero un bit al fonte del tuo comando vai a utilizzare il reset del bit.

Se devi mettere a zero un contatore il fronte del tuo comando lo invii al reset R del contatore...se devi partire da un numero diverso da 0 lo scrivi nell'ingresso preset PV del contatore stesso.

Ovviamente in SCL tutto questo risulta più semplice perché lo fai con l'assegnazione := sia da bit a bit e sia da int a int ad esempio per un valore.

Link al commento
Condividi su altri siti

18 ore fa, Cristian Nori ha scritto:

Non ho capito bene ma come dice batta il move parte dai byte e quindi non può mettere a zero un bit.

Quindi: 

Se devi mettere a zero un bit al fonte del tuo comando vai a utilizzare il reset del bit.

Se devi mettere a zero un contatore il fronte del tuo comando lo invii al reset R del contatore...se devi partire da un numero diverso da 0 lo scrivi nell'ingresso preset PV del contatore stesso.

Ovviamente in SCL tutto questo risulta più semplice perché lo fai con l'assegnazione := sia da bit a bit e sia da int a int ad esempio per un valore.

ok quindi ora farò delle prove. quindi da come ho capito il move non agisce come reset (almeno nel s7 1200) di bit ma solo di byte o word. per esempio lo uso quando ci sono di mezzo valori analogici da portare ad un determinato valore ( che può essere anche 0)

ma non significano reset!?

Modificato: da TheOutSideR
Link al commento
Condividi su altri siti

Set e reset, come istruzioni plc, tipicamente si riferiscono a variabili booleane. Certo poi che, se imposto un valore in una variabile, posso dire che ho settato la variabile, o che se ho scritto il valore zero, ho resettato la variabile. Ma l'istruzione che si usa in questo caso si chiama MOVE. Che poi MOVE è nel linguaggio ladder.
Per esempio, in SCL (strutturato) non uso una istruzione MOVE ma, semplicemente, faccio un'assegnazione. Esempio:
myVar1 := myVar2;

In strutturato scrivo nello stesso modo, sia che le variabili myVar1 e myVar2 siano booleane, byte, int, o altro.

Per settare o resettare una variabile booleana in strutturato, scriverei così:

myVarBool := TRUE; (Al posto di TRUE posso scrivere 1)
myVarBool := FALSE; (Al posto di FALSE posso scrivere 0)

 

Poi, molto spesso, si azzera una variabile per resettare tutti i bit della variabile, che sono magari usati nel programma come variabili booleane.

 

Insomma, il concetto non cambia se mi riferisco ad una variabile booleana o di altro tipo ma, programmando in ladder, in quasi tutti i plc, per le operazioni su variabili booleane si usano le istruzioni SET, RESET, o il simbolo della bobina; per le altre variabili, c'è il MOVE.

Link al commento
Condividi su altri siti

Sì, certo che si può. La sintassi per accedere ad un bit di una word, sia in ladder che in strutturato, è: myWord.%Xn (dove n è il numero del bit, partendo dal bit zero, che è il bit a destra). Puoi anche non scrivere il %, che TIA lo aggiunge da solo. Analogamente ai bit, si può accedere anche al byte (myWord .%Bn), o alla word (MyDWord.%Wn).

Personalmente uso questo sistema in casi molto rari, perché, probabilmente a causa dei limiti della mia memoria, mi piace avere sempre un nome della variabile che mi faccia capire subito cos'è.

Il TIA è orientato alla programmazione simbolica. Quando crei un blocco (FC, FB, DB), puoi scegliere se farlo "ottimizzato", o "non ottimizzato". Dicitura ingannevole, ma che in pratica significa, rispettivamente, con variabili allocate dalla cpu delle quali tu non conosci l'indirizzo (e in questo modo la cpu lavora in modo molto più efficiente, da cui nasce "ottimizzato"), o variabili indirizzate alla "vecchia maniera". Siemens consiglia vivamente, salvo i casi nei quali è indispensabile conoscere l'indirizzo delle variabili, di lavorare con blocchi ottimizzati. Da prove che ho fatto, con blocchi ottimizzati ho rilevato velocità di esecuzione superiori anche di oltre 5 volte.

Perché mi sono perso su questa storia dei blocchi ottimizzati? Perché se si lavora con blocchi non ottimizzati, ovviamente, si può accedere al bit di una variabile anche tramite l'indirizzo assoluto. Pratica che, personalmente, considero abominevole, dato che se sposti una variabile va tutto a p....

Pratica questa da abbandonare, tanto che nel TIA eventuali accessi a indirizzi assoluti vengono evidenziati in giallo.

E che si fa lavorando con blocchi ottimizzati, che gli indirizzi delle variabili nemmeno si conoscono? Un modo è appunto quello detto prima: myWord.%Xn. Ma si può fare di meglio, con quella che nel TIA viene chiamata "sovrapposizione con AT". Tu dichiari una variabile, per esempio di ti po Word (myWord). Subito sotto dichiari una variabile (myBits) e, nel tipo di variabile, scrivi AT. TIA ti farà vedere nel nome della variabile che non è una nuova variabile, ma è riferita a myWord. Fatto questo, definisci il tipo di variabile. Potrebbe essere un array di bit o di byte, o una struttura contenente bit o byte, ai quali puoi assegnare liberamente i nomi. Importante, ovviamente, rispettare le dimensioni.

In questo modo puoi accedere ai singoli bit di una variabile col nome anziché con un numero. 

Link al commento
Condividi su altri siti

On 1/30/2020 at 1:31 AM, batta said:

Fatto questo, definisci il tipo di variabile. Potrebbe essere un array di bit o di byte, o una struttura contenente bit o byte, ai quali puoi assegnare liberamente i nomi. Importante, ovviamente, rispettare le dimensioni.

In questo modo puoi accedere ai singoli bit di una variabile col nome anziché con un numero. 

 

Il mio vecchio, programmatore di PLC prettamente AllenBradley, usava questa logica per la costruzione di cicli automatici. Nel suo MicroLogix e SLC-500 (corrispettiva tecnologia del S7-200/300) non si usava molto alzare il bit univoco di una WORD, come oggi si fa inserendo un COIL ed assegnando l'indirizzo Word.%Xn (per esempio l'assegnazione standard dei bit usata nell' HMI alarm del TIA), ma, muoveva un valore decimale (che sia 2,4,8,16,32,64 ecc. nonché i valori decimali che raggiunge una WORD quando alziamo i corrispettivi bit) in uno "slot di Booleani".

Qui torniamo al discorso originario di questa discussione. Non sono d'accordo con il fatto che non si può usare l'istruzione MOVE su un bit, in quanto oggi è cambiata secondo me la concettualità di ciò che si fa, facendo esattamente ciò che si faceva prima, in maniera diversa.

 

Creo un Data Table di 16 elementi BINARY su B3.

Ho la possibilità di settare nel programma 16 bit, usando la sintassi OTE B3/0 (o OTL/OTU se si vuole eseguire un Latch/Unlatch) per il primo bit, fino a B3/15 che è l'ultimo bit del Data Table appena creato.

Differentemente, posso fare MOV 2 in B3:0, e vedrò che B3/0 è diventato vero.

Posso fare MOV 16 in B3:0 e vedro che B3/0, B3/1, B3/2, B3/3, sono diventati veri.

A questo punto, io posso anche solo voler settare OTL B3/1 con un fronte positivo , e nel momento in cui voglio resettare il bit, fare MOV 0 su B3:0. Ho appena eseguito l'istruzione MOV su un bit 😀

 

Logica contraria, creo un Data Table di un elemento Integer su N7.

Aprendo il Data Table vedrò che avrò a disposizione una sola WORD, N7:0.

In N7:0 posso fare MOV 2 (setto un valore decimale in una WORD). Differentemente, posso fare un OTU (reset su siemens) su N7:0/0, e vedrò che il valore di quella word è andato a zero. Ho appena eseguito l'istruzione reset su una WORD 😀

 

Di conseguenza, posso assegnare un simbolo su B3:0 che chiamerò W_AUTO e poi assegnare un simbolo a B3/0 che sarà Step 1, B3/1 sarà Step 2, e così via...

 

Parliamo solo di concettualità, perché a fare, si può fare tutto

Modificato: da Folder
Link al commento
Condividi su altri siti

4 ore fa, Folder ha scritto:

Differentemente, posso fare MOV 2 in B3:0, e vedrò che B3/0 è diventato vero.

Posso fare MOV 16 in B3:0 e vedro che B3/0, B3/1, B3/2, B3/3, sono diventati veri.

Non sono pratico della sintassi AB ma, scrivendo 2 in B3 mi aspetto di vedere alto il bit B3;1, e non B3:0.

Scrivendo 16, mi aspetto di vedere alto il bit B3:4.

Inoltre, per fare il set di un bit senza modificare gli altri, si dovrebbe fare un OR, e non un MOVE. Per il reset, si dovrebbe invece fare un AND con il complemento a 1.

Ma, a parte questo, vuoi mettere la leggibilità del programma, scrivendo (e leggendo) il nome del bit al posto di un numero?

Link al commento
Condividi su altri siti

A livello di efficienza, valutando che oggi il 90% dei PLC non sono più su microcontrollori dedicati, ma sono tutti softPLC che girano su OS realtime su CPU tradizionali, non credo cambi assolutamente nulla! Un RESET verrebbe tradotto in una maschera boolena e copiato sull'indirizzo del dato in quanto nessuno microprocessore ARM o ATOM (ed usano quasi tutti quelli) supporta operazioni dirette sui bit (Almeno non quelli che conosco io)!
Poi ognuno fa cose un po' diverse. Le booleane OMRON per esempio sono bit di word e occupano un sacco di risorse di calcolo della CPU, quelle di codesys sono BYTE come nei PC con 0 = FALSE e gli altri valori = TRUE le quali occupano più memoria (che oggi a parte alcune prese per i fondelli dei produttori di PLC che vendono solo più fumo è regalata), ma molta meno CPU. Fanno eccezione gli IO diretti, ma quelli mappati no! Su SIEMENS non mi sono mai preso il mal di pancia di analizzare, a differenza degli altri due dove ne ho avuto la necessità dovendo mappare strutture dati condivise su socket TCP e datagrammi UDP.


Comunque oggi non mi porrei il problema dell'efficienza! Se un tornio a controllo con 5 gruppi di assi interpolati e tutto il PLC, 5 interpreti di gCode e interpolatori separati, ha una ciclica veloce che occupa una media di 40us di 1ms ed una ciclica lenta che occupa una media di 70us su 10ms, non ha più senso parlare di prestazione! Anche facendo le cose male è difficile saturare l'hardware moderno! A meno che i produttori non impongano limitazioni software rallentando intenzionalmente il processo (non mi stupirei).

A livello di leggibilità quoto batta! Non ci sono paragoni il RESET (Fuori da SCL) è molto più leggibile.

Modificato: da Marco Mondin
Link al commento
Condividi su altri siti

8 ore fa, batta ha scritto:

Ma, a parte questo, vuoi mettere la leggibilità del programma, scrivendo (e leggendo) il nome del bit al posto di un numero?

come non condividere

Link al commento
Condividi su altri siti

8 hours ago, batta said:

Non sono pratico della sintassi AB ma, scrivendo 2 in B3 mi aspetto di vedere alto il bit B3;1, e non B3:0.

Scrivendo 16, mi aspetto di vedere alto il bit B3:4.

Inoltre, per fare il set di un bit senza modificare gli altri, si dovrebbe fare un OR, e non un MOVE. Per il reset, si dovrebbe invece fare un AND con il complemento a 1.

Ma, a parte questo, vuoi mettere la leggibilità del programma, scrivendo (e leggendo) il nome del bit al posto di un numero?

 

C'è stato errore di calcolo da parte mia, se mando ad 1 una word, di conseguenza alzo un bit. B3:0 è lo slot di booleani da 0 a 15, B3:1 è lo slot da 16 a 31 e così via. Che può essere interpretato come una word. Ma posso muovere 0 in B3:0 o fare reset Su B3/0, ottengo lo stesso risultato. Caso contrario per una word N7, posso sia muovere un valore decimale che azzerargli un bit. 

 

P.s., posso richiamare una memoria sia tramite l' indirizzo che il simbolo che si assegna, o nome, chiamatelo come volete

Modificato: da Folder
Link al commento
Condividi su altri siti

28 minuti fa, Folder ha scritto:

Caso contrario per una word N7, posso sia muovere un valore decimale che azzerargli un bit. 

Sì, ma rimane il fatto che se scrivi un valore in una word non imposti un solo bit, ma tutti i 16 bit. Se vuoi agire su un solo bit di una word scrivendo un valore nella word, devi giocare con AND e OR.

 

30 minuti fa, Folder ha scritto:

P.s., posso richiamare una memoria sia tramite l' indirizzo che il simbolo che si assegna, o nome, chiamatelo come volete

È quello che fanno più o meno tutti. Cambia un po' la sintassi, ma il concetto è sempre lo stesso.
Da tempo però c'è la tendenza (non solo in Siemens) di abbandonare gli indirizzi (salvo i casi in cui sia strettamente necessario conoscere l'indirizzo), e di lavorare esclusivamente in simbolico.
Lavorando in simbolico però, per rendere il programma più leggibile, si deve trovare il modo di far coincidere la variabile booleana myBit_0 con il bit 0 della word myWord.
In Siemens (ma più o meno è molto simile per tutti) si può accedere al bit con la sintassi myWord.%Xn (dove n è il numero del bit, partendo da destra).
Però, non si capisce subito quale sia la funzione del bit myWord.%Xn. Se a quel bit si riuscisse a dare un nome, la leggibilità ne guadagnerebbe non poco.

In Siemens questo si può fare con la "sovrapposizione con AT", oppure usando le istruzioni Scatter e Gather.
Con altri vendor immagino ci saranno dei metodi simili per ottenere lo stesso risultato.

 

Un altro motivo potrebbe essere per accedere ai singoli bit, sempre di variabili delle quali non si conosce l'indirizzo, in modo indicizzato. Quando si scrive myWord:%Xn, purtroppo, almeno in Siemens, n non può essere una variabile. Se, alla variabiel myWord sovrappongo un array di bool, ecco che posso accedere agli elementi dell'array (e quindi ai singoli bit) con un indice. Certo, potrei anche fare una semplice funzione che faccia la stessa cosa, ma così è sicuramente più facile ed immediato. Considerando poi che (parlo sempre di Siemens, ma credo anche per gli altri sia così) anche ai singoli elementi dell'array posso attribuire un diverso commento, torniamo ancora ad avere vantaggi in leggibilità.
 

Link al commento
Condividi su altri siti

Il non poter usare enumerativi o simbolici per accedere ai bit delle word è una limitazione anche del IEC 61131-3!
Poi in molti sistemi si possono mappare i singoli bit come BOOL, ma poi si pregiudica l'accesso come WORD.
Non si può nemmeno usare una variabile come indice dopo il "." cosa che sarebbe molto comoda e renderebbe il tutto più leggibile! Soprattutto quando si scrivono procedure di pacchettizzazione o spacchettizzazione di valori booleani sparsi!
Per esempio questa cosa illeggibile (Impacchetta 512 bit per una comunicazione UDP verso un HMI custom su PC):

maskOn := ULINT#16#1;
maskOff := ULINT#16#FFFFFFFFFFFFFFFE;

FOR col := 0 TO 63 DO
    FOR row := 0 TO 7 DO
        IF m_bitsPLC[col + (row * 64)] THEN
            processHMI.mainArea().plcBits.lwords[row] := processHMI.mainArea().plcBits.lwords[row] OR maskOn;
        ELSE
            processHMI.mainArea().plcBits.lwords[row] := processHMI.mainArea().plcBits.lwords[row] AND maskOff;            
        END_IF
    END_FOR
    maskOn := SHL(maskOn, 1);
    maskOff := SHL(maskOff, 1) OR ULINT#16#1;
END_FOR

Si semplificherebbe mostruosamente e diventerebbe molto più leggibile:
 

FOR col := 0 TO 63 DO
    FOR row := 0 TO 7 DO
        processHMI.mainArea().plcBits.lwords[row].col := m_bitsPLC[col + (row * 64)];
    END_FOR
END_FOR

Purtroppo il ".col" non è ammesso ed il tutto diventa poco leggibile ai più!
(L'esempio è IEC61131-3 puro ed usa LWORDS, probabilmente in SCL cambia un pelo)

Modificato: da Marco Mondin
Link al commento
Condividi su altri siti

7 hours ago, batta said:

Considerando poi che (parlo sempre di Siemens, ma credo anche per gli altri sia così) anche ai singoli elementi dell'array posso attribuire un diverso commento, torniamo ancora ad avere vantaggi in leggibilità.

Sono d'accordo che lavorare con i simboli semplifica molto le cose, anzi mi trovo bene con come il Siemens ti porta ad impostare il programma (o come la Siemens stessa consiglia nelle guide utenti). Penso sempre come se qualcun' altro dovesse leggere il mio programma, abbreviazioni esagerate sono perdite di tempo per capire cosa c'è scritto

 

Una cosa che mi piace di AB è il poter richiamare determinate memorie nel programma tramite l'indirizzo in tempo lampo. Mi spiego, la sintassi è molto user-friendly, della serie:

 

Creo un nuovo rung e scrivo;

"XIC I0/0 XIO I0/1 XIC B3/0 MOV 32265 N7:0" e premo invio.

"Se ho il primo input, non ho il secondo input, ho un booleano, muovo 32265 in N7:0

 

In siemens invece bisogna prima impostarsi le istruzioni (anche tramite i tasti rapidi) e successivamente inserire i simboli uno ad uno ricavati da una DB, un merker, o ciò che sia. Mi sà più di pragmatico.

 

Inoltre il vantaggio (oltre agli svantaggi) dell' indirizzo che se utilizzi per dire 50 bit nella struttura di base dei programmi e su ogni programma hanno sempre lo stesso indirizzo non ti devi far venire il mal di pancia per ricercare quel determinato bit (sono quelli, e dopo un po' che ci lavori, li impari a memoria).

 

 

Modificato: da Folder
Link al commento
Condividi su altri siti

1 ora fa, Folder ha scritto:

"XIC I0/0 XIO I0/1 XIC B3/0 MOV 32265 N7:0" e premo invio.

Certo che scrivere con gli indirizzi rende il programma incomprensibile. Personalmente apprezzo, del TIA, che se usi una qualsiasi variabile (ingresso, uscita, merker) che non ha già un nome, viene assegnato un nome di default (tag_1, tag_2, ecc). Solo al pensiero di lavorare con gli indirizzi al posto dei nomi, mi si risveglia la colite.

 

1 ora fa, Folder ha scritto:

In siemens invece bisogna prima impostarsi le istruzioni (anche tramite i tasti rapidi) e successivamente inserire i simboli uno ad uno ricavati da una DB, un merker, o ciò che sia. Mi sà più di pragmatico.

Intendi nella programmazione in ladder? Certo, prima devi inserire le istruzioni (contatto, bobina, box, ecc.), e poi associare le variabili. Tieni presente che puoi anche scrivere il nome che desideri della variabile, anche prima di averla dichiarata (viene sottolineata in rosso). Poi, prima di compilare, tasto destro sulle variabili sottolineate in rosso, e definisci la variabile. Se la variabile esiste già, l'autocompletamento ti aiuta molto. Personalmente preferisco prima dichiarare le variabili e dopo usarle, ma è una questione di abitudine.

 

1 ora fa, Folder ha scritto:

e su ogni programma hanno sempre lo stesso indirizzo non ti devi far venire il mal di pancia per ricercare quel determinato bit (sono quelli, e dopo un po' che ci lavori, li impari a memoria).

Questo se fai sempre la stessa macchina. In ogni caso, pensa che bello, invece, usare sempre gli stessi nomi, anche se sono stati modificati i cablaggi. E questo riferito agli I/O. Per quanto riguarda le memorie interne, l'ideale è usare le FB, così ogni blocco (in linea di massima) ha già le sue variabili in pancia.

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