VB NET Ricezione parziale s porta seriale

venerdì 27 marzo 2020 - 19.38
Tag Elenco Tags  VB.NET

BepC Profilo | Newbie

Ciao a tutti,
per le comunicazioni seriali avevo sempre fatto ricorso all'evento DataReceived della classe SerialPort, non sono mai stato un'aquila, ma il tutto funzionava abbastanza.
Ora sto rimettendo mano ad alcune librerie con cui gestivo la comunicazione con alcuni dispositivi ed ho provato ad evitare questo evento che, pare, sia piuttosto deprecato a causa dell'incertezza del suo effettivo scatenamento.
Quindi ho provveduto a modificare alcune cose applicando alcuni esempi osservati in giro.
Il problema si manifesta quando il dispositivo collegato m'invia una stringa superiore ai 4 caratteri, talvolta ne ricevo 5, talvolta 7 e mai completi.
Inquadro meglio:
Invio una stringa di comando
il dispositivo risponde con una stringa che termina con CR LF
Se ho inviato un check per capire se c'è, ottengo un "OK" seguito da CR LF e tutto fila liscio
Se invece mando un'interrogazione circa altre informazioni (es numero di serie) dovrei ottenere una cosa tipo "0000,000000" seguito da CR LF; invece mi perviene magari solo "00??" oppure altro, ma mai la stringa completa e mai la terminazione CR LF.
Il codice non è complicatissimo (si tratta di un test)
Premetto le impostazioni della porta: 9600 N81 Timeout lettura e scrittura InfiniteTimeout (non lo uso perché interrompo io il ciclo)
Qui il codice (molto semplice, ripeto per testing, poi verrà messo nei dovuti thread ecc.)

Private Shared Function GetmeInfo(PortaSeriale As IO.Ports.SerialPort, WriteTout As Integer, ReadTout As Integer, Cmd As String, ByRef Risultato As String) As Boolean
Dim TimeOutCounter As Integer = 0
Dim LocalBuffer As New System.Text.StringBuilder
Dim c As String = ""
Try
PortaSeriale.Write(String.Format("{0}{1}", Cmd, Chr(13)))
Catch ex As Exception
Return False
End Try
Threading.Thread.Sleep(WriteTout)
While True
While PortaSeriale.BytesToRead > 0
c = Chr(PortaSeriale.ReadChar)
If c = Chr(13) Then
Risultato = LocalBuffer.ToString
Return True
Else
LocalBuffer.Append(c)
End If
End While
Threading.Thread.Sleep(10)
TimeOutCounter = TimeOutCounter + 10
If TimeOutCounter > ReadTout Then
Return False
End If
End While
Return True
End Function

Non ci sono santi, 'sto buffer non riceve tutto, anche se modifico i tempi di attesa espandendoli a due o tre secondi (un'eternità).
Va da sé che il dispositivo funziona e che usando qualcosa tipo RealTerm ottengo sempre risposte corrette.
Grazie a tutti in anticipo
Beppe
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5