Max Reger Inserito: 21 aprile 2005 Segnala Inserito: 21 aprile 2005 Scusate la mia probabile ignoranza sull'argomento se pongo questo quesito: non è possibile indicizzare un array di dati ( o di strutture di dati), contenuto in una DB strutturata ad hoc, con indici che possano essere richiamati con parametro (per esempio struttura di informazioni su una serie di oggetti, e richiamo in modo parametrico della struttura associata all'i-esimo oggetto)?Grazie per la disponibilità di tutti
h.ki Inserita: 21 aprile 2005 Segnala Inserita: 21 aprile 2005 ..spero di aver interpretato correttamente quallo che intendi. Tu vorresti avere un vettore dal quale richiamare le variabili interne alla struttura tramite un indice (anch'esso una variabile)? del tipo #C?dim array[1..10]L array[n]non mi risulta sia possibile un accesso alla struttura di questo tipo
STEU Inserita: 21 aprile 2005 Segnala Inserita: 21 aprile 2005 Se ho capitop bene dovresti indicizzare un parametro any , questo è possibile.Chiaramente la lunghezza del parametro any deve coincidere con il tuo array.
Max Reger Inserita: 21 aprile 2005 Autore Segnala Inserita: 21 aprile 2005 MI RENDO CONTO DI NON ESSERE STATO PER NULLA CHIARO (POCHE IDEE MA CONFUSE..), E QUINDI MI SPIEGO CON UN ESEMPIO. DATA LA SEGUENTE DB (DI ESEMPIO), SE HO UN INDICE I VARIABILE (PARAMETRICO) POSSO ACCEDERE AL DATO par0 (OPPURE par1 ECC.) DELL'I-ESIMO CAMPO DELLA STRUCT?? (NB: SONO BOOL)DATA_BLOCK DB 230TITLE =VERSION : 0.1 STRUCT OrdineIndice : ARRAY [1 .. 100 ] OF //Variabile jolly provvisoria STRUCT par0 : BOOL ; par1 : BOOL ; par2 : BOOL ; par3 : BOOL ; par4 : BOOL ; par5 : BOOL ; par6 : BOOL ; par7 : BOOL ; par8 : BOOL ; par9 : BOOL ; par10 : BOOL ; par11 : BOOL ; par12 : BOOL ; par13 : BOOL ; par14 : BOOL ; par15 : BOOL ; END_STRUCT ; END_STRUCT ; BEGIN END_DATA_BLOCK
p.valli Inserita: 21 aprile 2005 Segnala Inserita: 21 aprile 2005 dalle prove che ho potuto fare (anche perchè avevo la tua stessa esigenza), ho scoperto che non è possibile mettere una variabile (d tipo INT) come ndice dell'array (es: array[var], dove var è il tuo indice), ma puoi solo usare costanti (array[1], array[2]....) per accedere al valore dell'emento dell'array.Se però usi una DB, puoi generarti una funzione e utilizzare i puntatori, sapendo la distanza da un elemento e l'altroopn db10dbw [ar1,p#0.0]dove in ar1 ha prima caricato l'indirizzo (in bit) dell'elemnto da puntare.es: per puntare a DB20.dbw10L 10L 8 (dimensione in byte)*ILAR1 (caricamento in registro AR1)opn db10L dbw [ar1,p#0.0] (AR1=80 e punterai a db10.dbw10)Ciao
cobe Inserita: 23 aprile 2005 Segnala Inserita: 23 aprile 2005 Ciao, visto che avevo la stessa necessità, ho preso al volo il tuo consiglio ma mi da errore su L DBW[AR1,p#0.0]Le righe prima sono ok ma su questa ho errore. devo fare qualche dichiarazione a parte?Ciao
GKG Inserita: 24 aprile 2005 Segnala Inserita: 24 aprile 2005 Prova così:L DBD [AR1,p#0.0]Infatti credo sia necessario appoggiarsi ad una DWORDCiao
Matteo Montanari Inserita: 25 aprile 2005 Segnala Inserita: 25 aprile 2005 (modificato) Prova così:L DBD [AR1,p#0.0]Infatti credo sia necessario appoggiarsi ad una DWORDnon è corretto, utilizzando un puntatore di tipo AR1 (o AR2) puoi fare le varie combinazioni: U DBX [AR1,P#0.0] L DBB [AR1,P#0.0] L DBW [AR1,P#0.0] L DBD [AR1,P#0.0]se devi eseguire un caricamento oppure = (S,R) DBX [AR1,P#0.0] T DBB [AR1,P#0.0] T DBW [AR1,P#0.0] T DBD [AR1,P#0.0]se devi eseguire un trasferimentoCiao, visto che avevo la stessa necessità, ho preso al volo il tuo consiglio ma mi da errore su L DBW[AR1,p#0.0]Le righe prima sono ok ma su questa ho errore.molto probabilmente ti segnava errore perchè scrivevi L DBW[AR1,p#0.0] e non L DBW [AR1,P#0.0](le nuove versioni correggono automaticamente l'errore di sintassi).devo fare qualche dichiarazione a parte?la dichiarazione devi farla se utilizzi un area di memoria e non il puntatore. supponendo di utilizzare lo stesso esempio di prima: L 10 L 8 // (dimensione in byte) *I T MD 250 // (caricamento in registro MD250) AUF DB 10 L DBW [MD 250] // (MD250=80 e punterai a db10.dbw10) è comodo utilizzare anche gli "offset" (P#0.0) ad esempio U DIX [AR1,P#0.0] // Legge stato Ingresso UN DIX [AR1,P#4.0] // Legge stato Appoggio Impulsivo X DIX [AR1,P#2.0] // Legge stato Uscita = DIX [AR1,P#2.0] // Scrive stato Uscita Modificato: 25 aprile 2005 da keosmm
doublecra Inserita: 3 maggio 2005 Segnala Inserita: 3 maggio 2005 Nel problema iniziale non hai detto con quale linguaggio hai intenzione di programmare il blocco.Esiste la possibilità di utilizzare il linguaggio di programmazione SCL (ma non è compreso nella licenza base di STEP 7) che consente di accedere alle DB dichiarate con strutture complesse semplicemente usando gli indici degli array.Nel caso tu abbia tale possibilità ti consiglio comunque di non abusare di tale linguaggio di programmazione perchè nella compilazione l'AWL che ne risulta è tipicamente abbastanza pesante.Se invece devi lavorare direttamente con AWL, l'unica strada è quella dei puntatori. In questo caso di consiglio di appoggiare l'intera struttura su una struttura locale gemella dell'originale e poi testare i bit che ti interessano. La soluzione è un po' più pesante ma ne guadagni in leggibilitàCiao e buon lavoro.
tode72 Inserita: 17 maggio 2005 Segnala Inserita: 17 maggio 2005 Ho seguito i vostri consigli anch'io e non da errore in AWL, ma devo ancora provarlo sul campo. Ho fatto però una variante, cioè una DB con tutti array come elementi. Secondo voi funziona lo stesso o mi devo aspettare che... :cussing: ... e devo rifare il pezzo di codice?Grazie mille dell'aiuto
Matteo Montanari Inserita: 17 maggio 2005 Segnala Inserita: 17 maggio 2005 Ho fatto però una variante, cioè una DB con tutti array come elementi. Secondo voi funziona lo stesso o mi devo aspettare che...dai pochi dati che dai non possiamo certo sapere il risultato.prova ad essere un pò più chiaro.se mai se ci dovesse essere qualche problema nel codice non penso che dovresti risciverlo tutto di sana pianta.utilizza delle variabili intermedie (mw o md) per sapere quale indirizzo stai puntando, controlla ed eventualmente modifica.sbagliando si impara (a non sbagliare più nello stesso punto).
tode72 Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Ho creato una DB con trentuno elementiUNO Array[1..3] of TimeDUE Array[1..3] of Time....TRENTA Array[1..3] of TimePUNTATORE IntL'ultimo elemento mi serve per tener memoria dell'ultima posizione scritta visto che voglio fare una coda circolare. Per l'indirizzamento ho scrittoCALL "TIME_TCK" RET_VAL:=#Tempo L "DB".PUNTATORE L 1 +I T "DB".PUNTATORE .. .. L "DB".PUNTATORE L 96 *I LAR1 AUF "DB" L #Tempo T DBW [AR1,P#0.0] Ovviamente se devo andare a scrivere nel secondo elemento o aggiungo 32 a AR1 o prendo P#4.0 visto che TIME prende 4 B, e 64 per il terzo elementoA questo punto spero che funzioni. Se qualcuno ha già qualche dritta, sono ben accette, altrimenti tra un paio di giorni lo scarico in macchina e vedo se funge e poi vedo il da farsi.
Matteo Montanari Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 nel blocco dati tu hai una struttura di questo tipo:00.0 uno[1] TIME T#0MS 04.0 uno[2] TIME T#0MS 08.0 uno[3] TIME T#0MS 12.0 due[1] TIME T#0MS 16.0 due[2] TIME T#0MS 20.0 due[3] TIME T#0MS o è diverso ancora.non riesco a capire la struttura dal tuo messaggio precedente, e non conoscendo la struttura del blocco dati, non posso verificare se il codice è corretto o meno.
GDA Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Ciao, il tuo metodo il AWL mi sembra il più efficace, comunque se volessi semplificare il codice, questo sarebbe possibile utilizzando SCL, e strutturando il tuo DB in modo che sia un array[1..31] di STRUCT contenenti i 3 dati di tipo TIME. In questo modo potresti indicizzare direttamente l'array con una variabile di tipo INT e scorrerlo tramite un semplice ciclo FOR.
tode72 Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Ho creato una db così fattaIndirizzo Nome tipo 0.0 UNO ARRAY [1..3]*4.0 TIME12.0 DUE ARRAY [1..3]*4.0 TIME............348.0 TRENTA ARRAY[1..3]*4.0 TIME360.0 PUNTATORE INTScusa ma non sono riuscito ad inserire un print screen altrimenti sarei stato più esaustivo.Poi ho usato il tratto di codice già scritto nell'FBQuindi diciamo che è una DB con 31 elementi, trenta dei quali sono degli Array i cui elementi sono di tipo time, el'ultimo elemento del DB è un intero.
Matteo Montanari Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Ciao, il tuo metodo il AWL mi sembra il più efficace, comunque se volessi semplificare il codice, questo sarebbe possibile utilizzando SCL, e strutturando il tuo DB in modo che sia un array[1..31] di STRUCT contenenti i 3 dati di tipo TIME. In questo modo potresti indicizzare direttamente l'array con una variabile di tipo INT e scorrerlo tramite un semplice ciclo FOR.SCL non è un linguaggio "standard" siemens, non fà parte del pacchetto base di programmazione.per questo motivo, oltre che quello economico, non viene molto usato e gli esempi o il codice sono scritti in KOP o AWL.di certo semplificherebbe di molto le cose.
tode72 Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Inoltre non devo fare uno scan di tutto il DB in una volta con un FOR sola, ma solo a fronte di alcune condizioni andare a scrivere sul DB. Potrebbe essere utile in quel caso, ma comunque preferirei fare lo stesso un loop in AWL condizionato dal puntatore
Matteo Montanari Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 carissimo tode72 non ho ancora ben capito cosa vuoi realizzare.con il codice che hai impostato scrivi il valore di tempo (letto con la funzione SFC64) nell'area di dati puntata dal puntatore con un offset di "96".nel primo caso ottieni:1 * 96 = 96 -> in questo caso specifico andersti a scivere la tua doppia word nell'indirizzo 12.0 ... 15.7 (associato a DUE tempo 1 della tua tabella)incrementi il puntatore 1 + 1 = 2e nel secondo caso ottieni:2 * 96 = 192 -> in questo caso specifico andersti a scivere la tua doppia word nell'indirizzo 24.0 ... 27.7 (associato a TRE tempo 1 della tua tabella)incrementi il puntatore 2 + 1 = 3e nel terzo caso ottieni:3 * 96 = 288 -> in questo caso specifico andersti a scivere la tua doppia word nell'indirizzo 36.0 ... 39.7 (associato a QUATTRO tempo 1 della tua tabella)seguendo questo ragionamento andresti a "riempire" tutti i tuoi "tempo 1" della tabella, con vaalori di tempo che praticamente si scostano l'uno dall'altro solamente di un ciclo di scansione.inoltre non scriveresti nulla nella primo (UNO) valore della tua tabella.consiglio, anziche mettereL "DB".PUNTATOREL 96 *I LAR1puoi mettereL "DB".PUNTATOREL 96 *I L 96- ILAR1ma diventa brutto da vedere, in alternativa puoi spostare l'inizio della tua tabella , anzichè dall'indirizzo 0 all'indirizzo 10.
tode72 Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Ciao Keosmmla funzione deve andare a salvare il tempo di inizio, di fine e la sua differenza (la calcolo io e la scrivo nel terzo elemento dell'array) degli ultimi 30 eventi della macchina. Non avevo postato tutto il tratto di codice con le varie condizioni, ma il senso è questoCiclo inizialeInizio puntatore =0Arriva l'evento (se non c'è tale evento salta alla fine)Salvo il tempo di inizio in DB / Array indicato dal puntatoreAttivo un flagCiclo successivoSe l'evento è ancora attivo ma ho il flag salto alla fine (attendo che l'evento smetta)Appena l'evento sparisce, salvo il tempo in DB/Array indicato dal puntatore +32 per ottenere la seconda posizione dell'array (so che devo scrivere lì perché c'è ancora il flag attivo)Calcolo la differenza e la salvo su DB/Array indicato dal puntatore +64 per ottenere la terza posizione dell'arrayresetto il flag e incremento il puntatoreCon le condizioni adatte spero che tutto fili liscio. Mettendo a 0 il puntatore iniziale dovrei scrivere in sequenza negli indirizzi0.012.024.0....e quando il contatore arriva a 31 lo riazzero.la mia domanda comunque rimane quella di sapere se in linea di principio, a parte qualche piccole sbavature, il concetto è esatto o devo trovare un'altra soluzione. TNX
Matteo Montanari Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 il concetto è esatto, potrebbe essere semplificato il codice, come ti ho suggerito nel messaggio precedente, dovresti partire da un indirizzo diverso da "0", utilizzare questo come indirizzo iniziale provoca sempre de problemi (vedi scrittura di più codice). se parti invece da un indirizzamento diverso, hai più possibilità di scrivere parti di codice uguali e lavorare solamente cambiando l'offset.stessa cosa utilizzando a "0" il puntatore, sarebbe più comodo, dal punto di vista di debug che il puntatore con "1" punti al primo dato, non al secondo.attenzione, che utilizzando il punatatore da "0" come fai tu, non devi azzerarlo a 31 (punterebbe l'area del 32mo dato) ma maggiore di 30 (non riesce a puntare l'area del 31mo dato).
tode72 Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Il limite del puntatore lo devo abbassare di sicuro, sorry, errore mio. Proverò a modificarlo secondo tuoi consigli.Grazie mille dell'aiuto
Luca Bab Inserita: 18 maggio 2005 Segnala Inserita: 18 maggio 2005 Forse non ho capito bene il problemama non e' piu' semplice questo?? OPN DB 10L DBB [MD 100]dove MD 100 = numero del byte spostato a sinistra di 3md100 ti fa' da puntatore incrementando di 1 prima lo moltiplichi in base al passo della tua struttura poisposti di 3 ( ultimi 3 bit servono per il numero del bit )ovviamente funzia anche a wordLuca
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