Vai al contenuto
PLC Forum


Problemi Di Comunicazione Libnodave - Errato trasferimento dei Bytes


mozart.5

Messaggi consigliati

Ciao a tutti!!

Stavo scrivendo un po' di funzioni ad alto livello per l'utilizzo delle Libnodave in VB.NET, quando mi sono accorto di un fatto abbastanza strano!

Per meglio comprendere il caso, fornisco qualche dato relativo alla mia configurazione:

- CPU S7-224

- PC/PPI Cable (Switch 010000 9.6 K 11bit DCE RTS Always )

- COM1

- PC Dell con installato Windows XP Pro 32 bit

- Processore Intel DUO

Il Problema che ho riscontrato è piuttosto singolare; tramite la funzione WriteBytes(), scrivendo nel byte V0 diversi valori, ho notato che il valore "2" non viene scritto correttamente ( Se passo il valore "2" su PLC trovo "0" :blink: ).

Quello che mi sembra strano è che è l'unico valore da 0 a 255 che mi fa questo scherzo!!

Un problema analogo l'ho trovato con la funzione complementare di lettura...qui addirittura il problema si riperquote a passi regolari sui numeri pari ( scrivo 2 e leggo 0, scrivo 4 e leggo 4, scrivo 6 e leggo 4, scrivo 8 e leggo 8, scrivo 10 e leggo 8,...e così via)

Qui riporto la funzione di scrittura che ho utilizzato...utilizza quasi direttamente la WriteBytes() Libnodave!!

    Public Function WriteByteToPLC_DB(ByRef PLC As PLC_AdrType, ByVal NumDB As Integer, ByVal StartAdr As Integer, ByVal Valore As Integer) As Integer
        'FUNZIONE DI SCRITTURA A BYTE
        '
        ' PLC       = Variabile di puntamento al PLC 
        ' NumDB     = Numero Del DB in cui si intende scrivere
        ' StartAdr  = Indirizzo di partenza per la scrittura nel DB 
        ' Valore    = Valore intero corrispondente agli 8 bit che si 
        '             binari che si intendono scrivere 
        'Return:
        '  1 = Scrittura a buon fine
        ' -2 = Errore di scrittura

        Dim WriteByte As Byte
        WriteByte = CByte(Valore)
        Debug.Print(CStr(WriteByte))

        If (PLCfunctions.daveWriteBytes(PLC.dConn, daveDB, NumDB, StartAdr, 1, WriteByte) = 0) Then
            WriteByteToPLC_DB = 1
            Debug.Print("Scrittura OK!")
        Else
            WriteByteToPLC_DB = -2
            Debug.Print("Errore di Scrittura!")
        End If
    End Function

Inizialmente pensavo ad un 'errata interpretazione del bit di parità...tuttavia mi sembra che il protocollo PPI necessita di tale servizio...quindi non so cosa fare!!

Voi cosa dite?

Link al commento
Condividi su altri siti


Io per prima cosa farei cosi:

verificherei che il dato che passa porta RS 485, metterei in monitor il transito dei dati, io per far cio' uso o l'oscilospopio con memoria, o un convertitore RS485-232 e catturo il flusso dati. Sono diventato matto con un problema simile non con i PLC ma con dei PIC che qualcuno ha fatto una routine per inviare i dati serialmente non perfetta e alcuni bit non venivano letti correttamente.

Dopo di che si puo' analizzare dov'è l'inghippo.

Link al commento
Condividi su altri siti

Quella sarebbe la soluzione più efficace e costruttiva...purtroppo non dispongo di un oscilloscopio con memoria!! :rolleyes:

Anzi...non ho proprio un oscilloscopio!! :lol:

Qualcuno sa se è un problema di impostazioni delle interfacce?

Perchè se tolgo il bit di parità non riesco ad instaurare la comunicazione!!

Grazie!!

Link al commento
Condividi su altri siti

Ciao

Premetto che non ho fatto prove in PPI con S7-200.... comunque penso di aver già visto quella funzione....

potresti:

1) Mostrare il codice della connessione. (vorrei controllare alcune cose, es: se hai abilitato in modo corretto TIME-OUT)

2) Quando avevo scritto la funzione che usi avevon pensato a "WriteByte" come un vettore di BYTE, potresti provare a dichiarare "WriteByte" come vettore con un elemento solo ??? Non ricordo se nella gestione della memoria è uguale (in VB6 lo era)....

Ciao

BR1

Link al commento
Condividi su altri siti

Ciao BR1!!

Anche io temo di aver fatto un pasticcio con le configurazioni delle funzioni di connessione e con i relativi tipi dei parametri!! :rolleyes:

Se mi dai un indirizzo mail (anche tramite messaggio privato...) ti invio l'intero esempio... così si può capire se ci sono problemi dovuti al cast delle variabili di VB!!

Grazie!!

;)

Link al commento
Condividi su altri siti

Ti ho appena mandato l'indirizzo e mail

quando risolviamo il problema pubblichiamo la soluzione in modo da aiutare anche gli altri che potrebbero avere problemi simili.

ciao

Link al commento
Condividi su altri siti

  • 1 month later...

Ciao Fabio

Scusa il ritardo, ma sono stato via per lavoro....

ti ho messo un piccolissimo esempio di comunicazione con libnodave in VB.NET nella sezione upload/download del sito....

(te lo spedisco anche sulla tua email)

Ricordati che nel caso di lettura di V con S7-200 devi impostare la DB a 1... io ho potuto testare la comunicazione solo con S7-300 (in ethernet, seriale e con DLL siemens [/s7ONLINE])...

L'esempio è molto spartano e dovrebbe esserti utile per le operazioni di connessione, lettura, scrittura e conversione (BYTE, INT, DINT)...

Fammi sapere .

Ciao

BR1

Link al commento
Condividi su altri siti

Un'ulteriore nota:

per quanto riguarda la classe "libnodave" ho eseguito la conversione automatica da C# a VB.NET, quindi è abbastanza orrenda !!!!

Appena possibile utilizzo la versione di Varg

ciao

Link al commento
Condividi su altri siti

  • 3 weeks later...

Grande!!

Ti ringrazio solo ora perchè anche io sono rientrato da pochi giorni...come se non bastasse sto traslocando!!

Ora ci metto subito le mani e la zucca!! ;) Poi ti faccio sapere!!

Grazie ancora!!

Link al commento
Condividi su altri siti

Eccomi... si parla del diavolo...

Io ho lavorato con l'S7-200

Configurazioni ottimali e Funzionanti...

ProtoNum = EmpTypeProto.daveProtoPPI

sBaudRate = "9600"

sCommPort = "COM1"

sParity = "E"

iRack = 0

iMPI = 2

iSlot = 2

Ovviamente la COM cambia in base a quella che usate.

Link al commento
Condividi su altri siti

Aggiungo altre informazioni...

Nei vecchi Programmi in VB6 e anche nel Porting in .NET alla funzione del Write gli ho sempre passato un Array di byte ed ha sempre funzionato regolarmente

Quindi potresti provare anche a passare un vettore indicizzato a 0

Dim WriteByte(0) As Byte

WriteByte (0) = CByte(Valore)

a quel punto lavori normalmente

Link al commento
Condividi su altri siti

Perfetto!!

Ora riesco a comunicare correttamente!

Purtroppo, nell'applicazione che stò provando a realizzare, si presenta un ulteriore problema...

Ammetto che probabilmente non è il luogo adatto dove inserire il post; infatti è un problema di programmazione VB più che di programmazione PLC.

Aprendo un processo in Background voglio controllare lo stato di un merker...il problema è che a seconda dello stato voglio modificare una proprietà di un oggetto del Form principale!

Ovviamente l'applicazione si "incavola" perchè cerco di modificare una proprietà da un thread diverso da quello di creazione dell'oggetto stesso! :rolleyes:

Ho letto qualche cosa relativo all "Invoke" ed al "Delegate"... però, non essendo ferratissimo nella programmazione Vb, non so bene come macinare il tutto!

Ciao e grazie!!

Link al commento
Condividi su altri siti

:lol:

benvenuto nel fantastico mondo del VB.NET

Ti Rispondero con una Paio di Righe di Codice....

Ipotizziamo che vuoi settare il Testo di Una Label da un Processo...

'Dichiarazione Generale sul Form:

Delegate Sub SetTextCallBack(ByVal Testo As String)
'Sub Per il Setting della Text
    Private Sub SetText(ByVal Testo As String)
        If Me.lblPIPPOTOPOLINO.InvokeRequired Then
            Dim d As New SetTextCallBack(AddressOf SetText
            Me.Invoke(d, New Object() {Testo})
        Else
            Me.lblPIPPOTOPOLINO.Text = Testo
        End If
    End Sub

Quindi quando vuoi cambiare la Text dell'oggetto lblPIPPOTOPOLINO tu farai un bel

SetText("TESTO")

La funzione in Cross-Safe farà quello che deve fare.

Link al commento
Condividi su altri siti

Grande Varg !

Esempio semplice ma completo !

Mozart stai solo attento che non ti aumenti l'appetito (che vien....) , infatti se in un thread noti la variazione di un bit e in un altro ne visualizzi lo stato è una cosa, ma se immagini un thread che legga ciclicamente uno o più PLC e poi per ottimizzare i tempi alla variazione di un bit (tipo PLC richede dati) tu ti crei un evento per scrivere dati su PLC potresti avere brutte sorprese....

infatti è facile capire che il collegamento seriale/ethernet al PLC non sia multi-thread (mentre un processo accede all'interfaccia non puoi fare lo stesso con un altro), quindi devi stare attento a sincronizzare le tue operazioni.

Ciao

BR1

Link al commento
Condividi su altri siti

Esatto bisogna stare attenti coi Thread hanno potenzialità enormi ma bisogna stare MOLTO e insisto sul MOLTO attenti.

Io ad esempio riscritto un programma di supervisione di stampanti tutto in Multithread, ogni plc è un thread, si riesce a raggiungere velocità che sfiorano l'incredibile, e sopratutto se un PLC ha problemi, l'attesa del Time-Out non influenza le altre comunicazioni.

In particolare puo essere una idea di sviluppo di un thread, creando un classe thread plc, si delega direttamente al thread eventuali scritture/letture aggiuntive.

Un esempio tipico di un Thread Polling puo essere

DO

--> Eseguo la Lettura di Polling

--> Se ho avuto richiesta da un "esterno" di effettuare una scrittura scrivo

--> Se ho avuto richiesta da un "esterno" di effettuare una lettura diversa leggo

LOOP

Facendo cosi se vi è una necessità di scrivere qualcosa o leggere qualcosa di aggiuntivo, passiamo il compito al Thread cosi non gli pestiamo i piedi, ma sarà lui che lo eseguirà appena è possibile.

Saluti

Link al commento
Condividi su altri siti

  • 1 month later...

Non posso che ribadire il commento di Br1!

Bravo Varg!

Seguendo il tuo esempio sono riuscito a fare un'applicazioncina che gestisce un set di variabili di un S7200.

Ho un solo problema piuttosto fastidioso:

Io ho creato degli array nel mio progetto VB da utilizzarsi come Database Virtuale...mi spiego... utilizzo un processo di lettura che effettua un polling degli elementi del mio array e aggiorna le pagina di visualizzazione ogni 100ms ( questa operazione non intacca il canale di comunicazione, pertanto la frequenza di scansione non dovrebbe pesare direttamente sulle operazioni di lettura e scrittura).

Ulteriori processi, suddivisi per tipo di dato, effettuano a loro volta un polling delle aree del PLC che intendo LEGGERE e COPIARE nel mio ARRAY (in realtà ho diversi array a seconda dei tipi di dato). Ogni processo ha i propri tempi di scansione.

Ovviamente un processo va in lettura solo se il canale è libero ( Quando un processo va in lettura o in scrittura viene alzato un Flag di Busy...poi resettato al termine dell'operazione).

La scrittuara è gestita da eventi generati dall'interfaccia...se voglio scrivere alzo una richiesta....se la richiesta è alta gli altri processi non possono accedere al canale...non appena il canale si libera, il processo di scrittura lo occupa ed esegue le sue operazioni.

Il mio problema è che dopo qualche minuto di funzionamento sembra che qualche cosa si blocchi...tutti i valori a video vengono buttati a 0 e poi ritornano come prima...non credo che sia un problema di aggiornamento del database...possibile che ad intervalli più o meno regolari falliscano tutti i tentativi di lettura? Magari cade la comunicazione? O è un problema di recupero dei dati dagli Array?

Ho provato a fare un controllo del tipo (aggiorna solo se leggi per n volte 0) ma niente!

Oramai è una sfida personale... :lol:

saluti!

Modificato: da mozart.5
Link al commento
Condividi su altri siti

  • 1 month later...

ciao,

il canale di comunicazione funziona costantemente? io sto testando la comunicazione seriale con un S7-200 attraverso il convertitore RS232-RS485 della siemens e ho notato che la comunicazione cade molto spesso (molti timeout in lettura) rispetto ad una connessione ISO/TCP con CP243?

da quanto ho capito usi l'accesso ad un'unica risorsa da parte di processi concorrenziali, mi sembra di capire che affidi la prenotazione della risorsa ad un flag, forse potrebbe essere più conveniente utilizzare uno strumento un pò più complesso, magari una classe che implementa i metodi di interfacciamento al PLC e che incorpori un sistema di gestione delle prenotazioni delle richieste trasperente al chiamante, per esempio, la classe espone i metodi leggi e scrivi, essendo essa l'unica che può accedere alle funzioni di accesso al plc si può pensare che ogni richiesta finisca in una coda FIFO e che venga processata nel momento in cui tutte le richieste precedenti sono state esaudite.

Link al commento
Condividi su altri siti

  • 3 weeks later...

Ok per il discorso fifo, ma poi bisogna anche stare all'occhio come vengono distribuite le risposte.

Dato che i thread hanno velocità diverse bisognerebbe verificare anche un modo di prelievo della risposta indipendente dall'ordine della richiesta.

Link al commento
Condividi su altri siti

  • 1 month later...

C'è qualche volenteroso che fa un piccolo schemino per principianti che si mettono all'opera con libnodave?

è una settimana che uso la funzione cerca in questo forum, ma ci sono talmente tanti thread con talmente tante discussioni che prima di leggerle tutte ci vuole una vita e soprattutto non si capisce molto.

Io sto provando a usare l'esempio vb.net contenuto nella directory ufficiale disponibile in sourceforge e l'esempio con il file excel sfruttando il vba di excel ma sto letteralmente impazzendo!

Ho una cp5512 ed una cpu 226 con porta 0 impostata in 187500.

chi mi aiuta a risolvere il mio problema? (nel pc ho solo visualstudio2005, non vb6...)

grazie a tutti

Link al commento
Condividi su altri siti

Prova nella sezione upload/download ci sono esempio in C# Visual Studio 2005 (Express Edition) e in VB.NET (2005).

Scarica quello chiamato "starterkit"

CIao e buon lavoro

BR1

Link al commento
Condividi su altri siti

Non riesco a collegarmi e non capisco dove sbaglio:

intanto ho una CP5511 e sto usando l'esempio in VB6 "testlibnpodave".

ho impostato

- tipo di connessione 10-PPI for S7 200;

- IP PLC 192.168.100.156 (che era già impostato di default, anche se non capisco a cosa serva visto che la mia 226 non ha nessuna scheda ethernet);

- porta seriale COM1 (anche questa di default ma io uso una CP perciò non ho nessuna porta seriale verso il plc)

- baud rate 19200 (è possibile andare a 187500? sarebbe meglio, ma posso accontentarmi)

- MPI/PPI 3 poichè nel mio caso è così.

- collegamento S7 ho di default /S7ONLINE ma non capisco ne l'utilità ne cosa scriverci

- Numero DB ho letto in varie discussioni che per l'area V del 200 va impostato come DB1

Cliccando in CONNETTI PLC ad ogni tentativo mi viene visualizzato nella finestra messaggi operatore "Errore Init Hardware 0 - in 0msec"

Qualcuno ha già testato il collegamento con questa configurazione? Mi dite cosa devo impostare?

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