Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Opc Server E Automation Interface - timeout nella syncread


Messaggi consigliati

Inserito:

Ciao a tutti,

Da poco ho iniziato a sviluppare un applicativo per comunicare verso S7-300 usando OPC server (Simatic NET 6.3), e devo dire funziona egregiamente.

L'applicazione è fatta in VB6 e utilizza l'automation interface (syncread e syncwrite)per leggere e scrivere e fin qui tutto bene.

Ho notato però che spegnendo il PLC o staccando il cavo, il timeout sulla lettura è LUNGHISSIMO circa 10 sec :o

Il tipo della hotline che ho chiamato dice che questo timeout non è settabile in nessun modo, e per assurdo non è nemmeno possibile leggere una life-list degli AG collagi in modo da evitare di leggere quelli spenti.

Qualcuno di vuoi ha qualche buona idea ?

Grazie :)


Inserita: (modificato)

Premetto che sono alle prime armi con OPC, però cerco comunque di aiutarti. Se ricordo bene VB6 non permette la programmazione multithreading... altrimenti potresti mettere la syncread in un thread separato ed eseguirlo con un timeout deciso da te... è un'operazione un po' macchinosa, è vero, ma in questo modo aggireresti il problema.

Mi viene in mente anche un'alternativa: sempre se non ricordo male, oltre alla syncread c'è anche una funzione per la lettura asincrona, giusto? Dovrebbe chiamarsi asyncread. Leggendo i dati in modo asincrono non hai il blocco del tuo programma per 10 secondi... ovviamente con la lettura asincrona ti complichi la vita, però non sempre riusciamo ad avere botte piena e moglie ubriaca.

Alternative migliori non mi vengono in mente... buon lavoro!

Domenico.

Modificato: da IMM-Domenico
Inserita:

Ciao Domenico e grazie per la risposta.

In effetti anche io ho pensato la stessa, la asyncread non blocca il programma ma stravolge un po la struttura dell'applicazione :( ( cosa che vorrei evitare).

Spulciando però nelle proprietà dell' OPCGruop ho scoperto che esiste un OPCgroup.IsActive.

Il manuale dice testualmente "Specifies the active status of the group. Make sure you set IsActive to true if you want to monitor the variables of this group" sembrerebbe quindi un valore del settare da programma, sarebbe davvero utile che invece questo valore indicasse la connessione attiva del OPCgroup.

Non è che per caso lo hai provato ?

Grazie

Inserita:

No, purtroppo per il momento non ho modo di provare... probabilmente inizierò a sviluppare con OPC dalla prossima settimana, però il manuale sembra inesorabilmente chiaro.

Fammi sapere come ne esci fuori, sono curioso.

Buon lavoro!

Inserita: (modificato)

Ciao Domenico,

Nel frattempo non mi sono dato per vinto e ho rotto le scatole ad un po di gente che mastica OPC più di me, con risultati sorprendentemente positivi :D ...... ti racconto in breve.

Il vero problema sta nel fatto che OPC, purtroppo, non fornisce una life-list degli AG in linea, almeno usando S7 come protocollo (per gli altri protocolli non saprei).

In compenso però, per ogni gruppo di item che definisci, è in grado di generare un evento "datachanged" ogni qualvolta i dati del gruppo cambiano e ... udite, udite, anche quando cambia lo stato della connessione relativa al gruppo ;)

L'uso di questo evento, che fa parte del set di eventi generati usando le chiamate asincrone, però non ti vincola all'uso delle chiamate asincrone, mi spiego meglio....

Poi definire un gruppo di items in modo che generi eventi ( .IsSubscribed = true e .IsActive = true ecco a cosa serve il parametro) , ma nulla vieta che all'interno dell'applicazione tu possa continuare a lavorare in modalità sincrona usando la syncread e syncwrite, entrambe le modalità posso coesistere.

A questo punto, è comodo continuare le operazioni di lettura e scrittura in modalità sincrona (che è moooolto piu semplice) e gestire l'evento in modo da testare solo il cambio di stato del collegamento. :D

A quanto pare si può avere botte piena e moglie ubriaca .... o quasi.

P.S. Devo dire che però è davvero deludente il fatto che uno strumento cosi potente come OPC non possa disporre di un semplice flag che indichi lo stato dell' AG attivo/non attivo .... vabbè pazienza.

Modificato: da Ltony
Inserita:

Grande!

Complimenti, mi sembra una soluzione molto elegante. Sapevo dell'evento datachanged, ma non sapevo che fornisse anche informazioni riguardo lo stato. Interessante!

Buon proseguimento!

Domenico.

Inserita:

buona sera a tutti !!!

sto' cercando di entrare pure io nel mondo dell'OPCserver...da circa due mesi ho comperato PC access;

ho un grande problema: Il manuale fa riferimento ad un client progettato con VB6 mentre io ho vb.net 2003 ; IL problema sono le matrici che in vb.net sono gestite in maniera diversa...... Non so' se passare al vb6

cosa mi consigliate??

Inserita:

Premesso che purtroppo non conosco PC access, io continuo ad usare VB6 specialmente, per applicazioni di produzione.

Non sarà alla moda, ma chi se ne frega.

La sua stabilità è ormai consolidata ed è sempre meglio evitare sorprese ( credo non sia un caso che il manuale faccia riferimento a quello).

Se poi come dici, sei anche alle prime armi con OPC credo sia davvero il caso di fare un esperimento per volta.

Io ormai sto cercando di infangarmi con .NET da qualche mese .... e credimi, ormai ho esaurito le imprecazioni con l'amico Bill Gates :D

Buona fortuna

Inserita:

Salve,

Ho notato però che spegnendo il PLC o staccando il cavo, il timeout sulla lettura è LUNGHISSIMO circa 10 sec

Mi sembra strano 10 sec.Dovrebbe essere quasi istantaneo, almeno per le APIs client sviluppate in VC++, quale e' il linguaggio piu' addatto per questo genere d'implementazioni.

BOOL MyClass::ConnectServer()
{
    HRESULT hr;
    CLSID clsid;


  hr = ::CLSIDFromProgID(PROGID_SERVER, &clsid);

    if (FAILED(hr))
    {
  HandleError(_T("Unable to get the server ID"), hr);
  return FALSE;
    }

    // Try a connection and get a ptr on the main server interface
    hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IOPCServer,  
                          (LPVOID*)&m_IOPCServer);
    if (FAILED(hr))
    {
  HandleError(_T("Unable to connect to the server"), hr);
  return FALSE;
    }

    //everything is OK
    return TRUE;
}

La funzione ConnectServer() prova ottenere una conessione con la main server interface tramite CoCreateInstance....., se non ci riesce perche la linea e' down ritorna subito in errore ( ne anche 1 secondo).

Forse il tuo codice fa qualche altro giro estrano...... ; <_<

Lo so, VB non e' il massimo per questo genere d'implementazione e quindi....

P.S. Devo dire che però è davvero deludente il fatto che uno strumento cosi potente come OPC non possa disporre di un semplice flag che indichi lo stato dell' AG attivo/non attivo .... vabbè pazienza.

Perche' dovrebbe....

Teoricamente,OPC e' uno standard e quindi la DLL della Schneider doveva andare bene per il Siemens e viceverza, ma in prattica questo non e' vero, visto

che c'e' sempre qualche virgola che non quadra, allora niente riferimenti personalizzati.

Una soluzione, potrebbe essere di ricchiamare il SFB 22 "STATUS"nel PLC ed appogiare i valori di ritorno su dei flags, per dopo andare a leggerli con l'API clinet sincronicamente con un read item method .

Saluto.

Inserita:

Ciao,

Tornando sul discorso del timeout per linea interrotta in lettura, bisogna anche

considerare altri fattori come ad essempio tipo di proccessori, sistema operativo,

media(MODBUS RTU, MODBUS TCP/IP, ETHWAY, XWAY TCP/IP, etc) utilizzati .

Poi, i numeri di partners collegati sulla rete, e numeri d'items trattati per ogni PLC influiscono nel refresh time sicuramante.

Un modo per monitorare la linea independentemente del feedback hardware e' mediante un routine di controllo SW che supervisa ciclicamente l'update, entro un periodo di tempo uguale al refresh item time + tempo di controllo time out.Per essempio se un local OPC client ha un update rate di 200 mS per un massimo di 20000 items basterebbe lanciare una routine watch dog che scatterebbe, se entro 300 mS il refresh di una variabile scelta per ogni PLC non avviene.

Saluto.

Inserita:

Ciao a tutti,

Forse il tuo codice fa qualche altro giro estrano......

Giro estrano ?!?!?!? magari fosse in giro ...... :(

E' rigorosamento piantato nella SyncRead, lo sapevo anche io che la connessione risponde subito anche se la linea non cè, il problema è quando l'AG sparische mentre sono nella syncread.

Io faccio la ConnectServer() all'inizio del programma nella sub main(), poi carico un form e cliclicamente leggo 10 word dall'AG (ce nè solo 1 applicazione molto semplice).

La frequenza di queste letture è di circa 10 al secondo.

Per cui, a meno di non fare sempre una ConnectServer() prima di ogni lettura (che mi sembra strano), il rischio che cada la connessione durante l'esecuzione della SyncRead è altissimo.

Alla prossima :)

Inserita:

Ciao,

...il problema è quando l'AG sparische mentre sono nella syncread.La frequenza di queste letture è di circa 10 al secondo.

Per cui, a meno di non fare sempre una ConnectServer() prima di ogni lettura (che mi sembra strano), il rischio che cada la connessione durante l'esecuzione della SyncRead è altissimo.

Hai raggione, la ConnectServer() viene fatta solo al inizio del pooling oppure dopo il ripristino di un break.

Ma, quando ti cade la connessione durante l'esecuzione della SyncRead, cosa succede, l'API si pianta,non fa il data refresh, ahh, ti apare il messaggio di timeout dopo 10 sec., behh, allora accorcia il refresh time, non so imposta 2 sec. e dopo fai un controllo SW su di una variabile che si aggiorna ogni 1 sec. nel PLC con un valore sempre diverso, un contatore ad essempio.

Poi, se al ritorno della SyncRead ricavi il medesimo valore della lettura anteriore, vuoldire che hai un problema di caduta linea o roba del genere, allora salti alla procedura di ripristino, azzerando e quindi rientri facendo un ConnectServer() ancora.

Saluto.

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