Vai al contenuto
PLC Forum


Cross Reference Alternativo... E Blocchi Scl


biuly

Messaggi consigliati

Comunque questa soluzione non è male e la posso utilizzare nel codice libero, ma nella parte strutturata in UDT la cosa si fa più complessa.
Perche' mai.. dove sarebbe questa complessita'..? facciamo questo esempio per solo 3 interi (timers).

UDT1: // DataTimers
Address Name         Type         Initial Value
-------------------------------------------------------
 0.0                  STRUCT
+0.0     Timers      STRUCT            
+0.0      N_Timer1   INT          1        
+2.0      N_Timer2   INT          2        
+4.0      N_Timer3   INT          3        
=6.0                 END_STRUCT            
=6.0                 END_STRUCT
DB10  : // DB_Timers
Address Name             Type            
-------------------------------------------------------
 0.0                      STRUCT
+0.0    DB_Timers_Block  "DataTimers"            
=6.0                     END_STRUCT

Richiamo FC45 passandoli a N_TIMER -> "DB_Timers".DB_Timers_Block.Timers.N_Timer1 // DB10.DBW0

Richiamo FC45 passandoli a N_TIMER -> "DB_Timers".DB_Timers_Block.Timers.N_Timer2 // DB10.DBW2

Richiamo FC45 passandoli a N_TIMER -> "DB_Timers".DB_Timers_Block.Timers.N_Timer3 // DB10.DBW6

Nella cross reference, ti verranno elencate le DW per il DB10... poi stampi l'UDT1 ove vedrai discriminati i valori per l'INTs ..!

Modificato: da Savino
Link al commento
Condividi su altri siti


La complessità sta nel fatto che io ho degli FB ai quali passo un variabile di tipo strutturato UDT all'interno della quale ci sono gli indirizzi dei timer.

Esempio:

Un mio FC2 per il controllo del superamento di soglie d'allarme viene richiamato così:

La variabile "DB_Soglie_Analogiche".WIT5311 è una variabile strutturata con dei campi

..

..

N_Timer_1 INT

N_Timer_2 INT

N_Timer_3 INT

..

..

All'interno dell'FC2 per il controllo delle soglie, uso i miei FC45 per temporizzare il superamento di soglia

ed uso quindi come numero dei timer #Analog.N_Timer_1 ...2 ....3

Quindi io carico il numero del timer all'interno di un campo del "DB_Soglie_Analogiche".WIT5311 e io non posso in fase di inizializzazione del DB mettere il valore di un campo di un'altro DB.

Quello che dici tu funziona se io richiamo l'FC45 passandogli direttamente "DB_Timers".DB_Timers_Block.Timers.N_Timer3 come parametro, ma se questo parametro deve essere ricavato da "DB_Soglie_Analogiche".N_Timer come faccio ?

Io a "DB_Soglie_Analogiche".WIT5311.N_Timer non posso assegnare "DB_Timers".DB_Timers_Block.Timers.N_Timer3 a meno di non farlo tramite

L "DB_Timers".DB_Timers_Block.Timers.N_Timer1

t "DB_Soglie_Analogiche".WIT5311.N_Timer1

.....

L "DB_Timers".DB_Timers_Block.Timers.N_Timer3

t "DB_Soglie_Analogiche".WIT5311.N_Timer3

Call FC45

Analog := "DB_Soglie_Analogiche".WIT5311

Valore := .....

......

......

Volevo postarti più immagini ma non riesco a limitare la dimensione a 30K

Modificato: da biuly
Link al commento
Condividi su altri siti

Ti posto il sorgente generato della FC2 e dell'UDT6

TYPE "UDT_Allarmi4Livelli"

VERSION : 0.1

STRUCT

Limit_HighHigh : INT ; //IN: Valore di allarme Molto Alto

Limit_High : INT ; //IN: Valore di avvertimento Alto

Limit_Low : INT ; //IN: Valore di avvertimento Basso

Limit_LowLow : INT ; //IN: Valore di allarme MoltoBasso

OverHighHigh : BOOL ; //OUT: Molto Alto

OverHigh : BOOL ; //OUT: Alto

UnderLow : BOOL ; //OUT: Basso

UnderLowLow : BOOL ; //OUT: Molto Basso

T_Set_HighHigh : INT := 2; //IN: Timer ritardo per allarme molto alto

T_Set_High : INT := 2; //IN: Timer ritardo per allarme alto

T_Set_Low : INT := 2; //IN: Timer ritardo per allarme basso

T_Set_LowLow : INT := 2; //IN: Timer ritardo per allarme molto basso

TimerNumberHighHigh : INT := 1; //IN: Numero del timer

TimerNumberHigh : INT := 1; //IN: Numero del timer

TimerNumberLow : INT := 1; //IN: Numero del timer

TimerNumberLowLow : INT := 1; //IN: Numero del timer

END_STRUCT ;

END_TYPE

FUNCTION "FC_CheckAllarmi4Soglie" : VOID

TITLE =

//Controlla che il valore dell'analogica sia all'interno dei limiti altrimenti

//attiva i bits di segnalazione

VERSION : 0.1

VAR_INPUT

Analog : "UDT_Allarmi4Livelli";

Valore : INT ;

END_VAR

VAR_OUTPUT

TimerSoglia_HighHigh : INT ;

TimerSoglia_High : INT ;

TimerSoglia_Low : INT ;

TimerSoglia_LowLow : INT ;

END_VAR

VAR_TEMP

Value : REAL ;

END_VAR

BEGIN

NETWORK

TITLE =

U( ;

L #Valore;

L #Analog.Limit_HighHigh;

>=I ;

) ;

SPBNB _001;

CALL "FC_TimerOnDelay" (

N_TIMER := #Analog.TimerNumberHighHigh,

PRESET := #Analog.T_Set_HighHigh,

BASE := 2,

ACTUAL := #TimerSoglia_HighHigh);

_001: U BIE;

= #Analog.OverHighHigh;

NETWORK

TITLE =

U( ;

L #Valore;

L #Analog.Limit_High;

>=I ;

) ;

SPBNB _002;

CALL "FC_TimerOnDelay" (

N_TIMER := #Analog.TimerNumberHigh,

PRESET := #Analog.T_Set_High,

BASE := 2,

ACTUAL := #TimerSoglia_High);

_002: U BIE;

= #Analog.OverHigh;

NETWORK

TITLE =

U( ;

L #Valore;

L #Analog.Limit_Low;

<=I ;

) ;

SPBNB _003;

CALL "FC_TimerOnDelay" (

N_TIMER := #Analog.TimerNumberLow,

PRESET := #Analog.T_Set_Low,

BASE := 2,

ACTUAL := #TimerSoglia_Low);

_003: U BIE;

= #Analog.UnderLow;

NETWORK

TITLE =

U( ;

L #Valore;

L #Analog.Limit_LowLow;

<=I ;

) ;

SPBNB _004;

CALL "FC_TimerOnDelay" (

N_TIMER := #Analog.TimerNumberLowLow,

PRESET := #Analog.T_Set_LowLow,

BASE := 2,

ACTUAL := #TimerSoglia_LowLow);

_004: U BIE;

= #Analog.UnderLowLow;

END_FUNCTION

L' "FC_TimerOnDelay" è la mia FC45 dei timer.

Modificato: da biuly
Link al commento
Condividi su altri siti

Dunque, tu hai definito un UDT individuato in codice SCL sorgente, non assegnato ad una DB... questo UDT viene dopo utilizzato dal FC2 ("FC_CheckAllarmi4Soglie") come parametri d'input... e per ogni richiamo del FC45 ("FC_TimerOnDelay") , i valori contenuti dai suoi data membri, vengono assegnati... e cosi via...

Quello che dici tu funziona se io richiamo l'FC45 passandogli direttamente "DB_Timers".DB_Timers_Block.Timers.N_Timer3 come parametro, ma se questo parametro deve essere ricavato da "DB_Soglie_Analogiche".N_Timer come faccio ?

Io a "DB_Soglie_Analogiche".WIT5311.N_Timer non posso assegnare "DB_Timers".DB_Timers_Block.Timers.N_Timer3 a meno di non farlo tramite

L "DB_Timers".DB_Timers_Block.Timers.N_Timer1

t "DB_Soglie_Analogiche".WIT5311.N_Timer1

.....

L "DB_Timers".DB_Timers_Block.Timers.N_Timer3

t "DB_Soglie_Analogiche".WIT5311.N_Timer3

Oppure ti crei un'altro UDT assegnato ad una DB.. :

DB10  : // DB_Soglie_Analogiche
Address Name             Type            
-------------------------------------------------------
0.0                      STRUCT
+0.0    WIT5311         "DataTimers"            
=6.0                     END_STRUCT
UDT1: // DataTimers
Address Name         Type         Initial Value
-------------------------------------------------------
0.0                  STRUCT
+0.0     Timers      STRUCT            
+0.0      N_Timer1   INT          1        
+2.0      N_Timer2   INT          2        
+4.0      N_Timer3   INT          3        
=6.0                 END_STRUCT            
=6.0                 END_STRUCT
Richiami 'FC2' passandoli a N_TIMER -> "DB_Soglie_Analogiche".WIT5311.N_Timer1 // DB10.DBW0
..
.

In sostanza, utilizzi un secondo UDT assegnato ad una DB per passarli la data in input all'UDT individuato in codice SCL sorgente. Dopotutto, quello che a te interressa e' individuare gli INTs in input, che saranno quelli fondati sulla DB10 "DB_Soglie_Analogiche".

Link al commento
Condividi su altri siti

Si, passandoli come parametri li individuo, ma volevo individuare gli int passati come campo della variabile UDT in ingresso al mio FC2 che tra i vari campi comprendeva anche dei campi N_Timer, e questo a quanto pare non si può fare. Quindi dovrei pulire tutti i miei UDT contenenti campi N_Timer e passarli alle FC come parametri di ingresso separati, ovviamente facendo come hai detto tu, che è una bella idea. Cioè al posto di passare un intero passo il valore del DB creato con L'udt dei TIMER.

Grazie della dritta e del tempo dedicato.

P.S: se ti viene in mente qualcos'altro sono qui.

Modificato: da biuly
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...