Crash applicazione Windows Form

di il
12 risposte

Crash applicazione Windows Form

Buongiorno a tutti, sto impazzendo per capire in quale parte del codice crasha:

-Visual studio 2022

-Utilizzo dll Libnodave siemens

Descrizione programma:

Ogni 10 millisecondi interrogo con 4 timer distinti 4 segnali PLC all'interno di una DB siemens tramite la libreria Libnodave.

Questo segnale indica il prelievo di un pezzo da parte del robot (1 su ogni timer)

Questi segnali (bool) li confronto con lo stato precedente e determino se è cambiato di stato, incrementando la produzione della macchina sul form, ed aggiornando un grafico di andamento…

ci sono altri 5 timer che lavorano ogni secondo che effettuano alcuni calcoli di media produzione ecc ecc… , oltre ad un 6° timer (da 1 secondo) per controllare il cambio codice in lavoro da parte dei robot. (sempre leggendo dentro la DB del PLC…)

PROBLEMA:

In buona sostanza tutto funziona benone… ma all'improvviso magari dopo ore…. l'applicazione si chiude senza errori…

Ho già rinchiuso ogni porzione di ogni sub dentro try catch con label di brack point in exception… ma non ci passa mai…. e mi ritrovo con applicazione chiusa senza errori …..

Non riesco a capire come andare a pinzare l'errore…

PS: se ce bisogno di qualche porzione di codice non ci sono problemi a postarlo… 

Ho già pensato di creare un log…. ma non saprei bene come gestirlo essendo che la comunicazione simultane di più timer credo non sia fattibile aggiornare un file txt con quella frequenza…

Grazie a tutti in anticipo 

12 Risposte

  • Re: Crash applicazione Windows Form

    Prima di tutto non ha senso operare ogni 10 ms perché è proprio Windows e i Timer standard che non hanno questo tipo di precisione.

    Penso che bastino dei controlli ogni 50 o 60 millisecondi

    Ho fatto qualcosa del genere in passato e l'uso di file di log mi ha risolto parecchi problemi, almeno mi ha indirizzato sul punto da controllare.

    Se non usi API particolari e solo la libreria, io punterei ad un problema con tale componente. 

    Come usi la libreria? Riporta qualche parte del codice che richiama la libreria 

  • Re: Crash applicazione Windows Form

    …. sicuro di aver bisogno di tutti quei timer ?
    La comunicazione con il PLC avviene su che tipo di connessione ?
    (socket su ethernet, RS232, RS485, USB o che altro ?)
    Secondo me hai un problema di timer che si sovrappongono, nel momento in cui un timer sta facendo qualcosa ne scatta un altro, il primo quindi si mette in attesa, ma mentre il secondo sta lavorando ri-scatta il primo e così via, il tutto viene messo nello stack per capire quando un timer finisce dove deve ritornare il processo, e una volta riempito lo stack va tutto in crash
    (ovviamente questa è una mia umile opinione, può essere che mi sbaglio), ma avendo avuto a che fare con PLC e comunicazioni per quasi 30 anni ormai di problemi di comunicazione ne ho visti parecchi.

    Avere dei timer da 10 millisecondi, su di un PC che deve fare altre mille cose, secondo me è troppo, il PC non è strutturato per tempi così brevi.
    Mi concentrerei quindi a una migliore gestione di tutti questi timer.

    E gli altri 5 timer da 1 secondo che eseguono calcoli, perchè non fai un timer unico e dentro lì gli fai fare tutti i calcoli necessari di tutti i 5 timer ?
    Stessa cosa del sesto timer, anche lui è di un secondo, per cui metti l'elaborazione dentro agli altri timer.

    Una soluzione alternativa sarebbe quella di usare i task e lanciarne più di uno, in modo da avere le elaborazioni in parallelo, ma su questo argomento passo la parola a chi è più esperto di me

  • Re: Crash applicazione Windows Form

    20/07/2023 - oregon ha scritto:


    Prima di tutto non ha senso operare ogni 10 ms perché è proprio Windows e i Timer standard che non hanno questo tipo di precisione.

    Penso che bastino dei controlli ogni 50 o 60 millisecondi

    Ho fatto qualcosa del genere in passato e l'uso di file di log mi ha risolto parecchi problemi, almeno mi ha indirizzato sul punto da controllare.

    Se non usi API particolari e solo la libreria, io punterei ad un problema con tale componente. 

    Come usi la libreria? Riporta qualche parte del codice che richiama la libreria 

    Ho abbassato i tempi a 50 milli

    PS: la variabile ENBL_1 assieme poi alle variabili del robot 2 3 e 4 sono variabili che mi consentono di abilitare i timer di fermo macchina e fermo robot .

    'R1A
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    
            Try
                SiemensPLC.IP = "xx.xxx.xxx.xxx"
                SiemensPLC.tipo = libnodave.daveDB
                SiemensPLC.dimensione = "Bit"
                SiemensPLC.N_Db = 104
                SiemensPLC.N_Byte = 283 * 8 + 2 'BYTE db,8 BIT (1BYTE MOLTIPLICATORE),BIT  DELLA DB SU BASE 0 
                SiemensPLC.N_Bit = 1
    
                SiemensPLC.connectTo()
    
                If SiemensPLC.plcValue(0).ToString = 1 Then
                    If SiemensPLC.plcValue(0).ToString <> OLD_1 Then
                        Label27.Text = CInt(SiemensPLC.plcValue(0).ToString) + CInt(Label27.Text)
                        pick_minuto_R1A = pick_minuto_R1A + 1
                        ENBL_1 = True
                    Else
                        ENBL_1 = False
                    End If
                End If
    
                If SiemensPLC.plcValue(0).ToString = OLD_1 Then
                    ENBL_1 = False
                    count_5sec_r1a = count_5sec_r1a + 1
                Else
                    ENBL_fermo_R1A = False
                    count_5sec_r1a = 0
                End If
    
                'Abilito conteggio di fermo robot dopo 5 secondi 
                If count_5sec_r1a >= 20 Then
                    ENBL_fermo_R1A = True
                End If
    
                OLD_1 = SiemensPLC.plcValue(0).ToString
            Catch ex As Exception
                Dim lol = ""
               
            End Try
    
    
        End Sub
        
       
  • Re: Crash applicazione Windows Form

    'Apertura socket verso PLC
        Public Shared Sub connectTo()
    
            Try
                ciclo = 0
    
                fds.rfd = libnodave.openSocket(102, IP) 'Connessione al PLC tramite IP
                fds.wfd = fds.rfd
                di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
                res = di.initAdapter
                dc = New libnodave.daveConnection(di, 0, 0, 2) 'Area hardware
                res = dc.connectPLC
                
                'plcValue = Nothing
                Dim ii As Integer
                Dim xx As Integer
    
                Select Case dimensione
                    Case "Bit"
                        memoryRes = dc.readBits(tipo, N_Db, N_Byte, N_Bit, memoryBuffer)
                        plcValue = memoryBuffer
                    Case "Byte"
    
                        'ReDim plcValue((Form1.n_array + 1) * 220)
                        ReDim plcValue(N_Bit - 1)
    
                        For I = 0 To Form1.n_array
                            ii = I
                            Dim destinazione As Integer = 0
                            Dim partenza As Integer = 0
                            partenza = N_Byte + (I * 220)
    
                            If 220 * (I + 1) > N_Bit Then
                                destinazione = N_Bit - (220 * I)
                            Else
                                destinazione = 220
                            End If
    
                            memoryRes = dc.readBytes(tipo, N_Db, partenza, destinazione, memoryBuffer)
    
                            'popolo elementi array
                            For x = 0 To destinazione - 1
                                xx = x
                                plcValue(ciclo) = memoryBuffer(x)
                                ciclo = ciclo + 1
                            Next
                        Next
                End Select
    
                dc.disconnectPLC() 'Disconnessione PLC
                di.disconnectAdapter() 'Disconnessione adattatore
                libnodave.closePort(fds.rfd) 'Chiudi connessione
            Catch ex As Exception
                Dim lol = ""
            End Try
    
        End Sub
  • Re: Crash applicazione Windows Form

    Sopra è il codice che apre il socket di comunicazione con il PLC

    sotto descrivo la funzione dei timer

  • Re: Crash applicazione Windows Form

    Descrizione timer:

    timer 1= prelevo dati robot 1

    timer 2= prelevo dati robot 1

    timer 3= prelevo dati robot 1

    timer 4= prelevo dati robot 1

    timer 5= aggiorna il grafico di produzione incrementale  (ogni secondo)

    timer 6= aggiorna il grafico dei pezzi al minuto (ogni secondo somma 1 a una variabile, la quale a 60 inserisce i dati in grafico)

    timer 7= controlla ogni secondo il turno attuale (3 turni)

    timer 8= va a leggere ogni secondo sul PLC il codice in lavoro, lo confronta con la versione OLD del ciclo prima… ed al cambio spiana i grafici e salva i dati su file

    timer 9= conteggia il fermo macchina (quando tutti e 4 i robot sono in stato di fermo … non prelevano pezzi)

    timer 10=  gestisce il fermo dei 4 robot

  • Re: Crash applicazione Windows Form

    Quale tipo di timer utilizzi?

    questo 

     https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.timer?view=windowsdesktop-7.0

    oppure questo 

    https://learn.microsoft.com/en-us/dotnet/api/system.timers.timer?view=net-7.0

  • Re: Crash applicazione Windows Form

    Il primo

  • Re: Crash applicazione Windows Form

    Ora ho aggiunto all'inizio di ogni form la scrittura dell'evento in un file Log… sembra riesca a stargli dietro ad aggiornarlo:

    In questo modo al crash dovrei trovarmi nel file log l'ultima operazione INIZIATA … quindi imputabile di crash… credo…

    Non aggiungo righe ad ogni evento perchè con un refresh di 50 milli per ogni robot ecc ecc diventerebbe enorme il file

    ES:

     'R1A
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    
            File.WriteAllText(Log, "Inizio lettura valori R1A (TIMER 1)" & vbCr & Now.ToString & vbCr & "----------------------------------------------")
    
            Try
            
               ......codice
    
            Catch ex As Exception
                Dim lol = "" 'SOLITO BREAK POINT
            End Try
    
        End Sub
  • Re: Crash applicazione Windows Form

    Io farei una prova con i timers sotto system.timers che sono "slegati" dall'interfaccia utente

  • Re: Crash applicazione Windows Form

    Non li ho mai utilizzati, faccio qualche prova per vedere come funzionano, grazie mille

  • Re: Crash applicazione Windows Form

    Ho iniziato a fare qualche prova: mai usati in questo modo quindi mi trovo davanti ad alcuni dubbi:

    Ho creato una classe per 1 timer… ipotizzando che lo configuroi da 1 secondo… essendo che nel codice ne utilizzo per esempio 6 da 1 secondo devo creare N classi da 1 secondo ciascuna oppure posso utilizzare la stessa classe per tutti e 6 i timer?

Devi accedere o registrarti per scrivere nel forum
12 risposte