mubeta Inserito: 16 giugno 2008 Segnala Inserito: 16 giugno 2008 Mi sto accingendo a scrive del codice in SCL, per una diretta richiesta del cliente, il quale, visto che ormai la barriera del "KNOW_HOW_PROTECT" è superata, vuole che il "suo" sorgente non accessibile.Il problema grosso che ho riscontrato, è nel pezzo di codice che segue:FOR i:=0 TO 96 BY 4 DO d1 := WORD_TO_BLOCK_DB(NrDB).DD[100+i] OR WORD_TO_BLOCK_DB(NrDB).DD[200+i]; d2 := WORD_TO_BLOCK_DB(NrDB).DD[300+i]; IF (d1 XOR d2) <> 0 THEN ...; END_IF; IF ... THEN ...; END_IF; WORD_TO_BLOCK_DB(NrDB).DD[i] := d1; END_FOR; Questo pezzo di codice è l'unico modo che ho trovato per accedere, in modo indicizzato ad una DB, ed indicizzare ulteriormente l'area di lavoro.E' vero che potrei copiare tutta la DB in locale, elaborare, e salvare alla fine, esiste il modo di farlo, ma, ahimè, parliamo di 200 WORD di dati.D'altro canto, in SCL, le operazioni logiche su parola suppartano al massimo la DWORD, e quindi scaturisce l'esigenza del loop sopra scritto.Se già la ricorsiva apertura della DB è un mattoncino per la CPU, il codice di spora è tutto un mattone. Ne sono conscio e consapevole.La domanda, che non è tale, è la richiesta di un vostro suggerimento, ammesso che esista, su come ottimizzare il codice descritto, in SCL appunto. Dall'aprire la DB in modo permanente, a quant'altro sapete fare di meglio.Come detto più sopra, non consigliatemi l'AWL, o la copia in area M (che ho già riflettuto).Buon proficuo lavoro.
Beatrice_Ru Inserita: 7 luglio 2008 Segnala Inserita: 7 luglio 2008 Indipendentemente dall' istruzione WORD_TO_BLOCK_DB, potresti ottimizzare la Routine in questo modo:Usare un ciclo "FOR" impiegna la CPU sino al termine del ciclo.potresti percio' invece che eseguire un ciclo For, usare un variabile di indice incrementandola ad ogni Scan-Logic in questo modo i := i + 4; per poi terminare indicizazione quando If i =64 then ... Cosi sovracarichi meno il tuo PLC.potresti inserire nelle tue DB un intera struttura dati (UDT) quindi richiamare la DB voluta conWORD_TO_BLOCK_DB(NrDB).Struct copia la tua struttura in una variabile Locale, (che e' stata creata dal medesimo UDT)Check := WORD_TO_BLOCK_DB(NrDB).Struct ;Poi esegui le operazioni con gli operanti OR, XORwhere: Def Struct,Check : UDT100 UDT100 is your "User Data Type"in questo modo puoi caricare un intera struttura Dati in una sola operazione, in un area locale.Udt 100 d1 : Dword: d2 : Dword: d3 : Dword:end def; Check := WORD_TO_BLOCK_DB(NrDB).Struct ; IF ((Check.d1 OR Check.d2) XOR Check.d3) <> 0 then ........ ........ End_if; Riguarda un po' meglio la definizione che io ti ho descritto, in quanto quanche volta SCL mi scordo qualcheregola di sintassi.Ma il concetto rimane.
mubeta Inserita: 8 luglio 2008 Autore Segnala Inserita: 8 luglio 2008 Come avevo già scritto nel primo post, non ci sta l'intera DB in locale; parimenti non posso permettermi di fare il loop a piccole dosi, per n cicli di scansione, perché perderei il significato e l'utilità del medesimo.Piuttosto, ero alla ricerca di una soluzione per fare l'apertura della DB una unica volta, in testa alla routine, come si fa in AWL, ma non ho trovato nulla per farlo.
Beatrice_Ru Inserita: 8 luglio 2008 Segnala Inserita: 8 luglio 2008 (modificato) Puoi caricare in una Variabile Locale anche un elemento complesso come una Struttura.Percio' una volta aperta, puoi farci tutti i giochi che vuoi, con tutti i sui sotto elementi.Senza ricorrere a molteplici aperture di Blocchi.Poi se non ti interessa ottimizzare il ciclo di eleborazione, che problemi hai ad aprire piu' di un Data Block alla volta ?Ottimizza i concetti informatici, e non creare pasticci.Elementi univoci, e strutture dati ben ottimizzate, ti permettono di creare un codice, piu' snello e piu' prestante.Anche l'operazione (x1 Or x2) xor X3 puo' essere semplificata.Ad esempio come mai hai degli Offset relatvi di 100,200,300 ?d1 := DBN.DD[100+i] OR DBN.DD[200+i];d2 := DBN.DD[300+i];perche' non formati la tua DB in maniera piu' efficiente ? Modificato: 8 luglio 2008 da Beatrice_Ru
mubeta Inserita: 8 luglio 2008 Autore Segnala Inserita: 8 luglio 2008 Puoi caricare in una Variabile Locale anche un elemento complesso come una Struttura.In qualunque modo si formattata la DB, fosse anche una struttura o più, come scritto nel primo post, 200 word non ci stanno nei dati locali, specialmente si si ha solo una 313 su cui lavorare.Poi se non ti interessa ottimizzare il ciclo di eleborazione, che problemi hai ad aprire piu' di un Data Block alla volta ?Sempre tornando al primo post, è scritto che le operazioni logiche tipo: OR, XOR, AND, ecc, sono possibili al massimo su doppia parola.Visto che tutti i dati NON ci stanno in locale, mi tocca prenderli dove sono, nella DB, che in quanto indicizzata, a quanto pare si apre solo in quel modo.Ad esempio come mai hai degli Offset relatvi di 100,200,300 ?Perché eveidentemente devo fare delle operazioni con tali offset. Nello specifico la parte di codice postata fa l'OR di 800 bit provenienti da due diverse fonti e poi genera un evento sul fronte di salita di uno qualunque (XOR).perche' non formati la tua DB in maniera piu' efficiente ?Perché se mischio di più i dati, altrove, per poterli mettere in quella DB, invece di usare un unico BLKMOV, mi toccherebbe dilungarmi ulteriormente per preparare la DB dove fare sto benetto fronte di salita.Non è mio tipico criticare su un forum, ma a me sembra di capire, leggendo i post precedenti, che di SLC per siemens tu ne capisca molto poco. Il problema centrale dell'esempio postato è evitare il ricorsivo uso della funzione WORD_TO_BLOCK_DB dal momento che la DB è già aperta; quindi scrivere quelle quattro righe di codice senza far rifare operazioni unitili alla CPU.Sono poi problemi miei su come formatto la DB, le UDT, se sono o meno ottimizzate; ma visti i limiti del linguaggio, c'è ben più poco da ottimizzare per generare un evento su fronte di salita di 800 bit provenienti da due diversi canali.
Beatrice_Ru Inserita: 9 luglio 2008 Segnala Inserita: 9 luglio 2008 (modificato) Nessuno ti sta criticando.Fai come vuoi tu, e studiati bene SCL, cosi che non avrai mai bisogno di nessun aiuto.Se tu vedi nessuno altro ti ha aiutato, A CASA MIA un aiuto e' sempre una bella cosa, non so se dalle tue partie' diverso.Ma hai provato a vedere, il tuo Codice dopo essere stato compilato in AWL (SCL => AWL).Hai controllato nelle istruzioni quante volte il Compilatore a richiesto un apertura di una nuova DB.Il Compilatore a volte e' piu' efficiente del tuo sorgete, e potrebbe gia' aver ovviato a quello che tu cerchi da tempo.Senti magari quando hai trovato la soluzione, perche' non ce la mandi ?Saluti. Modificato: 9 luglio 2008 da Beatrice_Ru
Beatrice_Ru Inserita: 10 luglio 2008 Segnala Inserita: 10 luglio 2008 (* ############################################# Program Example UDTDB TITLE : 'used DB from UDT ' VERSION: 'Example' AUTHOR: Beaty NAME: Example UDTDB Date 10 Jul 2k8 #############################################*)// [at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at]// [at] CREATE UDT 10 [at] // [at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at]TYPE UDT10 STRUCT EQ: STRUCT d0: ARRAY [0..99] OF DWORD; d1: ARRAY [0..99] OF DWORD; d2: ARRAY [0..99] OF DWORD; d3: ARRAY [0..99] OF DWORD; END_STRUCT; END_STRUCT END_TYPE // [at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at]// [at] CREATE DB 10 [at] // [at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at]DATA_BLOCK DB10 UDT10BEGINEND_DATA_BLOCK // [at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at]// [at] CREATE FB10 [at] // [at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at][at]FUNCTION FC10: DWORDVAR_INPUTNrDB: WORD; // Data Block numberi: INT; // IndexEND_VARVAR_OUTPUTCheck: DWORD; // CheckedEND_VARVAREq1: UDT10; // Structur Eq1 from UDT10d1,d2,d3: DWORD; // Oper d1..d3END_VAR Eq1:= DB10; d1:= Eq1.EQ.d1; d2:= Eq1.EQ.d2; d3:= Eq1.EQ.d3; Check := (d1 OR d2) XOR d3; FC10 := Check;END_FUNCTION
Beatrice_Ru Inserita: 10 luglio 2008 Segnala Inserita: 10 luglio 2008 Ecco la Compilazione in AWL SET SAVE = L 1612.1 L DW#16#10020640 T LD 1614 L W#16#A T LW 1618 L DW#16#84000000 T LD 1620 L DW#16#10020640 T LD 1624 L W#16#0 T LW 1628 L DW#16#87000000 T LD 1630 UC SFC 20 P#L 1614.0 P#L 1634.0 P#L 1624.0 L #i ITD L L#0 >=D U L 1612.1 = L 1612.1 TAK L L#99 <=D U L 1612.1 = L 1612.1 TAK L L#0 +D SPO I007 SPA I008I007: CLR = L 1612.1I008: L L#32 *D SPO I009 SPA I00aI009: CLR = L 1612.1I00a: L L#3200 +D SPO I00b SPA I00cI00b: CLR = L 1612.1I00c: LAR1 L LD [AR1,P#0.0] T #d1 L #i ITD L L#0 >=D U L 1612.1 = L 1612.1 TAK L L#99 <=D U L 1612.1 = L 1612.1 TAK L L#0 +D SPO I00d SPA I00eI00d: CLR = L 1612.1I00e: L L#32 *D SPO I00f SPA I010I00f: CLR = L 1612.1I010: L L#6400 +D SPO I011 SPA I012I011: CLR = L 1612.1I012: LAR1 L LD [AR1,P#0.0] T #d2 L #i ITD L L#0 >=D U L 1612.1 = L 1612.1 TAK L L#99 <=D U L 1612.1 = L 1612.1 TAK L L#0 +D SPO I013 SPA I014I013: CLR = L 1612.1I014: L L#32 *D SPO I015 SPA I016I015: CLR = L 1612.1I016: L L#9600 +D SPO I017 SPA I018I017: CLR = L 1612.1I018: LAR1 L LD [AR1,P#0.0] T #d3 L #d1 L #d2 OD L #d3 XOD T #Check L #Check T #RET_VAL CLR U L 1612.1 SAVE BE
Beatrice_Ru Inserita: 10 luglio 2008 Segnala Inserita: 10 luglio 2008 (modificato) Sorgente SCL del Esempio Insert new Object / External Source .... // importa il file FC10.SCL del link Modificato: 10 luglio 2008 da Beatrice_Ru
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