Vai al contenuto
PLC Forum


Registro FIFO della libreria LGF


Cesare Nicola

Messaggi consigliati

Faccio riferimento a questa discussione, in cui ho appreso che esiste un registro FIFO per il 1200:

Sto provando ad utilizzare quel FIFO, giusto per capire come funziona e valutare se e quando fa al caso mio (premetto che sono in grado in grado di costruirmi un FIFO ad hoc, ma sono comunque curioso di provare) . Non capisco, nonostante l'., come utilizzare i parametri di tipo VARIANT "item" e "buffer" (non ho esperienza con i VARIANT). Ho capito che in quelli devo scrivere il valore da inserire o prelevare dal FIFO, ma dove metto tale valore? In un array? Ma in che indice dell'array? Non dovrei, in teoria, fregarmene dell'indice e dire semplicemente al FIFO "aggiungi alla coda un nuovo valore" o "dammi l'ultimo valore della coda"? Se devo gestire io l'indice, a cosa mi serve questo FIFO?
Ho un po' di confusione in testa. :-)


 

Link al commento
Condividi su altri siti


Mi pare che le risposte a queste domande siano già presenti nella precedente discussione.

 

Riguardo al dato di tipo VARIANT, la grande comodità sta nel non legare il registro ad un tipo di dati.
L'array del tuo registro può essere costituito dalle variabili che ti fanno comodo per il tuo particolare lavoro.
Non sei costretto, per esempio, ad utilizzare un array di INT, oppure di REAL, ma puoi anche creare un array di STRUCT.
Insomma, nel tuo FIFO ci puoi mettere dentro tutto quello che vuoi, senza dover modificare la funzione.

 

Anche la faccenda degli indici è già spiegata nella precedente discussione.

Se gestisci il registro nel modo forse ritenuto più classico, quando inserisci un nuovo dato (oppure quando lo estrai, a seconda di come vai a gestire il registro), devi fare uno scroll di tutte le variabili.
Se il registro è lungo, e magari popolato con strutture complesse, questo scroll diventa un compito piuttosto gravoso, che potrebbe, da solo, richiedere anche qualche decina di ms per l'esecuzione completa.

 

La gestione con i due indici permette invece di agire sempre solo su un campo del registro, rendendo il tutto molto più leggero.

In questo momento non sono andato a riguardare la funzione ma, se non ricordo male, la gestione di questi due indici è fatta internamente dalla funzione. Serve solo per sapere dove andare ad inserire un nuovo dato e da dove andare ad estrarre il dato più vecchio. Non devi, salvo tu non lo voglia fare di proposito per motivi particolari, modificare questi indici.
 

Link al commento
Condividi su altri siti

Quote

Anche la faccenda degli indici è già spiegata nella precedente discussione.


Sì, lo so, ma non l'ho capita! :-)
 

Quote

La gestione con i due indici permette invece di agire sempre solo su un campo del registro, rendendo il tutto molto più leggero.

In questo momento non sono andato a riguardare la funzione ma, se non ricordo male, la gestione di questi due indici è fatta internamente dalla funzione. Serve solo per sapere dove andare ad inserire un nuovo dato e da dove andare ad estrarre il dato più vecchio


Cioè, se io passo ai parametri "item" e "buffer" un array, posso stabilire io un indice che sarà sempre quello, in cui leggo e scrivo? Cioè, scrivo in FIFO_array[1] e leggo in FIFO_array[1], per esempio? Proverò. Nel frattempo, per portare comunque avanti il progetto, che di tempo per le prove ahimè non ce n'è mai molto, ho usato un mio FIFO che era già pronto e perfetto per l'applicazione.

Link al commento
Condividi su altri siti

Ho riguardato la funzione, ed è come mi ricordavo.
Tu non ti devi assolutamente occupare degli indici. Le variabili "statFirstItemIndex" e "statNextEmptyItemIndex" sono solo variabili interne della funzione, e sono, rispettivamente, l'indice del dato più vecchio (quello che verrà estratto al prossimo comando di lettura), e l'indice del primo registro libero (dove verrà scritto il dato al prossimo comando di scrittura).
Se fai un reset del registro, questi indici vengono posti rispettivamente a -1 e 0.
Dopo la scrittura del primo dato ti troverai con "statFirstItemIndex" = 0 e "statNextEmptyItemIndex" = 1.

Ad ogni inserimento successivo viene incrementato "statNextEmptyItemIndex", mentre "statFirstItemIndex" non cambia (il primo dato, quello più vecchio, si trova ancora nella locazione 0).
Se leggi dati, "statNextEmptyItemIndex" non viene modificato e viene invece incrementato "statFirstItemIndex" (se ho estratto il dato dalla locazione 0, ora il dato più vecchio si trova nella locazione 1).

Il registro viene gestito non come uno stack (che, come precedentemente scritto, richiederebbe un pesante scroll), ma come un registro circolare. Quando ho scritto nell'ultima locazione, la prossima scrittura verrà fatta nella prima locazione. Il tutto, ovviamene, compatibilmente con lo stato del registro: se è pieno non posso inserire ancora dati, se è vuoto non posso leggere dati. Eventuali errori vengono segnalati nel parametri in uscita "statusID" e "status".
 

Anche questa volta, riguardando la funzione, devo dire che è fatta proprio bene.
La puoi usare con qualsiasi tipo di variabili. L'utilizzo delle variabili VARIANT infatti ti permette di creare il tuo archivio come meglio credi. Non importa se si tratta di un array di INT piuttosto che di REAL, o di un array di STRUCT. Va sempre bene. Ovviamente, "initialValue", "item" e "buffer" devono essere uguali.
Non devi nemmeno passare alla funzione la lunghezza dell'array o altre informazioni, perché si adatta automaticamente.
E degli indici "statNextEmptyItemIndex" e "statNextEmptyItemIndex" non te ne devi assolutamente occupare tu. Tu devi solo impartire i comandi di inserimento o estrazione del dato. La funzione decide dove scrivere il dato e ti darà sempre, il lettura, il dato più vecchio. Ovvero, quello che deve fare una funzione FIFO.

Link al commento
Condividi su altri siti

OK, ci è voluto ancora un po' ma sono riuscito a farlo funzionare. In effetti è utile che accetti in ingresso qualunque tipo di variabile. Mi piacerebbe poter sempre sapere se il buffer è pieno o vuoto, prima dell'operazione di caricamento o prelievo, mentre qui lo sai solo dopo aver fatto un tentativo, leggendo la risposta; non è un grosso problema e comunque dipende dall'applicazione  o da abitudini personali. In allegato un'immagine con qualche chiarimento.
FIFO.thumb.JPG.302e09824962bc91f70970aede1924bd.JPG
 

Link al commento
Condividi su altri siti

Quote

Mi piacerebbe poter sempre sapere se il buffer è pieno o vuoto, prima dell'operazione di caricamento o prelievo, mentre qui lo sai solo dopo aver fatto un tentativo, leggendo la risposta;

Potresti calcolare quanti campi liberi ci sono interrogando le variabili " statNextEmptyItemIndex" e " statFirstItemIndex", e tenendo conto della dimensione dell'array.
Oppure, molto semplicemente, se i due indici sono uguali significa che l'archivio è pieno. Il comando di inserimento di un nuovo dato terminerebbe con errore.

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