View Full Version : [VB.NET] Evento pinchanged (seriale)
Capello82
17-04-2008, 10:12
Salve a tutti... il frammento di codice che penso mi crei probelmi è il seguente.
Private Sub PinChange(ByVal sender As Object, ByVal e As System.IO.Ports.SerialPinChangedEventArgs) Handles serialPort.PinChanged
Me.Invoke(New PinChangeDelegate(AddressOf updatePin), New Object() {})
End Sub
Public Delegate Sub PinChangeDelegate()
Public Sub updatePin()
Application.DoEvents()
If serialPort.CtsHolding = False And send_complete = False Then
Threading.Thread.Sleep(100)
X_COORD.Text = XCOORD
Y_COORD.Text = YCOORD
InviaDati()
End If
End Sub
Come potete vedere io controllo lo stato del CTS e invio dei dati sulla seriale ogni volta che il ricevitore manda alto il CTS (unitamente all'altra condizione, che però non è importante in questa discussion).
Il problema è che dopo aver inviato i dati richiesti (tramite la chiamata della sub "InviaDati"), l'applicazione rimane bloccata fino al successivo invio di dati e non mi aggiorna nessun controllo nella form, se non quando viene chiamato il delegato mostrato.
Come posso liberare l'applicazione? Io sospetto che il problema sia il controllo sul CTS; forse lo fa di continuo, come un loop, e a causa di questo l'applicazione è impegnata.
Grazie ^^
Capello82
18-04-2008, 10:25
UP^^ nessuna idea?
Capello82
19-04-2008, 19:05
edit
uh? O.o
uh? O.oho editato perchè non ho qui vb.net per provare..ti consigliavo di provare a triggerare e.EventType per intercettare solo l'evento cambio cts così da lanciare la funzione update pin solo quando necessario (e non "sempre" come ora) per tentare di circoscrivere il problema
Per caso InviaDati, oltre a forse inviare i dati, aggiorna qualche controllo/grafica della form? Anche solo magari indirettamente per mezzo di altri eventi?
Capello82
20-04-2008, 11:57
ho editato perchè non ho qui vb.net per provare..ti consigliavo di provare a triggerare e.EventType per intercettare solo l'evento cambio cts così da lanciare la funzione update pin solo quando necessario (e non "sempre" come ora) per tentare di circoscrivere il problema
Potresti farmi un semplice esempio di quello che intendi? Sai, non sono molto ferrato in questo campo e non uso da molto VB 2005 ^^"
x GugoXX: in InviDati, ci sono condizioni "If" su alcuni controli e abilitazione e disabilitazione di alcuni bottoni.
Il problema del bloccaggio applicazione sembra essere risolto se uso il seguente codice:
Public Delegate Sub DataReceivedDelegate()
Public Sub updateCoord()
Application.DoEvents()
receivedchar = serialPort.ReadExisting
If receivedchar = "K" And send_complete = False Then
Threading.Thread.Sleep(100)
InviaDati()
End If
End Sub
Praticamente al posto del CTS uso l'evento "DataReceived": quando ricevo un carattere "K" chiamo la sub InviaDati. In questo modo l'applicazione è libera e risponde SEMPRE. Però preferirei usare la condizione sul CTS ^^"
Potresti farmi un semplice esempio di quello che intendi? Sai, non sono molto ferrato in questo campo e non uso da molto VB 2005 ^^"
Se non ricordo male l'evento serialPort.PinChanged ha un parametro che identifica il tipo di segnale che è cambiato (e.EventType). Verifica che la tua funzione sia chiamata solo quando e.EventType = CtsChanged (magari aiutandoti con un'interfaccia a semafori per vedere quando cambia di stato). Dai un'occhiata a msdn (ad esempio qui (http://msdn2.microsoft.com/en-us/library/system.io.ports.serialpinchange.aspx)) per maggiori info.
Capello82
21-04-2008, 10:12
Ho trovato il CTSChanged e quindi il codice è diventato il seguente:
Public Delegate Sub PinChangeDelegate()
Public Sub updatePin()
Application.DoEvents()
If IO.Ports.SerialPinChange.CtsChanged And send_complete = False Then
Threading.Thread.Sleep(100)
InviaDati()
End If
End Sub
Il risultato purtroppo è lo stesso :muro: anche se non so quanto sia attendibile la prova che ho fatto: purtroppo qui non ho la macchina con cui devo comunicare, quindi facevo cambiare il CTS direttamente sul cavetto ^^" Di per sé funziona: viene chiamata la sub "InviaDati" appena faccio cambiare il CTS, ma quando è in attesa, l'applicazione è sempre bloccata :(
Se per caso fosse bloccante (non e' da escludersi, anche se strano), potresti provare a ipotizzare di mettere quella parte in un thread separato.
Capello82
21-04-2008, 10:46
Se per caso fosse bloccante (non e' da escludersi, anche se strano), potresti provare a ipotizzare di mettere quella parte in un thread separato.
Con i thread ci ho litigato purtroppo... anche se so che risulterebbe molto utile, ma non so bene come fare. Ora ci penso su un po' :)
Capello82
22-04-2008, 08:49
Ma è possibile mettere il seguente codice:
Private Sub PinChange(ByVal sender As Object, ByVal e As System.IO.Ports.SerialPinChangedEventArgs) Handles serialPort.PinChanged
Me.Invoke(New PinChangeDelegate(AddressOf updatePin), New Object() {})
End Sub
Public Delegate Sub PinChangeDelegate()
Public Sub updatePin()
Application.DoEvents()
If serialPort.CtsHolding = False And send_complete = False Then
Threading.Thread.Sleep(100)
X_COORD.Text = XCOORD
Y_COORD.Text = YCOORD
InviaDati()
End If
End Sub
in un thread eseguito in background? Non ci riesco :muro:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.