Vai al contenuto
PLC Forum


Lettura Blocco Dati Da Pc - Lettura di un blocco dati (DB) del PLC da PC...


Messaggi consigliati

Inserito:

Ciao A tutti..... :)

Sono alle prese con un problema....

Sto sviluppando un applicativo in VC++ (microsoft).....

Vorrei poter leggere una DB del PLC (S7-300) collegato al PC in profibus con CP5611.....

Sto utilizzando come interfaccia un oggetto COM OPC (della Siemens ovviamente)...

Non sono riuscito a scovare da nessuna parte un esempio oppure una speigazione di come leggere un blocco di dati (es DB1,B0,20) non una singola variabile....

Per non annoiarvi troppo.......la faccio breve....

Il problema è che mi sembra assurdo che non risca ad ottenere dall'OPC

un array di bytes così come si trovano nel PLC ...

Magari, se qualche anima buona, volesse anche spiegarmi come scrivere un blocco di dati (es 20 bytes della DB1) sarei infinitamente grato.... :D

Ciao ancora a tutti...... Ringrazio anticipatamente per la risposta...... (sperando ci possa essere una risposta) :unsure: .


Inserita: (modificato)

Salve Paolo10 ,

Se il PC non era molto distante, un approccio PRODAVE MPI risultava piu' economico e meno

impegnativo.

Comunque,

Non sono riuscito a scovare da nessuna parte un esempio oppure una speigazione di come leggere un blocco di dati

Ma se ci sono sul CD ROM. <_<

Per non annoiarvi troppo.......la faccio breve....

Il problema è che mi sembra assurdo che non risca ad ottenere dall'OPC

un array di bytes così come si trovano nel PLC ...

Allora riesci a communicare ma e' il formato delle variabili che non ti risulta ?

L'item data ricevuta dal suo OPCHANDLE la ci devi appoggiare su di una VARIANT data type derivata dalla classe COleVariant.

// costruzione oggetto
COleVariant objectVariant(TAGS*values);   
// Usi la function ChangeType per formatare il valore della variabile puntata da *values in WORD 
// oppure DWORD
objectVariant.ChangeType(VT_I2); oppure objectVariant.ChangeType(VT_I4);
// formata la stringa col valore ricevuto
CString strValue(_T(""));
strValue.Format(_T("0x%02X"), objectVariant.lVal); // 2 Bytes

................

Ciao. B)

Modificato: da Savino
Inserita:

Ciao Savino....

Prima di tutto molte grazie per avermi risposto..... :)

In riferimento alla mia precedente domanda, scusami, forse mi sono spiegato male..... :(

Ho visto anch'io diversi esempi che dimostrano come poter leggere/scrivere singoli dati dal PLC.....

Il problema mio (se risolvibile) è che vorrei con una sola chiamata leggere, per esempio, una intera DB del PLC (per esempio DB1,B0,20 -> 20 bytes della DB1 a partire dall'offset 0).

Cioè in altre parole, vorrei poter leggere una array di dati per esempio 20 bytes ed ottenerli dall'OPC Server come si trovano nella DB del PLC.

In realtà ho provato un esperimento di "quasi successo" utilizzando come tipo di variant VT_BSTR....

però mi ritorna una stringa già convertita in ASCII in decimale del tipo : "{0|0|23|45|67...0|}"

Quindi per ottenere un array nel PC analogo alla DB del PLC devo fare la conversione al contrario....

Inoltre se sottopongo lo stesso dato all'opc server per la scrittura, il tipo di dato non viene accettato !! :huh:

Quindi il mio problema è solo che vorrei sapere se si può fare una "copia fisica" della DB del PLC in un array di bytes nel PC.

Anche nel tuo esempio, leggi un solo dato, ma possibile che non si possa leggere o scrivere un insieme (blocco) di dati con un solo accesso all'interfaccia COM OPC per ottenre una array con tutti i dati (bytes) della DB del PLC ?

Grazie ancora per la risposta. :rolleyes:

Ciao a tutti.......

Inserita: (modificato)

Ciao,

Cioè in altre parole, vorrei poter leggere una array di dati per esempio 20 bytes ed ottenerli dall'OPC Server come si trovano nella DB del PLC

supponiamo che la asyncronic Read func. handled dal OPC connection abbia un forma :

IOPCAsyncIO::Read

HRESULT Read(
    [in] DWORD dwConnection,
    [in] OPCDATASOURCE dwSource,//The data source; OPC_DS_CACHE or OPC_DS_DEVICE 
    [in] DWORD dwCount,                // Number of items to be read.
    [in, size_is(dwCount)] OPCHANDLE * phServer,
    [out] DWORD *pTransactionID,
    [out, size_is(,dwCount)] HRESULT ** ppErrors
    );

In realtà ho provato un esperimento di "quasi successo" utilizzando come tipo di variant VT_BSTR....

però mi ritorna una stringa già convertita in ASCII in decimale del tipo : "{0|0|23|45|67...0|}"

Allora converte da ASCII 1 carattere=1 byte.

Ti converrebbe usare un tipo di data Union di 1 unsigned int, 2 char e un campo bit di 16 elementi,

come contenitori data ( 16 bits) from PLC.

Poi S7 byte basso = intel byte alto e via dicendo ................

Good night. B)

Modificato: da Savino
Inserita: (modificato)
Ti converrebbe usare un tipo di data Union di 1 unsigned int, 2 char e un campo bit di 16 elementi,

come contenitori data ( 16 bits) from PLC.

Sorry, :o

Union di 1 signed int, 2 char e un campo bit di 16 elementi, piuttosto.Intervallo -32768/+32767

Saluto. B)

Modificato: da Savino
Inserita:

Ciao Savino.... :D

Ti devo ancora ringraziare per la tua cortesia (a dire il vero ci speravo molto.....) :)

Purtroppo però non sono riuscito a spiegarmi . . . . .

non devo leggere 16 bits.... (union ecc.....)

ma vorerei leggere per esempio 100 bytes (ovviamente contigui e dalla stessa DB del PLC)...

Quindi dovrei riuscire a capire come fare per leggere oppure scrivere un <blocco di dati di questa dimensione> in un solo colpo di queste dimensioni.....

Qualsiasi esempio o consiglio è molto ben accetto......

Questa cosa (cioè la lettura di un blocco di dati), che era quasi banale con le SAPI S7 (non più supportate da Siemens), sembra impossibile utilizzando il sistema OPC ...... o meglio non riesco a capire come fare....

Però, Savino, anche dalle tue risposte mi pare evidente che non sia così banale la cosa....o forse non sono riuscito a spiegarmi bene (spero sia così :rolleyes: ).

Ciao.... :wacko:

Spero di rileggere presto un tuo commento.....

Grazie per il supporto... e la sopportazione.... :)

Inserita:

Ciao Paolo10,

Spero di rileggere presto un tuo commento.....

Purtroppo non riesco a risponderti adesso.Vedro' sta sera, sul tardi, cosa posso fare. :rolleyes:

Comunque, nel fra tempo potresti postare od inviarmi qualche info in piu' come ad

esempio quale metodo OPC stai utilizando per leggere o scrivere le varialbili. <_<

Saluto.

Inserita:

Ciao Savino ancora 1000000 di grazie per l'interessamento alla mia questione ....

Hai un PM :D ! ! !

Se ritieni opportuno lo puoi publicare..... ma mi sembra troppo specifico e di poco interesse per eventuali altri utenti...

Ciao....

Inserita: (modificato)

Salve Paolo,

Dunque,

Cominciamo a vedere di riuscire a leggere asincronicamente la prima DB.

Formato del metodo:
IOPCAsyncIO2::Read
HRESULT Read(
    [in] DWORD dwCount,  //Number of items to be read
    [in, size_is(dwCount)] OPCHANDLE * phServer,// Array of server item handles of the items to be 
    [in] DWORD dwTransactionID,                         // read
    [out] DWORD *pdwCancelID,
    [out, size_is(,dwCount)] HRESULT ** ppErrors
    );
IMPORTANTE: IERI HO POSTATO IL FORMATO SVAGLIATO PER IL METODO .QUELLA ERA LA FORMA PARA LA LETTURA SINCRONICA. :o SORRY , LA FRETTA :(
Cioè in altre parole, vorrei poter leggere una array di dati per esempio 20 bytes ed ottenerli dall'OPC Server come si trovano nella DB del PLC.
Bene allora dwCount=20;
Poi, in
 m_Items[0].vtRequestedDataType = vtDataTypeItem0; // = VT_BSTR
al posto di VT_BSTR piuttosto scrivi VT_I2 ( formato 2 bytes cioe' word, no formato stringa), quindi
vtDataTypeItem0=VT_I2;
Per ultimo, Lettura data ricevuta dal handle OPCHANDLE * phServer Poi, se costruiamo una struttura array Union tra 10 words e 20 bytes
union reg_16bits
{signed int w_16;
char b_16[2];
 }; 
union reg_16bits m_DB1[21];

m_DB1[0].b_16[1]=phServer[0]; // m_DB1[0].b_16[1]=*phServer;          medesimo
m_DB1[0].b_16[0]=phServer[1]; // m_DB1[0].b_16[0]=*(phServer+1);
m_DB1[1].b_16[1]=phServer[2]; ............
m_DB1[1].b_16[0]=phServer[3];
........................

e cosi via fino il byte [20].

Poi, m_DB1[0].w_16 = e' la DB1.dbw0 in S7  e via elencando fino alla word 10.

B)

Prova aggiornare il codice con queste modifiche, ci sentiamo domani. ;)

good night. :)

Modificato: da Savino

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