Vai al contenuto
PLC Forum


Step7 Lite Cpu 314 Azzeramento Db


Claudio Jallin

Messaggi consigliati

Buongiorno a Tutti e complimenti per il sito, interessantissimo,

Come autodidatta sto utilizzando Step7 Lite con una cpu 314, avevo lavorato in precedenza con S5 ma è passato un pò di tempo, voglio far ripartire i pochi neuroni che mi rimangono :)

Per questo vorrei avere conferma di quello che ho scritto in AWL, si tratta di memorizzare ciclicamente il valore di un ingresso analogico 1-5V in una DB, ovvamente ogni lettura occuperà il byte successivo.

Fermo restando che funzioni così come è, alla fine della serie di cicli vorrei estrapolare la DB per stampare i dati, dopo di che azzerare la DB stessa per poterla utilizzare nella serie successiva.

Spero che qualcuno abbia voglia di istruirmi in merito, Grazie.

Questo è il mio passo di programma:

LAR1 P#DBX 0.0
L "TensBatt1"
T DBW [AR1,P#0.0]
L DBW [AR1,P#0.0]
L 1
>I
S "Read1_OK"
A "Read1_OK"
+AR1 P#2.0

Scusate non si tratta di Byte ma di Word

Link al commento
Condividi su altri siti


ciao e benvenuto nel Forum

iniziamo dalla fine:

l'istruzione +AR1 P#2.0 non è RLC dipendente quindi non basta una istruzione AND a monte ma devi metterci anche un salto

S "Read1_OK" va TRUE quando la tensione sale sopra 1V ma una volta TRUE vi rimane, ti conviene modificare le istruzioni, non ho capito il tuo intento ma se vuoi memorizzare tensioni > 1V gestisci il tutto con un salto SPBN

p.es.

L DBW [AR1,P#0.0]
L 1
>I
SPBN x1
+AR1 P#2.0
x1: NOP 0
Inoltre:
- Quando la tensione è >1 il prog cicla molto velocemente e in un attimo ti riempirà la DB, e non penso che è quello che vuoi
- Quando arriverà a fine DB il PLC andrà in STOP, devi gestire questo ponendo dei limiti all'indice e casomai riciclando dall'inizio con sovrascrittura del dato più vecchio
- I dati integer espressi in volt con valori da 1 a 5 hanno una risoluzione troppo bassa, non so cosa vuoi fare ma potresti memorizzare i mV piuttosto che i V
scusa se ho scritto male ma sono di fretta, ciao
Modificato: da JumpMan
Link al commento
Condividi su altri siti

Ciao e grazie del benvenuto,

se devo essere sincero speravo di avere risposta da Te, se posso permettermi il "Tu".

Come ho cercato di spiegare prima il valore lo voglio memorizzare solo una volta, infatti questo passo è vincolato ad un fronte di salita per una sola scansione, ed è per questo che utilizzo il Set, in un altro passo sarà resettato per darmi la possibilità di memorizzare di nuovo una nuova Word della DB in questione.

In altre parole, ho un lasso temporale di circa 3 sec in cui prelevo un solo valore, dopo altri 10 sec mi ritrovo nuovamente 3 sec per memorizzare un nuovo valore dall'ingesso analogico. Questo si ripete fino all'intervento di un errore che corrisponde alla condizione di "TensBatt1" < 1.

Link al commento
Condividi su altri siti

se devo essere sincero speravo di avere risposta da Te, se posso permettermi il "Tu".

in questo forum ci si da tutti del tu, come se fossimo tra colleghi.

Come ho cercato di spiegare prima il valore lo voglio memorizzare solo una volta, infatti questo passo è vincolato ad un fronte di salita per una sola scansione, ed è per questo che utilizzo il Set, in un altro passo sarà resettato per darmi la possibilità di memorizzare di nuovo una nuova Word della DB in questione.

Nelle istruzioni che hai messo non c'è nessun vincolo ad un fronte, vengono elaborate tutte ogni n millisecondi

In altre parole, ho un lasso temporale di circa 3 sec in cui prelevo un solo valore, dopo altri 10 sec mi ritrovo nuovamente 3 sec per memorizzare un nuovo valore dall'ingesso analogico. Questo si ripete fino all'intervento di un errore che corrisponde alla condizione di "TensBatt1" < 1.

Cosa vuol dire 3s per memorizzare? se p.es. la cpu ha un t.ciclo di 0.01s in un lasso di tempo di 3s la cpu legge 300 valori, quale di questi vuoi memorizzare? il primo, l'ultimo, tutti o una media dei 300 valori?

Potrebbe andare bene un clock con un t-off di 10s e un t-on di 3 secondi ed usi il fronte di discesa del t-on per memorizzare il valore ?

...non mi è ancora ben chiaro cosa vuoi fare...

Link al commento
Condividi su altri siti

Grazie di nuovo, per il "Tu" lo avevo notato, ma la gentilezza non guasta mai.

Nelle istruzioni che hai messo non c'è nessun vincolo ad un fronte, vengono elaborate tutte ogni n millisecondi

è vero ho postato solo la parte riferita al caricamento della DB, in realtà questo passo è frutto di una condizione particolare e viene letto solo una scansione.

Cosa vuol dire 3s per memorizzare? se p.es. la cpu ha un t.ciclo di 0.01s in un lasso di tempo di 3s la cpu legge 300 valori, quale di questi vuoi memorizzare? il primo, l'ultimo, tutti o una media dei 300 valori?

I tempi che ho descritto sono i potenziali tempi di ciclo meccanico, si tratta di una prova reale di attivazione a impulsi di 3 sec di una batteria al litio con un carico resistivo variabile.

Il mio obbiettivo è verificare quante attivazioni riesce a fare fino a quando è scarica e di conseguenza il tempo di scarica, inoltre con i valori di tensione letti definisco la curva della scarica stessa.

Spero di essere stato più chiaro :smile: ,

grazie JumpMan.

Link al commento
Condividi su altri siti

Oggi avevo un po' di tempo libero e ho provato a buttare giù qualche riga di codice, ho fatto una FB che fa tutto quello che chiedi, se vuoi provarla, poi casomai ti spiego come funziona...

Apri un nuovo progetto vuoto

Copia/incolla questo nella tabella simboli

Cycle Execution	OB      1	OB      1	
Dati	DB     10	DB     10	Dati loggati
FILL	SFC    21	SFC    21	Initialize a Memory Area
Log_End	M      10.2	BOOL	Bit fine log
Log_Memo	M       0.5	BOOL	Memorizza dato in log
Log_NrDatiMem	MW     14	INT	Nr di dati memorizzati
Log_Reset	M      10.0	BOOL	Azzeramento Log
Log_Val	MW     12	INT	Valore da memorizzare
LogFull	M      10.3	BOOL	Bit DB dati piena
Logger	FB      1	FB      1	Logger dati
Logger_DB	DB      1	FB      1	DB per FB1

Poi vai nella cartella sorgenti del progetto s7 e premi tasto dx> inserisci nuova sorgente AWL, aprila e incollaci dentro questo codice

DATA_BLOCK "Dati"
TITLE =
VERSION : 0.1


  STRUCT 	
   Volt : ARRAY  [0 .. 99 ] OF INT  := 0;	
  END_STRUCT ;	
BEGIN
   Volt[0] := 0; 
   Volt[1] := 0; 
   Volt[2] := 0; 
   Volt[3] := 0; 
   Volt[4] := 0; 
   Volt[5] := 0; 
   Volt[6] := 0; 
   Volt[7] := 0; 
   Volt[8] := 0; 
   Volt[9] := 0; 
   Volt[10] := 0; 
   Volt[11] := 0; 
   Volt[12] := 0; 
   Volt[13] := 0; 
   Volt[14] := 0; 
   Volt[15] := 0; 
   Volt[16] := 0; 
   Volt[17] := 0; 
   Volt[18] := 0; 
   Volt[19] := 0; 
   Volt[20] := 0; 
   Volt[21] := 0; 
   Volt[22] := 0; 
   Volt[23] := 0; 
   Volt[24] := 0; 
   Volt[25] := 0; 
   Volt[26] := 0; 
   Volt[27] := 0; 
   Volt[28] := 0; 
   Volt[29] := 0; 
   Volt[30] := 0; 
   Volt[31] := 0; 
   Volt[32] := 0; 
   Volt[33] := 0; 
   Volt[34] := 0; 
   Volt[35] := 0; 
   Volt[36] := 0; 
   Volt[37] := 0; 
   Volt[38] := 0; 
   Volt[39] := 0; 
   Volt[40] := 0; 
   Volt[41] := 0; 
   Volt[42] := 0; 
   Volt[43] := 0; 
   Volt[44] := 0; 
   Volt[45] := 0; 
   Volt[46] := 0; 
   Volt[47] := 0; 
   Volt[48] := 0; 
   Volt[49] := 0; 
   Volt[50] := 0; 
   Volt[51] := 0; 
   Volt[52] := 0; 
   Volt[53] := 0; 
   Volt[54] := 0; 
   Volt[55] := 0; 
   Volt[56] := 0; 
   Volt[57] := 0; 
   Volt[58] := 0; 
   Volt[59] := 0; 
   Volt[60] := 0; 
   Volt[61] := 0; 
   Volt[62] := 0; 
   Volt[63] := 0; 
   Volt[64] := 0; 
   Volt[65] := 0; 
   Volt[66] := 0; 
   Volt[67] := 0; 
   Volt[68] := 0; 
   Volt[69] := 0; 
   Volt[70] := 0; 
   Volt[71] := 0; 
   Volt[72] := 0; 
   Volt[73] := 0; 
   Volt[74] := 0; 
   Volt[75] := 0; 
   Volt[76] := 0; 
   Volt[77] := 0; 
   Volt[78] := 0; 
   Volt[79] := 0; 
   Volt[80] := 0; 
   Volt[81] := 0; 
   Volt[82] := 0; 
   Volt[83] := 0; 
   Volt[84] := 0; 
   Volt[85] := 0; 
   Volt[86] := 0; 
   Volt[87] := 0; 
   Volt[88] := 0; 
   Volt[89] := 0; 
   Volt[90] := 0; 
   Volt[91] := 0; 
   Volt[92] := 0; 
   Volt[93] := 0; 
   Volt[94] := 0; 
   Volt[95] := 0; 
   Volt[96] := 0; 
   Volt[97] := 0; 
   Volt[98] := 0; 
   Volt[99] := 0; 
END_DATA_BLOCK

FUNCTION_BLOCK "Logger"
TITLE =Logger dati
VERSION : 0.1


VAR_INPUT
  PtrArrayDati : ANY ;	//Puntatore array dati (p.es. P#DB1.DBX0.0 BYTE 100)
  Reset : BOOL ;	//Azzera dati (su fronte FP)
  Memo : BOOL ;	//Memorizza dato (su fronte FP)
  ValMin : INT ;	//Valore minimo ammesso
  Val : INT ;	//Valore da memorizzare
END_VAR
VAR_IN_OUT
  DatiMem : INT ;	//Quantità dati memorizzati
  End : BOOL ;	//Fine memorizzazione
  Full : BOOL ;	//DB dati piena
END_VAR
VAR
  FF : ARRAY  [0 .. 16 ] OF //Flags per fronti
  BOOL ;	
  MemoAR1 : DWORD ;	
END_VAR
VAR_TEMP
  TempAny : ANY ;	//Appoggio per PtrArrayDati in procedura reset
  DbNr : INT ;	//Appoggio per NrDb in procedura Memo
  DbArea : DWORD ;	//Appoggio per area dati DB in procedura Memo
  byTemp_1 : BYTE ;	//byte temp
  iTemp_1 : INT ;	//Int temp
END_VAR
BEGIN
NETWORK
TITLE =Reset dati

      U     #Reset; 
      FP    #FF[0]; 
      SPBN  _001; 


// Copia i 10 bytes del puntatore any in un dato locale temp
      L     DIW    0; 
      T     LW     0; 
      L     DID    2; 
      T     LD     2; 
      L     DID    6; 
      T     LD     6; 
// Ora il dato locale TempAny contiene lo stesso valore impostato nel parametro di ingresso PtrArrayDati

      L     L#0; 
      T     #byTemp_1; // Azzera byte temp
      T     #DatiMem; // azzera word nr. dati memorizzati
      L     DID    6; // (pointer contenuto nel parametro any)
      T     #MemoAR1; // inizializza memoria puntatore AR1

// Azzera area dati
      CALL "FILL" (
           BVAL                     := #byTemp_1,
           RET_VAL                  := #iTemp_1,
           BLK                      := #TempAny);


      SET   ; // Resetta bit vari 
      R     #End; 
      R     #Full; 

_001: NOP   0; 


NETWORK
TITLE =Memorizza valore

// Valuta condizioni per memorizzazione
      U     #Memo; // Bit esterno
      FP    #FF[1]; // (fronte)
      UN    #End; // memorizzazione non terminata 
      UN    #Full; // e DB non piena
      UN    #Reset; // e non bit di reset
      SPBN  _002; 

      L     #Val; // Controlla se valore ok
      L     #ValMin; 
      <=I   ; 
      S     #End; // In caso contrario setta bit End
      SPB   _002; //    e salta a _002

// Prepara dati per memorizzazione
      L     DIW    4; 
      T     #DbNr; 
      L     DID    6; 
      T     #DbArea; 

// Memorizzazione
      L     #MemoAR1; // Imposta puntatore con il valore precedente
      LAR1  ; 
      AUF   DB [#DbNr]; 
      L     #Val; 
      T     DBW [AR1,P#0.0]; 

// Incrementa puntatore
      +AR1  P#2.0; 
      TAR1  ; 
      T     #MemoAR1; 

// Incrementa indice nr dati memorizzati
      L     #DatiMem; 
      L     1; 
      +I    ; 
      T     #DatiMem; 

// Controlla se DB piena
      L     DIW    2; // fattore di ripetizione (byte) nel parametro ANY
      L     2; // :2
      /I    ; // = qtà word
      L     #DatiMem; 
      <=I   ; 
      S     #Full; 


_002: NOP   0; 

END_FUNCTION_BLOCK

DATA_BLOCK "Logger_DB"
TITLE =
VERSION : 0.0

"Logger"
BEGIN
   Reset := FALSE; 
   Memo := FALSE; 
   ValMin := 0; 
   Val := 0; 
   DatiMem := 0; 
   End := FALSE; 
   Full := FALSE; 
   FF[0] := FALSE; 
   FF[1] := FALSE; 
   FF[2] := FALSE; 
   FF[3] := FALSE; 
   FF[4] := FALSE; 
   FF[5] := FALSE; 
   FF[6] := FALSE; 
   FF[7] := FALSE; 
   FF[8] := FALSE; 
   FF[9] := FALSE; 
   FF[10] := FALSE; 
   FF[11] := FALSE; 
   FF[12] := FALSE; 
   FF[13] := FALSE; 
   FF[14] := FALSE; 
   FF[15] := FALSE; 
   FF[16] := FALSE; 
   MemoAR1 := DW#16#0; 
END_DATA_BLOCK

ORGANIZATION_BLOCK "Cycle Execution"
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1


VAR_TEMP
  OB1_EV_CLASS : BYTE ;	//Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ;	//1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ;	//Priority of OB Execution
  OB1_OB_NUMBR : BYTE ;	//1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ;	//Reserved for system
  OB1_RESERVED_2 : BYTE ;	//Reserved for system
  OB1_PREV_CYCLE : INT ;	//Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ;	//Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ;	//Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ;	//Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =Logger dati

      CALL "Logger" , "Logger_DB" (
           PtrArrayDati             := "Dati".Volt,
           Reset                    := "Log_Reset",
           Memo                     := "Log_Memo",
           ValMin                   := 1,
           Val                      := "Log_Val",
           DatiMem                  := "Log_NrDatiMem",
           End                      := "Log_End",
           Full                     := "LogFull");


END_ORGANIZATION_BLOCK

Ora premi CTRL+T (oppure menu file>genera sorgente)

Ti ritroverai i blocchi OB1,FB1,DB1,DB10,SFC21

l'FB1 funzona così:

Ad ogni fronte dell'ingresso Memo

- Se Val>ValMin memorizza il valore Val nell'array Volt della DB "Dati"

- DatiMem viene incrementato di 1 (nr dati memorizzati)

- Se Val <= ValMin viene settato il bit End e non memorizza più valori

- Se l'array di dati è pieno viene settato il bit End e non memorizza più valori

Un fronte nell'ingresso Reset azzera tutto l'array di dati ed i vari puntatori e bit

L'ho già simulato e funziona...

Nota: All'interno ho usato delle letture di parametri in modo assoluto( L DIW , T LW) questo non è il massimo e di solito non si fa, l'ho fatto solo per non complicare ulteriormente il codice scomodando il puntatore AR1 per 4 istruzioni in croce, l'importante è mantenere i puntatori all'inizio senza modificarne l'indirizzo...

Link al commento
Condividi su altri siti

Sono a dir poco sbigottito, mille grazie JumpMan, adesso però tocca a me avere un pò di tempo.

Non so se sono io impedito o è a causa del fatto che utilizzo Step7 Lite ma non riesco a fare il copia-incolla della tabella dei simboli.... :huh:

Appena riesco a testare il tutto ti faccio assolutamente sapere.

Di nuovo molte grazie...

Link al commento
Condividi su altri siti

E' sicuramente colpa dello S7 lite probabilmente gestisce la clipboard in maniera diversa... mi sa che dovrai scriverli a mano.

Oppure se vuoi incolla questo in un file nominato simboli.asc:

126,Cycle Execution         OB      1   OB      1                                                                                 
126,Dati                    DB     10   DB     10 Dati loggati                                                                    
126,FILL                    SFC    21   SFC    21 Initialize a Memory Area                                                        
126,Log_End                 M      10.2 BOOL      Bit fine log                                                                    
126,Log_Memo                M       0.5 BOOL      Memorizza dato in log                                                           
126,Log_NrDatiMem           MW     14   INT       Nr di dati memorizzati                                                          
126,Log_Reset               M      10.0 BOOL      Azzeramento Log                                                                 
126,Log_Val                 MW     12   INT       Valore da memorizzare                                                           
126,LogFull                 M      10.3 BOOL      Bit DB dati piena                                                               
126,Logger                  FB      1   FB      1 Logger dati                                                                     
126,Logger_DB               DB      1   FB      1 DB per FB1          

poi fai Tabella> importa e clicchi sul file (sempre che lite abbia import/export...)

Modificato: da JumpMan
Link al commento
Condividi su altri siti

Avevamo ragione, Step7 Lite mi ricorda la versione evoluta di S5, sotto il menù File ha sia import che export, e per l'importazione accetta solo file .awl - .seq - .sdf - .k7e.

Quindi ho copiato tutto in un file di testo e gli ho cambiato l'estensione in awl, lo ha importato e ha creato OB1 DB1 DB10, ma non FB1 e SFC21 dandomi i seguenti errori che francamente non capisco il perchè:

Riga 145 Errore di sintassi in #Reset
Riga 147 Errore di sintassi in _001
Riga 183 Errore di sintassi in #Memo
Riga 185 Errore di sintassi in #End
Riga 186 Errore di sintassi in #Full
Riga 187 Errore di sintassi in #Reset
Riga 188 Errore di sintassi in _002
Riga 194 Errore di sintassi in _002
Riga 205 Errore di sintassi in DB
(Warning) Riga 207 Accertarsi che sia stato aperto il DB globale esatto.
A parte questo piccolo inconveniente ho cominciato a studiare quello che hai scritto, e complimenti perchè grazie ai commenti lo capirebbe anche un bambino (e forse meglio di me) è molto chiaro tutto il ciclo, solo un paio di domande: la limitazione a 99 word è modificabile o è un limite fisico?
Se non sbaglio la SFC 21 non può essere richiamata in contemporanea da diversi FB, posso fare in modo che questo non succeda settando un merker per bloccare un altro richiamo?
Nel mio caso posso sostituire la MW12 con l'ingresso analogico oppure è sempre meglio trasferirlo su una MW?
Adesso provo a scrivere la FB 10 io e poi provo, Troverò il modo di sdebitarmi...grazie
Link al commento
Condividi su altri siti

e ha creato OB1 DB1 DB10, ma non FB1 e SFC21 dandomi i seguenti errori che francamente non capisco il perchè:

Non ho mai usato lo S7-lite e non so che limitazioni abbia, ho provato ad eseguire passo passo quanto ti ho scritto nel #6 e mi compila senza errori...

Se non crea SFC21 lo trovi nella cartella System Function Blocks della biblioteca standard, oppure lo trascini direttamente dalla CPU al progetto offline.

Per gli errori riferiti alle label forse non riconosce il carattere "_" metti un qualsiasi altro carattere nelle etichette e negli SPB (p.es. M001)

Quelli col cancelletto li deve riconoscere, sono gli operandi IN/OUT dell' FB :o

la limitazione a 99 word è modificabile o è un limite fisico?

Puoi usarne quante ne vuoi, basta che cambi gli indici dell'array nella db fino al limite massimo di dati ammessi in db per quella cpu.

Eventualmente (se non lo corregge automaticamente) dovrai correggere il parametro PtrArrayDati in OB1

Se non sbaglio la SFC 21 non può essere richiamata in contemporanea da diversi FB, posso fare in modo che questo non succeda settando un merker per bloccare un altro richiamo?

Che io sappia non ci sono controindicazioni a usare SFC21 più volte, a patto che non lo si usi contemporaneamente per trasferire dati da/verso la stessa area in 2 richiami contemporaneamente.

Nel mio caso posso sostituire la MW12 con l'ingresso analogico oppure è sempre meglio trasferirlo su una MW?

L'ingresso analogico ha valori da 0 a 27648, lo devi scalare ed appoggiare a una MW o DBW

Troverò il modo di sdebitarmi...grazie

Basta il grazie

ciao

Modificato: da JumpMan
Link al commento
Condividi su altri siti

Piano piano ci sto lavorando, trascrivendo tutto non mi ha dato nessun errore di sintassi come in precedenza, solo al richiamo della SFC21 mi dava errato il parametro RET_VAL ( iTemp_1) non lo ha accettato con dichiarazione Temp e richiedeva un Out. Non so se è la stessa cosa o se devo cambiare qualcos'altro ma nella tabella delle dichiarazioni l'ho spostato nell'Out e così lo ha accettato, dimmi se può andare bene.

Mi sono reso anche conto che per riuscire a collaudarlo dovevo cambiare i blocchi in modo da renderlo uniforme con il resto del programma, a questo punto ne faccio uno nuovo con i nuovi oggetti.

Mi metto al lavoro...

Grazie

Ciao

Link al commento
Condividi su altri siti

non lo ha accettato con dichiarazione Temp e richiedeva un Out.

non dovrebbe, ma hai messo tipo dati int ? se ti soffermi col mouse sopra la riga rossa che messaggio di errore ti appare nella tooltip ?

Mi sono reso anche conto che per riuscire a collaudarlo dovevo cambiare i blocchi

Fb1 non usa alcun parametro assoluto (eccetto quelli della sua DB di istanza) quindi dovrebbe essere adattabile a qualsiasi programma

I suoi parametri in/out che dichiari in OB1 li puoi cambiare a piacere.

Comunque fai pure le tue prove, se hai domande siamo qua...

Modificato: da JumpMan
Link al commento
Condividi su altri siti

non dovrebbe, ma hai messo tipo dati int ? se ti soffermi col mouse sopra la riga rossa che messaggio di errore ti appare nella tooltip ?

Non so cosa era successo, nell'indicazione richiedeva un dato dichiarato Out, ora ho rimesso a posto la tabella dichiarazioni e va tutto bene...

Fb1 non usa alcun parametro assoluto (eccetto quelli della sua DB di istanza) quindi dovrebbe essere adattabile a qualsiasi programma

I suoi parametri in/out che dichiari in OB1 li puoi cambiare a piacere.

Nel programma che ho già scritto FB1 è già utilizzato, per non sconvolgere tutto cambio i blocchi...e poi non penserai mica che mi accontento di testare una batteria per volta, lo strumento in questione è già cablato con otto posti diponibili in contemporanea... :whistling:

Devo lavorare ancora molto...

Sempre grazie tanto

Buonanotte

Link al commento
Condividi su altri siti

Niente di particolare, quando faccio un FB lo metto sempre così ho a disposizione alcuni bit da usare nei fronti, se servono bene altrimenti sono lì...

Non uso mai operandi E/A/M/T/C con indirizzo assoluto all'interno di blocchi FB/FC, questo garantisce la portabilità degli FB/FC su qualsiasi progetto...

Link al commento
Condividi su altri siti

Piccolo aggiornamento: ho fatto alcune delle modifiche che pensavo e ho caricato il programma in cpu, mi va in errore e sto correggendo alcuni sbagli nei miei altri FB.

Vorrei sapere solo questo, è corretto pensare di richiamare sempre il tuo FB per la memorizzazione dei dati se ho più test da fare contemporaneamente, appoggiandomi al settaggio di un merker ad ogni lettura dl FB? Inoltre non c'è problema se lo chiamo da un altro FB invece che dall'OB1?

Ovviamente ad ogni richiamo diverso vado a cambiare le destinazioni tipo:

CALL "Logger" , "Logger_DB" (

PtrArrayDati := "Dati".Volt,
Reset := "Log_Reset",
Memo := "Log_Memo",
ValMin := 1,
Val := "Log_Val",
DatiMem := "Log_NrDatiMem",
End := "Log_End",
Full := "LogFull");
Come esempio ho cambiato aggiungendo solo un "2"
CALL "Logger" , "Logger_DB" (
PtrArrayDati := "Dati2".Volt,
Reset := "Log_Reset2",
Memo := "Log_Memo",
ValMin := 1,
Val := "Log_Val2",
DatiMem := "Log_NrDatiMem2",
End := "Log_End2",
Full := "LogFull2");
Fammi sapere se dico stupidaggini, grazie JumpMan
Link al commento
Condividi su altri siti

Puoi farlo tranquillamente, è l'uso tipico degi FB / FC.

Devi però ogni volta cambiare anche la db d'istanza Logger_DB !

Il bit Log_memo l'hai volutamente lasciato uguale ?

Modificato: da JumpMan
Link al commento
Condividi su altri siti

...dimenticavo...

Se ti ritrovi con troppe DB puoi duplicare gli array nella DB dati e mantenere sempre la stessa DB (se non viene troppo lunga)

Dati.Volt_1

Dati.Volt_2

Dati.Volt_3

Dati.Volt_4

Io di solito integro i dati risultanti (in questo caso l'array Volt) all'interno della DB di istanza stessa dell'FB nelle variabili STAT, ma alcuni utenti del forum non condividono uesto modo di lavorare, per questo non te l'ho neanche proposto.

Link al commento
Condividi su altri siti

Grazie JumpMan,

Devi però ogni volta cambiare anche la db d'istanza Logger_DB !

Ma le variabili non cambiano nome, come mai dovrei utilizzare una DB d'istanza diversa?

Il bit Log_memo l'hai volutamente lasciato uguale ?

Si è il risultato di un movimento unico per tutti gli otto test.

Se ti ritrovi con troppe DB puoi duplicare gli array nella DB dati e mantenere sempre la stessa DB (se non viene troppo lunga)

Veramente se le word possibili sono 255 sono ancora poche per ogni test, infatti il Log_Memo sarà settato ogni tre prove, credo, ma per ora è piuttosto una teoria...

Link al commento
Condividi su altri siti

Ma le variabili non cambiano nome, come mai dovrei utilizzare una DB d'istanza diversa?

La differenza tra un FC e un FB è che quest'ultimo ha bisogno di una DB di istanza dove l'FB stesso andrà ad appoggiare i valori dei parametri in, out, in/out e stat (questi ultimi non presenti in un FC).

La DB d'istanza (lo dice la parola) deve essere una DB diversa per ogni istanza del richiamo, poi ci sarebbe un altro modo di usare gli FB (multiistanza) che non è il caso di spiegare ora per non creare confusione.

La riga di richiamo di un FB può (volendo) anche non contenere dichiarazioni di variabili nei parametri, nel senso che puoi richiamare un FB con la sua DB senza dichiarare nessuno o alcuni dei suoi parametri IN/OUT, in questo caso funzionerà lo stesso ma con i valori presi direttamente dalla DB di istanza e non dai parametri dichiarati in OB1. In questo caso le variabili possono essere lette/ scritte altrove nel programma.

Veramente se le word possibili sono 255 sono ancora poche per ogni test, infatti il Log_Memo sarà settato ogni tre prove, credo, ma per ora è piuttosto una teoria...

Questo con S5, con S7 la grandezza massima di una DB dipende dalla CPU usata, e sulla serie 31x dovrebbe essere di 16 k bytes, quindi il tuo array puoi ingrandirlo un bel po'

Link al commento
Condividi su altri siti

La riga di richiamo di un FB può (volendo) anche non contenere dichiarazioni di variabili nei parametri, nel senso che puoi richiamare un FB con la sua DB senza dichiarare nessuno o alcuni dei suoi parametri IN/OUT, in questo caso funzionerà lo stesso ma con i valori presi direttamente dalla DB di istanza e non dai parametri dichiarati in OB1. In questo caso le variabili possono essere lette/ scritte altrove nel programma.

Questo allora potrebbe fare al caso mio, ma quando le variabili sono indicate nel richiamo non sono lette e scritte altrove?

Link al commento
Condividi su altri siti

Ti faccio 2 esempi:

Richiamo con parametri:

     CALL  FB1 , "DB1"
      VarIn:= MW2
      VarInOut:= MW4
      VarOut:= MW6
Prima di elaborare FB1 il sistema trasferisce automaticamente MW2 e MW4 nelle corrispondenti word (VarIn e VarInOut) della DB1
Durante l'elaborazione del blocco tutte le letture e scritture sono effettuate nelle variabili della DB d'istanza (in questo caso DB1)
A fine elaborazione vengono copiati i valori di VarInOut e VarOut rispettivamente in MW4 e MW6

Richiamo senza parametri:

     L MW2
      T "DB1".VarIn
      L MW4
      T "DB1".VarInOut

      CALL  FB1 , "DB1"
      VarIn:= 
      VarInOut:= 
      VarOut:= 


      L "DB1".VarInOut
      T MW4
      L "DB1".VarOut
      T MW6

Prima del richiamo vengono impostate le variabili dell'FB (anche altrove)

Non essendo dichiarati parametri l'FB lavora esclusivamente sulle variabili della DB d'istanza DB1
Dopo l'elaborazione vengono scritti i risultati sulle MW4 e MW6
Funziona allo stesso modo ma è più disordinato, personalmente non abuso di questo sistema di scrivere i parametri fuori dal richiamo, ma a volte fa comodo, se lo faccio, cerco di mettere le operazioni nello stesso segmento, ti faccio un esempio:
    
      L MW2
      L 100
      *I 
      T "DB1".VarIn

     
      CALL  FB1 , "DB1"
      VarIn:= 
      VarInOut:=MW4
      VarOut:= MW6

Oppure:

      L MW2
      ITD
      T "DB1".VarIn

      CALL  FB1 , "DB1"
      VarIn:= 
      VarInOut:=MW4
      VarOut:= MW6
Modificato: da JumpMan
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...