Vai al contenuto
PLC Forum


Puntatori, Array Ed Applicazione Un Po Incasinata S7


paolo.francovigh

Messaggi consigliati

paolo.francovigh

Buongiorno a tutti,

non sono molto pratico di array e puntatori ma ora ho un applicazione un po più incasinata del solito.

Ho creato un array[1..20] che si chiama CODA di dati tipo STRUCT

Coda ARRAY[1..20]

STRUCT

CodPrelievo BOOL FALSE Codice prelievo (0=magazzino 1=baia)

NBaiaPrelievo INT 0 Numero della baia per il prelievo

NRullieraPrelievo INT 0 Numero rulliera per il prelievo

CodDeposito BOOL FALSE Codice deposito (0=magazzino 1=baia)

NBaiaDeposito INT 0 Numero della baia per il deposito

NRullieraDeposito INT 0 Numero rulliera per il deposito

TipoPallet BOOL FALSE Tipo di pallet (0=normale 1=grande)

StatoPrelievo INT 0 Stato prelievo (0=da eseguire 1=in corso 2=completato)

StatoDeposito INT 0 Stato deposito (0=da eseguire 1=in corso 2=completato)

END_STRUCT

Poi uso l'SFC20 per fare un BLOCKMOVE:

CALL "BLKMOV"

SRCBLK :="DB30_CODE".Coda[2]

RET_VAL:=MW10

DSTBLK :="DB30_CODE".Coda[3]

Solamente che mi servirebbe indicizzare tramite variabili le posizioni degli array (al posto di [2] e [3]) cosi da fare una funzione di shift ad esempio ricorsiva che sposti la posizione 20 alla 19, la 19 alla 18 e così via.

Qualcuno potrebbe darmi una mano?

Grazie anticipatamente.

Link al commento
Condividi su altri siti


[...] che sposti la posizione 20 alla 19, la 19 alla 18 e così via.

Se sposti la 20 nella 19, e poi la 19 nella 18, e così via, ti diventa tutto uguale... devi procedere in senso contrario.

In ogni caso io non userei il "BLKMOV" ma farei io di mio una funzione ad hoc alla quale passare gli indici che mi servono.

(non so neanche se strutturerei i dati in quel modo, ma non è una cosa che posso decidere senza sapere i dettagli dell'applicazione)

ciao

Link al commento
Condividi su altri siti

paolo.francovigh

Ciao, per il discorso dello shift è chiaro che sposterò i dati da una posizione N ad una posizione N+1 o N-1 libera, in modo da non sovrascrivere o perdere dati.

Quello che mi preme sapere, indipendentemente dallo shift, è come dire al BLKMV di prendere i dati nella posizione con indice 2 e spostarla in quella con indice 3 ma non scrivendo 2-3 ma prendendo i valori da una variabile. In questo modo farei:

CALL "BLKMOV"

SRCBLK :="DB30_CODE".Coda[XXXX]

RET_VAL:=MW10

DSTBLK :="DB30_CODE".Coda[YYYY]

E farei ripetere N volte il CALL incrementando o riducendo di 1 le variabili XXXX e YYYY ad ogni ciclo.

Modificato: da paolo.francovigh
Link al commento
Condividi su altri siti

Se ho ben capito vuoi indicizzare i parametri relativi al blockmove per lanciare la funzione ogni qualvolta devi aggiornare il tracking....

Prova questo:

//***********************

LAR1 P##X_Sorgente // Parameter assignment ANY

//***********************

L W#16#1002 // ID code & type

T LW [AR1,P#0.0]

L 3238 // Nr. bytes

T LW [AR1,P#2.0]

L #dbso // Nr. DB100 sorgente

T LW [AR1,P#4.0]

L 0 // From DW number

SLD 3

OD DW#16#84000000

T LD [AR1,P#6.0]

//***************************

LAR1 P##Y_Destinatario // Parameter assignment ANY

//***************************

L W#16#1002 // ID code & type

T LW [AR1,P#0.0]

L 3238 // Nr. bytes

T LW [AR1,P#2.0]

L #dbde // Nr. DB destination = DB 501

T LW [AR1,P#4.0]

L 0 // To DW number

SLD 3

OD DW#16#84000000

T LD [AR1,P#6.0]

CALL "BLKMOV" // SFC20 DATA_BLOCK_MOVE

SRCBLK :=#X_Sorgente

RET_VAL:=#return

DSTBLK :=#Y_Destinatario

in questo esempio il numero di bytes è fisso, ma può essere cambiato, i parametri "dbso" e "dbde" sono gli indici della db sorgente e destinatario e sono parametri in ingresso della FC.

i parametri X_Sorgente e Y_Destinatario sono invece dichiarati nell'intestazione della FC nella zona TEMP e sono dichiarati come tipo "any"

buon divertimento

pigroplc

Link al commento
Condividi su altri siti

Prova anche a farti un blocco come questo :

IN

DB_Origine Word

DB_Destinazione Word

Primo_Byte_Origine Dword

Primo_Byte_Destinazione Dword

Nr_Bytes Word

OUT

Ret_Val Int

TEMP

Sorgente Any

Destinazione Any

LAR1 P##Sorgente //carica l'indiririzzo iniziale del puntatore sorgente in AR1

L B#16#10 //carica l'ID di sintassi e trasferiscilo nel

T LB [AR1,P#0.0] //byte 0 del puntatore Sorgente

L B#16#2 //carica il tipo di dati"Byte"e trasferiscilo

T LB [AR1,P#1.0] //nel byte 1

L #Nr_Bytes //carica Nr.bytes da trasferire e trasferiscilo

T LW [AR1,P#2.0] //nella word 2

L #DB_Origine //carica Nr.DB Origine e trasferiscilo

T LW [AR1,P#4.0] //nella word 4

L #Primo_Byte_Origine //carica Nr.del primo byte da trasferire e

SLD 3 //traferiscilo adattato

T LD [AR1,P#6.0] //nella dword 6

L B#16#84 //carica il codice di area di memoria

T LB [AR1,P#6.0] //trasferiscilo su byte 6

// DESTINAZIONE

LAR1 P##Destinazione //carica l'indiririzzo iniziale del puntatore destinazione in AR1

L B#16#10 //carica l'ID di sintassi e trasferiscilo nel

T LB [AR1,P#0.0] //byte 0 del puntatore Destinazione

L B#16#2 //carica il tipo di dati"Byte"e trasferiscilo

T LB [AR1,P#1.0] //nel byte 1

L #Nr_Bytes //carica Nr.bytes da trasferire e trasferiscilo

T LW [AR1,P#2.0] //nella word 2

L #DB_Destinazione //carica Nr.DB Destinazione e trasferiscilo

T LW [AR1,P#4.0] //nella word 4

L #Primo_Byte_Destinazione //carica Nr.del primo byte da trasferire e

SLD 3 //traferiscilo adattato

T LD [AR1,P#6.0] //nella dword 6

L B#16#84 //carica il codice di area di memoria

T LB [AR1,P#6.0] //trasferiscilo su byte 6

// RICHIAMO SFC20

CALL SFC 20

SRCBLK :=#Sorgente

RET_VAL:=#Ret_Val

DSTBLK :=#Destinazione

In questo modo quando richiami il tuo blocco hai tutto parametrizzato , metti in ingrsso dove ti chiede il primo byte il valore in MD

se per esempio hai 10 pacchetti di 30 dbw l'una

ti fai un puntatore che conte da 1 a 10

e te lo moltiplichi 30 per puntare nella zona giusta ,

fai il tuo spostamento ,

controlli se puntatore = 10 ( se si finito )

add 1 al puntatore

salti indietro sino a che il puntatore ti arriva a 10

La stessa cosa te la puoi fare facendo 1 db per ogni pacchetto

e copiarti direttamente le db ( con parametro solo in db sorgente e in db destinazione )

Ciao

Luca

Link al commento
Condividi su altri siti

Se ho capito bene vuoi fare un FIFO di 20 posizioni con la tua struttura. E quando hai un evento devi aggiungere le informazioni al prossimo array.

Perche' invece di spostare i dati della tua struttura (da [20] a [19], per esempio) non cambi solo il puntatore? Cerco di spiegarmi meglio. All'evento x metti i dati nell'array [1], al seguente evento li metterai nell'array [2], poi [3] e cosi' via, senza dover spostare tutti i dati.

Link al commento
Condividi su altri siti

paolo.francovigh

Ma non esiste un metodo più semplice far si che il numero che rappresenta la posizione dell'array sia una variabile?

Invece di scrivere:

CALL "BLKMOV"

SRCBLK :="DB30_CODE".Coda[2]

RET_VAL:=MW10

DSTBLK :="DB30_CODE".Coda[3]

Vorrei poter scrivere:

CALL "BLKMOV"

SRCBLK :="DB30_CODE".Coda[MW10]

RET_VAL:=MW10

DSTBLK :="DB30_CODE".Coda[MW20]

Link al commento
Condividi su altri siti

paolo.francovigh

X Ron the Bon

La tua idea è buona, però la mia coda FIFO deve poter essere editata, cioè poter spostare la posizione 10, ad esempio, in posizione 2 e viceversa e deve essere possibile cancellare un elemento dalla coda e ricompattare il tutto. Per fare tutto questo il tutto deve essere rappresentato su pannello operatore.

Siccome il BLKMV funziona bene spostandomi gli elementi dell'array, volevo solamente richiamare per N volte l'SFC20 passandogli le accoppiate 1-2, poi 2-3, poi 3-4 e così via.

Modificato: da paolo.francovigh
Link al commento
Condividi su altri siti

Ma non esiste un metodo più semplice far si che il numero che rappresenta la posizione dell'array sia una variabile?

Non credo ( ma mi piacerebbe essere smentito ) poiche' "DB30_CODE".Coda[2] e' simbolico , non e' assoluto

P#DB30.DBX0.0 BYTE 28 questo invece e' assoluto e parametrizzabile

ciao

Luca

Link al commento
Condividi su altri siti

paolo.francovigh

Le aree iniziali dei db del mio array vanno di 18 in 18 byte, potrei quindi lavorare incrementando di 18 (invece che 1) e lavorare con l'indirizzamento P#DB30.DBX0.0.

Siccome al BLKMV devo passare il P#DB30.DBX0.0 come faccio ad incrementarlo di 18 prima del BLKMV in modo che sia P#DB30.DBX18.0 ?

Link al commento
Condividi su altri siti

Felice_Boccia

Vai su . di Step 7 "Argomanti della guida",cerca :

Impiego del tipo di parametri Any

Troverai un'esempio che puoi usare per la tua applicazione, l'esempio carica 10 byte dalla DB22 Byte 11 alla DB33 Byte 202.

Prendi l'esempio modifica la lunghezza delle byte da spostare da 10 a 18, modifica la Db Sorgente e la Db di Destinazione DB30,

ti crei un puntatore indice_partenza, dove legge il puntatore DBX11.0 sostituisci con la P#indice_partenza,

ti crei un puntatore indice_arrivo, dove legge il puntatore DBX202.0 sostituisci con la P#indice_arrivo.

Dovrebbe funzionare. Ciao

Link al commento
Condividi su altri siti

come faccio ad incrementarlo di 18 prima del BLKMV in modo che sia P#DB30.DBX18.0 ?

non capisco bene il problema ?? ADD 18 ???

io solitamente lavoro con un puntatore da 1 a 10 ( se hai 10 pacchetti ) poi moltiplico per il passo ( 18 ) poi moltiplico per 8 ( o sposto 3 a sinistra )

DBX18.0 = DBX (18x8 + 0 ) metti 144 in MD200 = DBX[MD200]

Ciao

Luca

Link al commento
Condividi su altri siti

Ciao,

Non ho letto tutte le risposte precedenti perchè ho fretta, io una cosa del genere l'ho fatta con la funzione CopyDataBlock1 siemens, chiamata anche DB_COPY1.

Il parametro QANF è il dato da dove si inizia a scrivere, può essere un intero.

Copiavo i parametri da una DB con un solo set di dati ad una con N set di dati.

Link al commento
Condividi su altri siti

paolo.francovigh

Ho fatto come da indicazioni di Felice Boccia ed altri prima che mi hanno consigliato, il tutto funziona, posso tranquillamente spostare i blocchi all'interno delle code e quindi gestirle un po come voglio indicizzando le zone all'interno dell'array.

Quello che ho imparato dai vostri consigli è stato sopratutto sull'uso del parametro ANY che non avevo mai usato e diventa un ottimo strumento unito ai puntatori.

Vi ringrazio tutti per il supporto che mi avete dato, debbo dire che la comunità di PLC Forum è molto preparata e disponibile ;)

Paolo.

Link al commento
Condividi su altri siti

  • 1 year later...

salve a tutti...su alcuni post ho letto che tra fase e terra vi deve essre 220v...in un impianto di videosorveglianza ho meso un alimentatore stabilizzato da 5a,ed ho collegato giustamente fase neutro e terra..

appena attacco la terra sul morsetto dell alimentatore ,l alimentatore va in isolamento...ho testato fase e terra 220v......neutro e terra 0v.....fase e neutro 220v

Link al commento
Condividi su altri siti

ciao mauro ,tu dici di staccare tutte le alimentazioni delle delle telecamere,non questo non lo provato,ma se fosse questo l problema cosa potrebbe essere?da premettere che l impianto funzionava bene sin quando su quel appartamento si e verificato un problema con l impianto ce aveva fatto l elettricista(tutto ad un tratto le lampade ad incandecenza apparivano piu luminose sinoalla fulminazione,e bruciato anche l ex alimentatore ....

Link al commento
Condividi su altri siti

A me' e' successo che una telecamera si era bruciata mandando di conseguenza il positivo a massa... ti conviene provare a staccare il carico

Link al commento
Condividi su altri siti

i casi sono due: o il positivo in uscita e' a massa , quindi se attacchi la terra alla calza ( negativo) provoca un corto con conseguente blocco dell'alimentatore ,

oppure e' l'alimentatore che e' difettoso internamente ( pero' e' strano un caso simile)

ivano65

Link al commento
Condividi su altri siti

si ivano la causa deve essere una delle 2 opzioni da te citate....ma all inzio questo impianto funzionava anche con a terra attacata all alimentatore,sin quando su quest appartamento e successo un guasto elettrico del tipo lampade ad incandescenza che tutto ad un tratto spravano alimentatore del videoctofono che si bruciava(compreso il mio,che poi ho sostituito con uno nuovo)dopo di che si e presentato il problema in questione....ma pero di risolverlo.....

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