Claudio Jallin Inserito: 13 dicembre 2014 Segnala Inserito: 13 dicembre 2014 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
JumpMan Inserita: 13 dicembre 2014 Segnala Inserita: 13 dicembre 2014 (modificato) 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: 13 dicembre 2014 da JumpMan
Claudio Jallin Inserita: 13 dicembre 2014 Autore Segnala Inserita: 13 dicembre 2014 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.
JumpMan Inserita: 14 dicembre 2014 Segnala Inserita: 14 dicembre 2014 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...
Claudio Jallin Inserita: 14 dicembre 2014 Autore Segnala Inserita: 14 dicembre 2014 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 , grazie JumpMan.
JumpMan Inserita: 14 dicembre 2014 Segnala Inserita: 14 dicembre 2014 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...
Claudio Jallin Inserita: 14 dicembre 2014 Autore Segnala Inserita: 14 dicembre 2014 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.... Appena riesco a testare il tutto ti faccio assolutamente sapere. Di nuovo molte grazie...
JumpMan Inserita: 14 dicembre 2014 Segnala Inserita: 14 dicembre 2014 (modificato) 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: 14 dicembre 2014 da JumpMan
Claudio Jallin Inserita: 15 dicembre 2014 Autore Segnala Inserita: 15 dicembre 2014 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
JumpMan Inserita: 15 dicembre 2014 Segnala Inserita: 15 dicembre 2014 (modificato) 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 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: 15 dicembre 2014 da JumpMan
Claudio Jallin Inserita: 15 dicembre 2014 Autore Segnala Inserita: 15 dicembre 2014 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
JumpMan Inserita: 15 dicembre 2014 Segnala Inserita: 15 dicembre 2014 (modificato) 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: 15 dicembre 2014 da JumpMan
Claudio Jallin Inserita: 15 dicembre 2014 Autore Segnala Inserita: 15 dicembre 2014 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... Devo lavorare ancora molto... Sempre grazie tanto Buonanotte
Claudio Jallin Inserita: 16 dicembre 2014 Autore Segnala Inserita: 16 dicembre 2014 Forse una domanda la farei, perchè usi l'array FF sui fronti di salita? Scusa l'ignoranza... Grazie
JumpMan Inserita: 16 dicembre 2014 Segnala Inserita: 16 dicembre 2014 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...
Claudio Jallin Inserita: 18 dicembre 2014 Autore Segnala Inserita: 18 dicembre 2014 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
JumpMan Inserita: 18 dicembre 2014 Segnala Inserita: 18 dicembre 2014 (modificato) 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: 18 dicembre 2014 da JumpMan
JumpMan Inserita: 18 dicembre 2014 Segnala Inserita: 18 dicembre 2014 ...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.
Claudio Jallin Inserita: 18 dicembre 2014 Autore Segnala Inserita: 18 dicembre 2014 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...
JumpMan Inserita: 18 dicembre 2014 Segnala Inserita: 18 dicembre 2014 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'
Claudio Jallin Inserita: 18 dicembre 2014 Autore Segnala Inserita: 18 dicembre 2014 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?
JumpMan Inserita: 18 dicembre 2014 Segnala Inserita: 18 dicembre 2014 (modificato) 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: 18 dicembre 2014 da JumpMan
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora