PDA

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?

dvbman
19-04-2008, 16:24
edit

Capello82
19-04-2008, 19:05
edit

uh? O.o

dvbman
19-04-2008, 21:50
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

gugoXX
20-04-2008, 09:19
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 ^^"

dvbman
20-04-2008, 19:29
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 :(

gugoXX
21-04-2008, 10:29
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: