Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Sequenza Di Numeri Assegnati A Bit


Messaggi consigliati

Inserito:

Ciao! Per visualizzare dei messaggi su un pannello occorre introdurre un numero in una word di dati. Es. nella word settata per i messaggi introduco il 3 e mi apparirà il 3° messaggio. Quello che avevo in mente (e che ho anche visto) era assegnare in qualche modo la sequenza di numeri ad una sequenza di bit, es. M120.0, M120.1 ecc. in modo che alzando il bit M120.1 mi appaia il messaggio 1, alzando l'M120.2 mi appaia il massaggio 2 e così via per tutti i messaggi. In questo modo mi sembra più semplice gestire questi messaggi, nel senso che potrei così assegnare nel commento al simbolo direttamente il testo del messaggio ed anche per il debug sarebbe più chiaro.

Come dicevo ho visto una funzione che faceva appunto questo ma non ho capito bene come facesse e con che tecnica. Purtroppo non me la sono copiata e mi piacerebbe avere il vostro aiuto per provare a capire come si potrebbe fare...

Grazie...


Inserita:

Forse non ho capito bene cosa intendi , ma occhio che su molti pannelli il messaggio 1 è associato al bit 0 e non all'1 ovvero M120.0 messaggio 1 120.1 messaggio 2...

Inserita:

Cerco di spiegare meglio. In questo pannello, per i messaggi, devi impostare una db con delle Word. Quando tu vuoi visualizzare il messaggio 3 inserisci in questa word il valore 3. Ora programmando il messaggio che ti serve credo che si possa fare un MOVE in quella DB e tutto funziona. Quello che mi pareva facesse quella funzione era in pratica assegnare ad ogni bit di una Merker Word un valore in numero per cui se alzo appunto l'M120.0 appare il messaggio 1, se alzo l'M120.1 ho il messaggio 2 e così via. In questo modo l'M120.0 avrà come simbolico che so "Emergenza premuta" e sarà facilmente riconoscibile scorrendo il programma ma sopratutto sarà facile cercarlo in caso di problemi... credo.

Comunque ho recuperato il codice della funzione... senza commenti. Se mi date una mano ad interpretarla se si può. (Il codice nel .TXT allegato)

Messaggi.txt

Inserita: (modificato)

25 anni fa avevo fatto un FB su S5 che gestiva un display pilotato da 8 uscite del plc, la complicazione è che se hai più di un bit a 1 dovrebbe mostrarti tutti i corrispondenti messaggi ad intervalli regolari di tempo.

L'FB che avevo fatto funzionava così:

Ciclicamente esaminava lo stato di 6 word per un totale di 96 messaggi, ad ogni ciclo esaminava la word successiva, se la word era diversa da 0 iniziava ad esaminare i bit, appena ne trovava uno alto trasferiva in uscita il valore corrispondente al messaggio e faceva partire un timer che bloccava temporaneamente l'elaborazione dell'FB, allo scadere del timer la scansione continuava con i bit successivi, finiti i bit passava alla word successiva e così via...

Ho dato una occhiata all'allegato ma mi sembra una cosa buttata li alla bell'e meglio...

Modificato: da JumpMan
Inserita:

ciao

... dovrebbe mostrarti tutti i corrispondenti messaggi ad intervalli regolari di tempo.

oppure dopo la pressione di un pulsante mostri il messaggio successivo, che secondo me è più comodo e dà all' operatore il tempo che gli serve per recepire il messaggio

quello che conta è la logica su come farlo e su come gestire gli errori , poi il tipo di plc viene in seguito.

comunque se vuoi alzare un bit (o più bit contemporaneamente) e trasformarli in numeri non è complicato , poi ognuno sceglie il metodo che più gli aggrada.

Inserita:
oppure dopo la pressione di un pulsante mostri il messaggio successivo, che secondo me è più comodo

Vero, è più comodo ma potrebbe leggere solo il primo e non accorgersi degli altri...

Inserita:

ciao

Vero, è più comodo ma potrebbe leggere solo il primo e non accorgersi degli altri...

si lo sò , ma è risolvibile in diversi modi... infatti mi è successo :wacko: e in base al dispositivo di visualizzazione agivo im maniera diversa per avvisare l'operatore della presenza di altri allarmi , in modo da sopperire al problema.

Inserita:

Mai usato lo sviluppo degli allarmi con il numero in una word, ma sempre nel singolo bit; e, onestamente, non ne capisco la necessità ...

Di quale pannello stiamo parlando ?

Inserita: (modificato)

Sono anni che non vedo più visualizzatori di questo tipo...

Che poi, a dirla tutta, la modalità di visualizzazione degli allarmi (ON, OFF, ACK, RST) sarebbero regolamentati da una norma, ma ciò è ovviamente impossibile con questo tipo di visualizzatore.

Si potrebbe aggiungere un pulsante luminoso rosso che lampeggia quando subentrano uno o più nuovi allarmi, premendo il pulsante si acquisisce la lettura e si visualizza il successivo, quando sono visualizzati tutti il pulsante rimane acceso fisso, se gli allarmi rientrano il pulsante si spegne. Questo tipo di funzionamento rispetterebbe la norma ma è abbastanza complicato da fare...

Se il visualizzatore è vecchio è forse più conveniente sostituirlo con un nuovo piccolo HMI con già la gestione allarmi integrata, così se si rompe si trova il ricambio (e non serve star li a costruire un FB da 1000 istruzioni)

Modificato: da JumpMan
Inserita:

'ciao

Sono anni che non vedo più visualizzatori di questo tipo...

sono pannelli in uso oltre 20 anni fà . Ma ce ne sono alcuni odierni low cost , anche di marche famose (spero a fine produzione),che usano ancora lo stesso metodo. Un allarme è una pagina dell hmi e per far uscire la pagina devi inserire il suo numero in un registro , quindi allarme =numero.

Inserita: (modificato)

Grazie di tutte le risposte. Il pannello è un UniOP vecchio. Comunque qui non stiamo parlando degli allarmi... che infatti sono gestiti come si dovrebbe. Qui stiamo parlando dei soli messaggi che si utilizzano per informare l'operatore. Ho sbagliato io a fare l'esempio di "Emergenza Premuta" avrei dovuto dire "Avviare Ciclo"... Comunque anche se non comprendo a fondo la funzione che ho riportato nel .TXT (sono alle prime armi) fa esattamente quello che riportava JumpMan ossia visualizza il messaggio corrispondente con un BIT e nel caso di più messaggi li alterna per consentire all'operatore di vederli tutti... Se capisco bene imposta una sola WORD per i messaggi quindi li limita a 16... giusto? La DB22.DBW2 la usa come per la funzione in se...

Modificato: da IlFincoITA
Inserita:

Ma allora non serve fare tutto quell'incasinamento là, e non servono neanche i bit. Praticamente vuoi fare quello che io definisco segnalazioni di manovre errate, solo che ora devo uscire e non psso metterti l'esempio. Ciao, buona domenica.

Inserita: (modificato)

Allora, se ho ben capito quello che vuoi fare assomiglia a quello che io chiamo "ManovreErrate", ma potrebbe benissimo essere "StatoMacchina"...

Non so se preferisci lavorare in KOP o in AWL, lo puoi fare in entrambi i modi, oppure anche misto (1 segmento kop e uno awl alternati).

- Fai un nuovo FC e mettici un parametro Out / int di nome NrMessaggio mettici anche un parametro iout/bool di nome ManErr (se vuoi)

- Sul primo segmento azzeri il ManErr:

   SET
   R ManErr

- Sui segmenti successivi puoi mettere direttamente le logiche per i messaggi:

012: POMPA SPENTA
  PulSta           PomAvv             ____  
----| |-------------|/|--------------|MOVE|----------(ManErr)----(RET)
                                  12 |____|NrMessaggio

Nel mio esempio qui sopra visualizzo il messaggio 12 se premo il pulsante di start ed ho la pompa non avviata

- Metti tanti segmenti quanti sono i messaggi da visualizzare, la priorità è data ai messaggi programmati per primi.

- In OB1 assegni al parametro NrMessaggio la word dell' HMI

- Il parametro bool ManErr lo puoi usare per accendere una spia rossa lampeggiante che segnala all'operatore la manovra errata (e il messaggio da leggere)

Poi chiaramente lo puoi perfezionare, p.es. mettere un tempo minimo di visualizzazione del messaggio ecc. ecc.

L'esempio te l'ho fatto in KOP, io di solito facevo la logica booleana in KOP (solo attivazione bit ManErr) e mettevo 3 istruzioni AWL nel segmento successivo per fare quello che fanno il MOVE e il RET, alla fine era un poco più ottimizzato a livello di quantità istruzioni (circa la metà) ma tutto in kop è più leggibile...

Modificato: da JumpMan
Inserita:

OK grazie ancora... è molto chiaro.

Inserita: (modificato)

Un esempio fatto in SCL

Questo è un Esempio per creare la DB dei tuoi messaggi operatore

DATA_BLOCK DB6

// Blocco Struttura Dati per FC6 EFB6 Messaggi

//

//

STRUCT // Struttura Dati per i Messaggi

Messages: ARRAY [0..7] OF WORD; // Array dei Messaggi

Message_Val: INT; // Numero del Messaggio da Visualizzare

Message_Delay: S5TIME; // Ritardo Tempo di Visualizzazione Messaggio

Message_Here: BOOL; // Presenza Messaggi

END_STRUCT

BEGIN

END_DATA_BLOCK

Questa è la gestione dei messaggi

FUNCTION_BLOCK FB16

TITLE = 'Messages Scan'

//

// Gestione Messaggi

//

VERSION : '1.0'

AUTHOR : Kumt

NAME : Ctrl_Msg

FAMILY : SCL

VAR_INPUT

DB_Msg: BLOCK_DB; // Blocco Dati dei Messaggi

N_Messages: INT; // Numero di Word Messaggi da Scansionare

Time_Scan: TIMER; // Timer da Usare per Tempo di Visione Messaggio

Scan_Preset: S5TIME; // Tempo di Visione del Messaggio

Msg_Clr: BOOL; // Azzeramento Messaggi

END_VAR

VAR_IN_OUT

Message_Here: BOOL; // Messaggio Presente

END_VAR

VAR_OUTPUT

Msg_Value: INT; // Uscita Valore da Visualizzare

END_VAR

VAR

Messages: ARRAY[0..7]OF WORD; // Array Messaggi da Scansionare

Msg_Chk_W: WORD; // Numero Word in Controllo

Scan_Bit: INT;

Scan_Word: INT;

Word_Msg: WORD;

View_OK: BOOL;

View: INT;

TIMER1: S5TIME;

BiVal: WORD; // Valore Resto Temporizzatori

T_Out: BOOL;

END_VAR

VAR_TEMP // Variabili non Ritentive

END_VAR

BEGIN

Messages[0]:= ROL(IN:=DB_Msg.dw0,N:=8); // Attribuisco ad ogni elemento Array la Corrispondente Word dei Messaggi

Messages[1]:= ROL(IN:=DB_Msg.dw2,N:=8); // I Bits vengono Rovesciati, per Riporli in Ordine.

Messages[2]:= ROL(IN:=DB_Msg.dw4,N:=8);

Messages[3]:= ROL(IN:=DB_Msg.dw6,N:=8);

Messages[4]:= ROL(IN:=DB_Msg.dw8,N:=8);

Messages[5]:= ROL(IN:=DB_Msg.dw10,N:=8);

Messages[6]:= ROL(IN:=DB_Msg.dw12,N:=8);

Messages[7]:= ROL(IN:=DB_Msg.dw14,N:=8);

View:= Msg_Value;

IF Msg_Clr THEN // Reset di Tutti i Messaggi

Scan_Bit :=0; Scan_Word:=0;

FOR Scan_Word :=0 TO 7 DO

Messages[scan_Word]:=0;

END_FOR;

END_IF;

IF Messages[0]<>0 OR Messages[1]<>0 OR // Verifica Presenza Messaggio

Messages[2]<>0 OR Messages[3]<>0 OR

Messages[4]<>0 OR Messages[5]<>0 OR

Messages[6]<>0 OR Messages[7]<>0 THEN Message_Here:= True;

ELSE

Message_Here:= False;

Scan_Word:=0;

Scan_Bit :=0;

Word_Msg :=1;

END_IF;

IF (Message_Here = True) AND (NOT T_Out) THEN

Scan_Bit := Scan_Bit + 1;

IF Scan_Bit >16 THEN Scan_Bit :=0;

Word_Msg :=0;

Scan_Word := Scan_Word+1;

END_IF;

IF Scan_Word > N_Messages THEN Scan_Word:=0;

Scan_Bit :=0;

Word_Msg :=0;

END_IF;

Word_Msg := SHL(IN:=Word#2#0000_0000_0000_0001,N:=Scan_Bit);

Msg_Chk_W := Word_Msg AND Messages[scan_Word];

IF Msg_Chk_W <>0 THEN

Msg_Value := (Scan_Word*16)+Scan_Bit+1;

END_IF;

END_IF;

IF Message_Here = False THEN

Msg_Value:=0; // Valore del Messaggio = Zero se non vi sono messaggi

END_IF;

IF View <> Msg_Value THEN View_OK:= True;

ELSE View_OK:= False;

END_IF;

TIMER1 := S_PEXT(T_NO:=Time_Scan,S:=View_OK, TV:=Scan_Preset,R:=False,BI:=biVal,Q:=T_Out); // Impulso di Reset

END_FUNCTION_BLOCK

Modificato: da AlexKumt

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