Vai al contenuto
PLC Forum


Snap7 E Lettura Dword


Messaggi consigliati

Buongiorno a tutti!
Ho recentemente scoperto la libreria snap7 e vorrei fare i complimenti all'autore per l'ottimo lavoro!

Sto facendo delle prove utilizzandola con VB2010.
Avrei un dubbio che provando a leggere il manuale e facendo delle prove non sono riuscito a togliermi e che sintetizzo facendo un esempio:
se voglio leggere il valore di DB3.dbd85 posso:
Dim Buffer(1024) As Byte
risultato = Client.DBRead(3, 85, 4, Buffer)
Ottenendo i 4 byte che poi vado successivamente a sommare nel programma.

Esiste un modo per ottenere direttamente una variabile in formato doppia word con il contenuto di DB3.dbd85?

Mi sembra che potrei usare:
risultato=Client.ReadArea(S7AreaDB,3,85,2,S7WLDWord,buffer)
Ma non funziona...

Grazie!!

Link al commento
Condividi su altri siti


Ciao,

se non ti funziona, "risultato" dovrebbe contenere l'errore, che può aiutarti a capire cosa è successo.

Inoltre, se invece di passare alla DBRead un array di Byte, gli passi l'indirizzo di un intero a 32 bit, avrai direttamente la tua variabile (almeno, in C si comporta così).

Infine ricordati che i byte della DWORD saranno invertiti (swap).

Link al commento
Condividi su altri siti

Grazie per la risposta!

Allora, quando eseguo la lettura Visual Basic esce dal debug e non viene caricato nulla in "risultato"

Per quanto riguarda il dimensionamento dell'array se dichiaro:

Dim Buffer As Integer

ottengo subito l'errore:

Impossibile convertire il valore di tipo 'Matrice a 1 dimensioni di Integer' in 'Matrice a 1 dimensioni di Byte' perché 'Integer' non è derivato da 'Byte'.

La funzione sembra accettare solo un array in byte! (ma forse sbaglio :smile: )

Per quanto riguarda l'inversione pensavo di usare: longword SwapLongword(longword lwValue)
Domani faccio altre prove!

Grazie

Link al commento
Condividi su altri siti

Non ho mai usato VB2010, quindi so poco del suo funzionamento: in C, in caso di errore, il valore c'è e ti assicuro che aiuta, altrimenti torna 0; certo è che, se torna sempre 0, anche in caso di errore, diventa difficile gestire gli eventuali errori che possono accadere.

Non ho usato finora la funzione ReadArea(), ma l'unica cosa che mi viene in mente è provare a ridurre a 1 il parametro Amount della funzione (il quarto parametro): non vorrei che con "Amount of word to read" Davide intendesse la quantità di dati definiti con Wordlen (il parametro successivo), quindi se devi leggere una DWORD ci vorrebbe 1; con 2, puo' andare oltre le dimensioni del DB, visto che il dato magari non esiste, e ti torna un errore (o almeno dovrebbe).

Per la funzione DBRead(): è definita come int DBRead(int DBNumber, int Start, int Size, void *pUsrData); quindi pUsrData è un puntatore a void (quindi un puntatore universale); quando l'ho usata io l'ho chiamata con DBRead(150, 168, 2, &m_wStationsResults); legge dalla DB150, partendo dal dato 168, legge 2 byte e li inserisce nella WORD m_wStationsResults e con & gli passo l'indirizzo della variabile; se gli passi il nome di un array, automaticamente gli passi l'indirizzo dell'array.

Se non erro, in Basic per passare un puntatore ad una funzione si utilizza l'operatore ByVal: verifica nella documentazione che non abbia affermato una castroneria.

Per l'inversione la funzione SwapLongword(), che ho utilizzato anch'io, è quella corretta per un dato DWORD.

Link al commento
Condividi su altri siti

Ciao,

lavorare con array di byte permette di non usare i puntatori in ambienti managed come .net e java. Lo svantaggio è che devi inserire o estrarre i dati nell'array, cosa comunque abbastanza semplice.

Inoltre anche se lavori in C++ o Delphi devi comunque invertire l'ordine dei byte (nel caso di 4 bytes come dword devi scambiare il primo con il quarto ed il secondo con il terzo), essendo il PLC big-endian.

In Moka7, il port full java di Snap7 (lo scarichi dallo stesso repository di snap7) c'è la classe S7 (in S7.java) che permette di inserire ed estrarre qualunque tipoo di variabile (bit,word float, datetime ecc..) su un array di byte. La sintassi è davvero molto simile al C#.

Credo che nella prossima versione di snap7 la inserisco nel wrapper .net, non lo immaginavo, ma ho avuto letteralmente decine di richieste su come estrarre i dati da un array.

[at]drugo66

E' giusto, "Amount" indica la quantità di items, quando mi riferisco alla dimensione in bytes uso "Size". ;)

Davide

Link al commento
Condividi su altri siti

lavorare con array di byte permette di non usare i puntatori in ambienti managed come .net e java. Lo svantaggio è che devi inserire o estrarre i dati nell'array, cosa comunque abbastanza semplice.

ok, io penso porti ad avere piu' controllo e quindi nel caso permetta cose particolari (maschere o filtri) ma da un altro punto di vista, funzioni (pappapronta :smile: ) tipo "daveGetFloat" rendano piu' leggibile e immediato il codice.

Credo che nella prossima versione di snap7 la inserisco nel wrapper .net

Bene! :clap:

Complimenti ancora per il tuo lavoro!

[at] drugo66

Grazie dei suggerimenti, ci sto lavorando!!

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