Paolo10 Inserito: 16 gennaio 2006 Segnala Inserito: 16 gennaio 2006 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'OPCun 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.... Ciao ancora a tutti...... Ringrazio anticipatamente per la risposta...... (sperando ci possa essere una risposta) .
Savino Inserita: 16 gennaio 2006 Segnala Inserita: 16 gennaio 2006 (modificato) Salve Paolo10 ,Se il PC non era molto distante, un approccio PRODAVE MPI risultava piu' economico e menoimpegnativo.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'OPCun 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. Modificato: 16 gennaio 2006 da Savino
Paolo10 Inserita: 17 gennaio 2006 Autore Segnala Inserita: 17 gennaio 2006 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 !! 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. Ciao a tutti.......
Savino Inserita: 18 gennaio 2006 Segnala Inserita: 18 gennaio 2006 (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 PLCsupponiamo 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. Modificato: 18 gennaio 2006 da Savino
Savino Inserita: 18 gennaio 2006 Segnala Inserita: 18 gennaio 2006 (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, Union di 1 signed int, 2 char e un campo bit di 16 elementi, piuttosto.Intervallo -32768/+32767Saluto. Modificato: 18 gennaio 2006 da Savino
Paolo10 Inserita: 18 gennaio 2006 Autore Segnala Inserita: 18 gennaio 2006 Ciao Savino.... 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ì ).Ciao.... Spero di rileggere presto un tuo commento.....Grazie per il supporto... e la sopportazione....
Savino Inserita: 18 gennaio 2006 Segnala Inserita: 18 gennaio 2006 Ciao Paolo10,Spero di rileggere presto un tuo commento.....Purtroppo non riesco a risponderti adesso.Vedro' sta sera, sul tardi, cosa posso fare. Comunque, nel fra tempo potresti postare od inviarmi qualche info in piu' come adesempio quale metodo OPC stai utilizando per leggere o scrivere le varialbili. Saluto.
Paolo10 Inserita: 18 gennaio 2006 Autore Segnala Inserita: 18 gennaio 2006 Ciao Savino ancora 1000000 di grazie per l'interessamento alla mia questione ....Hai un PM ! ! !Se ritieni opportuno lo puoi publicare..... ma mi sembra troppo specifico e di poco interesse per eventuali altri utenti...Ciao....
Savino Inserita: 19 gennaio 2006 Segnala Inserita: 19 gennaio 2006 (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. 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. Prova aggiornare il codice con queste modifiche, ci sentiamo domani. good night. Modificato: 19 gennaio 2006 da Savino
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