Sharp7 icon indicating copy to clipboard operation
Sharp7 copied to clipboard

Problema funzione WriteArea

Open IvanLampedecchia opened this issue 2 years ago • 3 comments

Ciao, Sto avendo alcuni problemi con la funzione DBWrite: In un protocollo di scambio dati tra PC e PLC che prevede l'accesso ad un DB in Lettura/Scrittura da entrambe le parti, a volte questa funzione restituisce 0 (esito positivo) anche se fisicamente sul PLC i dati non sono scritti. Il protocollo di scambio è il seguente:

LOOP(condition) PC=>PLC (DB1): Stringa XXXXXX (Risposta su DB1) PLC=>PC (DB2): Stringa XXXXXXXXX (Risposta su DB2) PC=>PLC(DB1): Stringa ------ (Reinizializza stringa con carattere predefinito) PC=>PLC(DB2): Stringa ------ (Reinizializza stringa con carattere predefinito) END LOOP

Ho momentaneamente tamponato questo problema con un meccanismo di Scrittura=>Rilettura=>Retry.

Avendo poca esperienza con questo protocollo fatico a comprendere se il problema sia dato dalla funzione che esce prematuramente o dal PLC che fa qualche scherzetto.

IvanLampedecchia avatar Oct 29 '21 08:10 IvanLampedecchia

Hi!

Capisco il problema. Potresti darmi altri indizi per aiutarti?

  • Hai una PLC ed un PC, giusto?
  • Cosa intendi come risposta su DB2? Che la tua PLC scrive su Sharp7 Server o semplicemente su un'altra DB?
  • Il software che realizza questo scambio di information tra PC e PLC usa Sharp7 anche per leggere o scrivere altre aree o variabili?
  • Quando si presenta il problema? Saresti in grado di riprodurlo?

Il problema che descrivi mi sembra dovuto a thread-safety. Purtroppo Sharp7 è molto low-level e non è tread-safe di per sé: c'é un semplice socket di comunicazione e ogni azione viene eseguita attraverso lo stesso canale e la plc può eseguirne una alla volta in maniera procedurale.

Per sapere se il problema è dovuto a questo potresti provare a isolare il tuo loop e vedere se riesci a riprodurre il problema.

In Sharp7Reactive abbiamo risolto il problema con un LimitedConcurrencyLevelTaskScheduler.

Saluti, FB

fbarresi avatar Nov 01 '21 21:11 fbarresi

Ciao, Grazie per la tempestiva risposta, Allora tutti i DB risiedono fisicamente sul PLC che funge da Server. Due di questi, fungono da canali RX/TX per i comandi. DB 1 viene usato dal PC per scrivere una missione da eseguire al plc (Stringa di 9 caratteri) DB 2 viene usato dal PLC per comunicare l'esito della missione (stringa di 12 caratteri). Non ho avuto ancora modo di testare accuratamente le altre variabili, con i primi test non ho rilevato il problema. C'è da dire però che lo scambio di dati per le altre variabili non è così interattivo.

Il software in cui è integrata la libreria esegue tutta la procedura su un singolo thread quindi non ci sono problemi di concorrenza. Il problema è replicabile implementando quel protocollo di scambio (vedi codice qui sotto) Ho isolato tutto il loop (il programma fa solo questo ciclicamente) e l'ho fatto girare un po'. Non sono riuscito ad entrare in debug perchè per capire se l'operazione è andata a buon fine devo rileggere il valore ma nel momento in cui rileggo lo stato dell'oggetto è diverso da quello che aveva al momento della scrittura.

https://codeshare.io/nzqxXj

Il metodo S7WriteString è solo un wrapper di S7Client.WriteString che va a

convertire la stringa in array di byte(facendo la conversione in UTF8) e poi va a chiamare DBWrite.

Ho provato a scrivere la stringa byte per byte con la funzione WriteArea ma ho avuto gli stessi problemi: stringa da scrivere: "M01001000" valore iniziale DB: "#########" Inizio scrittura byte per byte: =>"########0" ok =>"########0" fail (la funzione comunque esce con 0) =>"######0#0" ok =>"#####10#0" ok =>"#####10#0" fail (la funzione comunque esce con 0) =>"###0#10#0" ok =>"##10#10#0" ok =>"#010#10#0" ok =>"#010#10#0" fail (la funzione comunque esce con 0)

PS: proverò anche questa Sharp7Reactive per vedere se il problema persiste Il lun 1 nov 2021, 22:05 Federico Barresi @.***> ha scritto:

Hi!

Capisco il problema. Potresti darmi altri indizi per aiutarti?

  • Hai una PLC ed un PC, giusto?
  • Cosa intendi come risposta su DB2? Che la tua PLC scrive su Sharp7 Server o semplicemente su un'altra DB?
  • Il software che realizza questo scambio di information tra PC e PLC usa Sharp7 anche per leggere o scrivere altre aree o variabili?
  • Quando si presenta il problema? Saresti in grado di riprodurlo?

Il problema che descrivi mi sembra dovuto a thread-safety. Purtroppo Sharp7 è molto low-level e non è tread-safe di per sé: c'é un semplice socket di comunicazione e ogni azione viene eseguita attraverso lo stesso canale e la plc può eseguirne una alla volta in maniera procedurale.

Per sapere se il problema è dovuto a questo potresti provare a isolare il tuo loop e vedere se riesci a riprodurre il problema.

In Sharp7Reactive https://github.com/evopro-ag/Sharp7Reactive abbiamo risolto il problema con un LimitedConcurrencyLevelTaskScheduler.

Saluti, FB

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/fbarresi/Sharp7/issues/26#issuecomment-956589670, or unsubscribe https://github.com/notifications/unsubscribe-auth/AF7FEMFJFRR6ZTYQAO44XNLUJ36JTANCNFSM5G6X2DLA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

IvanLampedecchia avatar Nov 02 '21 09:11 IvanLampedecchia

Hi, If I understand correctly, I am having the same problem. It will fail to write to the PLC when using the AreaWrite method, yet it will still return a 0 (like it was written).

This will happen randomly and not very often but it is a critical failure, since we cannot know if the variable was written properly. Reading the variable just after does not work either, since it could have been modified from another source. We write to the same db in the plc just before this happens, but it´s all done sequentially and not over multiple threads.

Example:

  • 11:36:47.166 : Write int 0 to db XXXX, start 22 >>> Returns 0, it´s written to plc.
  • 11:36:47.233: Write byte 6 to db XXXX (same as before), start 4 >>> Returns 0, it´s NOT written to plc.

As I said, this works most of the times, but still fails some of them.

Please let me know if more information is needed, or if any help is needed.

josbri avatar Feb 01 '22 10:02 josbri