Vai al contenuto
PLC Forum


Scl: Proviamo Ad Ottimizzarlo - Voi conoscete una soluzione alternativa?


Messaggi consigliati

Inserito:

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.

  • 3 weeks later...

Inserita:

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 con

WORD_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, XOR

where:

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 qualche

regola di sintassi.

Ma il concetto rimane.

Inserita:

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.

Inserita: (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: da Beatrice_Ru
Inserita:
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.

Inserita: (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 parti

e' 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. :rolleyes:

Modificato: da Beatrice_Ru
Inserita:

(*

#############################################

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 UDT10

BEGIN

END_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: DWORD

VAR_INPUT

NrDB: WORD; // Data Block number

i: INT; // Index

END_VAR

VAR_OUTPUT

Check: DWORD; // Checked

END_VAR

VAR

Eq1: UDT10; // Structur Eq1 from UDT10

d1,d2,d3: DWORD; // Oper d1..d3

END_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

Inserita:

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 I008

I007: CLR

= L 1612.1

I008: L L#32

*D

SPO I009

SPA I00a

I009: CLR

= L 1612.1

I00a: L L#3200

+D

SPO I00b

SPA I00c

I00b: CLR

= L 1612.1

I00c: 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 I00e

I00d: CLR

= L 1612.1

I00e: L L#32

*D

SPO I00f

SPA I010

I00f: CLR

= L 1612.1

I010: L L#6400

+D

SPO I011

SPA I012

I011: CLR

= L 1612.1

I012: 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 I014

I013: CLR

= L 1612.1

I014: L L#32

*D

SPO I015

SPA I016

I015: CLR

= L 1612.1

I016: L L#9600

+D

SPO I017

SPA I018

I017: CLR

= L 1612.1

I018: 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

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