wasabi Inserito: 15 giugno 2015 Segnala Share Inserito: 15 giugno 2015 Ciao a tutti! Premetto di essere nuovo del forum e del mondo Siemens, quindi perdonate l'ignoranza In passato ho sviluppato uno SCADA interfacciato a PLC Siemens con OPC Server. Funziona, ma non mi ha esaltato particolarmente, in particolare l'esigenza di definire tutte le variabili ( indirizzi di memoria ) in lettura e scrittura all'avvio del programma, senza che ci fosse un sistema "comodo" per aggiungere variabili run-time. comunque, ora devo sviluppare un'altro SCADA per Siemens che deve essere installato su 5 PC e, per risparmiare sulle licenze, sto valutando alternative: Snap7 Ho fatto alcune prove e mi sembra un ottimo prodotto, i miei complimenti all'autore Però evidentemente c'è qualcosa che sto sbagliando perchè le performance che ho in lettura sono davvero scarse: 2 byte in circa 30 ms 10000 byte in circa 2800 ms la lettura avviene con una sola chiamata alla funzione DBRead() A questo punto ho provato ad usare la funzione ReadMultiVars() e le performance sono migliorate: 2000 byte in circa 500 ms Il problema con questa funzione è che devo calcolare a mano i byte da trasferire + la dimensione dell'header ( che tra l'altro non ho capito quanto sia ) ed eseguire la funzione per ogni blocco da 240 byte ( PDU concordato ) Detto questo, sono riuscito ad usarla, ma dopo un certo numero di chiamate ( circa 500 ) non legge più nulla e non restituisce nessun codice di errore Per contestualizzare meglio la mia situazione, sto usando: - Visual Studio 2010, C# - PLC Siemens S7-300 con Simatic NET Saluti e grazie per l'aiuto, Davide. Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 15 giugno 2015 Segnala Share Inserita: 15 giugno 2015 (modificato) Sono tempi biblici Ho in linea un 1500 ed ho fatto una prova con una DB da 65000 bytes. Per conoscere il tempo ho modificato nel demo C# (per rimanere nelle tue stesse condizioni) la funzione ShowResult() private void ShowResult(int Result) { // This function returns a textual explaination of the error code TextError.Text = Client.ErrorText(Result) + " (" + Client.ExecTime().ToString() + " ms)"; } Ed i tempi sono sempre nell'ordine dei 320 ms per 65000 bytes e 3 ms se il pacchetto rimane nel PDU size. Sospetto che hai qualche problema di rete.... Raccontami meglio la tua configurazione figliuolo Modificato: 15 giugno 2015 da dan64100 Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 15 giugno 2015 Autore Segnala Share Inserita: 15 giugno 2015 Il PC che sto usando per i test ha Windows 8.1 e c'è installato l'ambiente di sviluppo Beckhoff ( sia la versione 2, sia la 3 ) Sono collegato con il cavo ethernet direttamente al PLC Ho modificato il programma di esempio in C#, una lettura ( DBRead ) di 10000 byte in circa 2700 ms C'è qualche impostazione lato PLC che dovrei controllare ? Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 15 giugno 2015 Segnala Share Inserita: 15 giugno 2015 Ho appena provato con una CPU IM151-8 (PDU=240) ed ho 272 ms per 10000 bytes 751 ms per 32768 bytes (la più grande possibile per questa CPU). Non ho windows 8 ma ho provato a suo tempo Windows 10 (technical preview) senza alcuna differenza apprezzabile. Non credo che sia un problema di sistema operativo, i tempi di cui sopra li ho rilevati da NT 4 (in VM) fino a Windows 7. Il ping che tempo ti da ? Prova clientdemo.exe (su qualunque altro PC, non richiede il framework .net, basta snap7.dll) lo trovi nella cartella rich-demos/i386. Che CPU usi ? Sono tempi troppo alti anche per una CPU313+CP343-Lean a carbonella. Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 15 giugno 2015 Autore Segnala Share Inserita: 15 giugno 2015 CPU313C-2 DP Il ping è <1 ms ho provato clientdemo.exe sulla stessa macchina con gli stessi risultati....ora provo su un'altro PC Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 15 giugno 2015 Autore Segnala Share Inserita: 15 giugno 2015 Appena provato con un altro PC ( Windows 7 ): stesso risultato ho il sospetto che sia colpa del PLC Link al commento Condividi su altri siti More sharing options...
batta Inserita: 15 giugno 2015 Segnala Share Inserita: 15 giugno 2015 - PLC Siemens S7-300 Dovresti essere più preciso. Dai il codice completo. Dico questo perché, anche utilizzando Step 7, si nota una differenza enorme nella velocità di comunicazione tra CPU vecchie e nuove. Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 15 giugno 2015 Autore Segnala Share Inserita: 15 giugno 2015 CPU313C-2 DP... Pensavo fosse questo il codice completo Domani guardo meglio comunque è sicuramente una cpu vecchia, il mio cliente la usa da tempo per test Quella che si dovrà usare sull'impianto sarà un plc software (ora non ho sotto mano il suo codice) Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 15 giugno 2015 Segnala Share Inserita: 15 giugno 2015 Se il SoftPLC e' Siemens allora è WinAC, 480 bytes di PDU e usa la velocità dell'adattatore di sistema a 1Gb/s. Viaggi a 2 ms max per telegramma. Purtroppo la CPU più piccola che ho è la IM151-8, non è un fulmine di guerra ma ha Ethernet integrata, quindi abbastanza veloce almeno per le comunicazioni. Non ho modo di confermarti il problema della 313. Su quelle recenti o di tipo PN però ti posso assicurare i tempi di sopra Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 16 giugno 2015 Autore Segnala Share Inserita: 16 giugno 2015 Ho appena provato con il SoftPLC modello IPC477 e le prestazioni sono decisamente migliori 10000byte in circa 50 ms Ora però ho un altra domanda, sempre inerente alle librerie Snap7 Prima devo spiegare brevemente cosa sto cercando di fare: Vorrei creare un sistema di notifiche ( eventi ) al variare di alcune locazioni di memoria ( variabili ) Tralasciando l'implementazione della classe che gestisce la lista delle variabili da monitorare, il cuore del sistema consiste in un thread che continua a leggere i valori di queste in polling Per via della natura di queste variabili, potenzialmente sparse nei vari DB, ho deciso di usare la funzione di libreria ReadMultiVars() Ho letto nel manuale che questa funzione non esegue automaticamente lo "split" delle chiamate a seconda della dimensione del PDU concordato, quindi dovrei farlo io a mano calcolando per ogni variabili la sua dimensione + la dimensione del suo header E qui la prima domanda: qual'è la dimensione dell'header ? Non conoscendo la dimensione dell'header ho deciso, solo per test, di stare dalla parte della ragione ed eseguire una lettura a blocchi di 10 variabili ( ogni variabile è un intero da 2 byte ) Il sistema sembra funzionare. Sempre per test ho aggiunto un centinaio di variabili "in ascolto", alcune delle quali vengono incrementate dal PLC ogni secondo ed il supervisore visualizza correttamente il loro valore. Il problema è che dopo un certo numero di letture il sistema non funziona più e ReadMutilVars() sembra non leggere lo stato aggiornato delle variabili, ritorna sempre l'ultimo valore letto e non quello attuale. Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 16 giugno 2015 Autore Segnala Share Inserita: 16 giugno 2015 Ho fatto altri test per capire meglio Ho semplificato al massimo il codice nel thread di lettura per cercare di isolare il problema Ora nel thread esegue una lettura con ReadMultiVars() ed una con DBRead(), entrambe della stessa locazione di memoria ( DB5.10 x 2 byte ) l'esecuzione è condizionata da un semaforo rilasciato da un timer da 20 ms ( ho variato il valore del timer diverse volte, ma il risultato non cambia ) Ogni volta stampo una stringa del tipo: Numero Progressivo - Valore letto con ReadMultiVars() - Valore letto con DBRead() questo è il risultato: 1 -> RM: 0x14 0x7a - DBR: 0x14 0x7a 2 -> RM: 0x14 0x7a - DBR: 0x14 0x7a 3 -> RM: 0x14 0x7a - DBR: 0x14 0x7a 4 -> RM: 0x14 0x7a - DBR: 0x14 0x7a ... 38 -> RM: 0x14 0x7b - DBR: 0x14 0x7b 39 -> RM: 0x14 0x7b - DBR: 0x14 0x7b ... 200 -> RM: 0x14 0x7e - DBR: 0x14 0x7e 201 -> RM: 0x14 0x7e - DBR: 0x14 0x7e ... 2960 -> RM: 0x14 0xb4 - DBR: 0x14 0xb4 2961 -> RM: 0x14 0xb4 - DBR: 0x14 0xb4 ... 3008 -> RM: 0x14 0xb4 - DBR: 0x14 0xb5 Da qui in poi la ReadMultiVars() non funziona più correttamente 3009 -> RM: 0x14 0xb4 - DBR: 0x14 0xb5 ... 7498 -> RM: 0x14 0xb4 - DBR: 0x15 0x0c 7499 -> RM: 0x14 0xb4 - DBR: 0x15 0x0c Dopo un certo numero di operazioni di lettura, la funzione ReadMultiVars() restituisce sempre lo stesso valore, mentre la funzione DBRead() continua a leggere correttamente Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 16 giugno 2015 Segnala Share Inserita: 16 giugno 2015 (modificato) MultiRead/Write è una funzione nativa di S7Protocol, è stata pensata da Siemens per acquisire molte variabili con indirizzi eterogenei sfruttando un solo telegramma. In caso di variabili grandi non ha alcun senso splittarle, in ogni caso vanno a saturare il PDU quindi tante variabili grandi in parallelo ci mettono lo stesso tempo di tante variabili grandi in serie, anzi di più perché per ogni variabile devi aggiungere un header nel telegramma. I payload sono Lettura : PDULength-(12+12*NumItems) Scrittura : PDULength-(12+16*NumItems) Dove PDULength è il PDU negoziato (non assumerlo di 240, nella tua nuova CPU è senz'altro 480) e NumItems è max 20. ---------- Sono arrivato a circa 35000 cicli in ambiente e 10000 nel compilato, ed ancora ottengo valori diversi. La funzione nella libreria è certo che funziona, la uso da sempre per acquisire in parallelo i triggers delle stazioni all'interno di un PLC e non ha mai perso un colpo. Il grosso punto interrogativo è come al solito il Garbage collector di .NET (secondo come utilità solo alla scabbia). Mi sono messo nell'ipotesi credo peggiore, chiamo ciclicamente una funzione di lettura ed al suo interno creo il reader. Ora provo ad usare un'istanza globale (ho inserito apposta il metodo clear() ) e vediamo cosa accade... P.S. Stai usando snap7 1.4.0 e la nuova classe S7MultiVar giusto ? Modificato: 16 giugno 2015 da dan64100 Link al commento Condividi su altri siti More sharing options...
wasabi Inserita: 16 giugno 2015 Autore Segnala Share Inserita: 16 giugno 2015 Effettivamente stavo usando la versione 1.3 delle librerie Ho scaricato la nuova versione ( 1.4 ) ed ho visto la classe S7MultiVar, ho visto che ora salvi tutti i GCHandle associati ai buffer di lettura. Effettivamente non ci avevo fatto caso, il Garbage collector potrebbe essere la causa del malfunzionamento che vedo Ora non ho il PLC sotto mano, ma domani mattina provo con la nuova versione... Grazie ancora per l'aiuto Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 16 giugno 2015 Segnala Share Inserita: 16 giugno 2015 Bene, è quello il problema. C'è un demo apposito CSClientMultiRead, lo trovi nella soluzione CSharp in examples/dot.net/WinForm/CSharp Link al commento Condividi su altri siti More sharing options...
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