Vai al contenuto
PLC Forum


Copiare Variabili In Base All'intero.


lappone2

Messaggi consigliati

Buona sera a tutti.

Mi sto facendo del male a fare la seguente operazione:

Ho un INT che può assumere valori compresi tra 1 e 20.

In base al valore, devo copiare da un DB dei valori e copiarli su tre variabili.

Sto mettendo giù un'FC che mi dia in uscita le tre variabili di mio interesse (#a, #b, #c).

ES.

X=INT

se X=1

copia

DB1.DBW2 in #a

DB1.DBW4 in #b

DB1.DBW44 in #c

se X=2

copia

DB1.DBW6 in #a

DB1.DBW8 in #b

DB1.DBW46 in #c

se X=3

copia

DB1.DBW10 in #a

DB1.DBW12 in #b

DB1.DBW48 in #c

Ecc.

Ho scritto qualcosa utilizzando funzioni L e T a manetta, ma il codice è una porcheria, affosso la CPU, considerando che devo richiamarla diverse volte nel programma.

Peronalmente ho sempre copiato blocchi di variabili "compatti" da un DB all'altro con l'aiuto di FC20 (ho un'FC che uso per le ricette).

Non ho mai avuto necessità di costruire un sistema che mi discrimina i byte da copiare da un DB (sono relativamente "alle prime armi" :unsure: ), c'è qualcuno che può aiutarmi a mettere giù un'idea per creare una funzione scritta in modo funzionale?

Vi ringrazio in anticipo.

Modificato: da lappone2
Link al commento
Condividi su altri siti


No, in effetti non è che hai fatto un bel lavoro; anche se, con il passo di variabili che hai, non riesci comunque a scrivere un codice pulito:

1) Dichiara all'interno della tua FC una variabile DWORD, che chiameremo, ad esempio "ptr";

2) Potresti ora fare un simile codice;

OPN DB1;

L x;

L offset1; // (passo del primo offset rispetto allo 0)

+I;

SLW 3;

T #ptr;

L DBW[#ptr];

T #a;

L x;

L offset2; // (passo del secondo offset rispetto allo 0)

+I;

SLW 3;

T #ptr;

L DBW[#ptr];

T #b;

L x;

L offset3; // (passo del terzo offset rispetto allo 0)

+I;

SLW 3;

T #ptr;

L DBW[#ptr];

T #c;

Questo codice va giusto bene se i dati destinati alle tre variabili, sono di volta in volta contigui, in tre matrici distinte. Il tuo caso non è proprio questo, quindi, oltre che a delle somme, devi usare anche delle moltiplicazioni, per fare si che, di volta in volta, il valore di offest porti la variabile ptr a valere (2, 4, 44); (4, 6, 46), etc.

Quello che sembra tu non sappia fare, è puntare ad una word della DB, aperta una unica volta ad inizio FC, tramite un puntatore ... hai l'esempio. Ora trovati i calcoli corretti per ricavare di volta in volta gli esatti offset e, ricorda, che una volta calcolato il numero devi shiftare a sinistra di tre, (SLW 3;), perché, nei puntatori, i primi tre bit puntano ai singoli bit del byte interessato.

Link al commento
Condividi su altri siti

Puoi anche puntare usando il registro AR1,

ti riporto il codice solo a titolo di esempio:

AUF DB1

L x // Indice 1...20

L 1

-I // Indice 0...19

L 4

*I // Indice 0-4-8-12..76

SLW 3 // Converte in puntatore (P#0.0-P#4.0-P#8.0-P#12.0 ... P#76.0)

LAR1 // carica in AR1

L DBW [AR1, P#2.0]

T a

L DBW [AR1, P#4.0]

T b

TAR1 // Scarica puntatore in ACCU 1

SRW 1 // Divide per 2

LAR 1 // ricarica il puntatore (P#0.0-P#2.0-P#4.0-P#6.0 ... P#38.0)

L DBW [AR1, P#44.0]

T c

Se non vado errato dovrebbe già funzionare.

Link al commento
Condividi su altri siti

Vi ringrazio per la cortese risposta.

La sfortuna é che si tratta di un DB abbastanza corposo e a dirla tutta, non l'ho generato io... Ripassare e rifare tutto mi scoccia, visto che è qualcosa di collaudato e funzionante.

Personalmente, tendo sempre a raggruppare le variabili con un concetto logico.

Provo a fare qualche prova con i vostri utili consigli.

Vi terrò informati.

Grazie ancora, siete stati gentili.

Link al commento
Condividi su altri siti

Ho costruito la funzione seguendo i vostri consigli.

Ho fatto alcune modifiche e tutto funziona alla grande!

Grazie davvero.

:thumb_yello:

Volevo chiede un'altra cosa senza aprire un'altra discussione (sempre se non vado contro le regole del forum e contro la vostra pazienza...)

Ho due FB che vengono richiamati in OB1.

I due FB sono "due macchine identiche" che sono state ragruppate in un unica CPU.

Se entrambi i FB vengono richiamati contemporaneamete, mi si presentano errori incomprensibili (come allegato)

Questi si verificano in diverse parti dei due FB.

I FB sono identici, tutte le FC, DB, richiamate in essi, anche se uguali sono univoche (sono sicuro al 100% che non sto sovrascrivendo nulla).

In comune hanno solo un richiamo a SFB2 (ognuno con proprio DB) e SFC20.

ES:

OB1-

-FB1(DB1)

-FC1--SFC20

-FC2--SFB2(DB10)

-FB2(DB2)

-FC3--SFC20

-FC3--SFB2(DB11)

Qualcuno ha già avuto un'inconveniente di questo tipo?

Grazie come sempre della vostra enorme disponibilità....

Link al commento
Condividi su altri siti

Hai usato dei fronti P ed N, appoggiandoti A VARIABILI LOCALI, che non si ritengono all'uscita della funzione, per forza che ti succedono i casini.

TUTTO cosa deve avere un valore certo, o, noto, all'entrata della funzione, non deve stare in variabili locali. Ranza via tutto, ed impiega delle aree M, o qualcosa altro, per le variabili da ritenere a fine funzione.

Modificato: da mubeta
Link al commento
Condividi su altri siti

Grazie per il supporto.

Scusa, se aprofitto del tuo aiuto, ma vorrei capire meglio ciò che mi hai detto.

Per tutto deve avere un valore certo o noto all'ingresso della funzione, intenti l'ingresso di abilitazione EN o intendi i valori di passaggio IN/OUT di una FC-FB?

Nella funzione che vedi dallo screenshot, dovrei passare la variabile #nomecicloesecuzione da locale a MWx e così via?

Grazie.

Link al commento
Condividi su altri siti

No, Mubeta si riferisce ai bit #imp1_1 eccetera, ma piuttosto che usare variabili M sposta quei bit dalle variabili TEMP alle variabili STAT.

Occhio anche a un vecchio problema che affligge (affliggeva?) gli FB/FC, se hai una variabile OUT è sempre meglio che la dichiari IN/OUT anche se la usi solo in scrittura, ho avuto dei problemi con le variabili OUT (molti anni fa, c'è una vecchia discussione in merito).

Modificato: da JumpMan
Link al commento
Condividi su altri siti

Non so...

Ero preoccupato inizialmente dalla sfb2 richiamata in giro nei FB.

Pensandoci bene, (questo non è il caso) per i PID, utilizzo un paio di sfb e non ho mai avuto anomalie di questo tipo...

Proverò a passare le TEMP in STAT, vedo se cambia qualcosa...

Dimenticavo... Se faccio funzionare i FB in modo alternato, non ho nessun problema...

Modificato: da lappone2
Link al commento
Condividi su altri siti

Per forza, l'area temporanea delle variabili L non viene intaccata ed al successivo richiamo, guarda caso, si ritrova uguale allo stato precedente.

Nel precedente post, intendevo, come ti hanno poi spiegato, che quando una funzione viene richiamata, (punto d'entrata, riferendosi al codice), le variabili che devono avere un valore noto, non possono e non devono risiedere nell'area LOCAL. (I manuali prodotto sono anche molto chiari, ma, in ogni caso, è facilmente intuibile). Le variabili che passi come ingresso certo che sono rinfrescate, ci mancherebbe altro.

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