Porta seriale ReadLine vs ReadExisting o come leggere correttamente i dati dalla porta seriale
-
10-07-2019 - |
Domanda
Sto leggendo i dati dalla porta seriale. I dati vengono fuori scala. Ora sto usando Readline ()
e sto facendo cadere i dati anche dopo aver rimosso DiscardInBuffer ()
.
Qual è il modo corretto di leggere i dati dalla porta seriale? Ci sono così pochi esempi online che sento che è come un santo graal che nessuno ha capito.
Qualche aiuto per favore?
Sembra che la porta seriale sia un bambino capriccioso.
C #, WinCE 5.0, thin client HP, Compact framework 2.0
private void WeighSample()
{
this._processingDone = false;
this._workerThread = new Thread(CaptureWeight);
this._workerThread.IsBackground = true;
this._workerThread.Start();
} //end of WeighSample()
private void CaptureWeight()
{
globalCounter++;
string value = "";
while (!this._processingDone)
{
try
{
value = this._sp.ReadLine();
if (value != "")
{
if (value == "ES")
{
_sp.DiscardInBuffer();
value = "";
}
else
{
this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
}
}
}
catch (TimeoutException)
{
//catch it but do nothing
}
catch
{
//reset the port here?
MessageBox.Show("some other than timeout exception thrown while reading serial port");
}
}
} //end of CaptureWeight()
Una cosa da notare sulla mia applicazione è che inizio il thread (pesa Campione) quando il cursore salta sulla casella di testo. La ragione di ciò è che il peso può anche essere digitato manualmente (parte del req). Quindi non so in anticipo se un utente deve premere STAMPA sulla bilancia o digitare il peso. In entrambi i casi dopo l'acquisizione dei dati, esco dal thread di lavoro. Inoltre, si noti che non sto utilizzando DataReceived evento porta seriale, poiché mi è stato detto che non è affidabile.
Eventuali commenti / idee sono benvenuti. Questa è la mia prima esperienza con le porte seriali.
Soluzione
Non ho mai mai avuto fortuna con il funzionamento di ReadLine. Basta fare una lettura in un buffer locale ogni volta che sono disponibili i dati e quindi utilizzare un thread separato per scansionare i dati e trovare le interruzioni di riga.
Altri suggerimenti
Dipende da quale carattere (i) di fine riga (EOL) è per i dati di input. Se i tuoi dati sono orientati alla linea, ReadLine è una funzione valida da utilizzare, ma potresti voler esaminare la proprietà NewLine ed essere sicuro che sia impostato in modo appropriato per i tuoi dati di input.
Ad esempio, se la bilancia genera un avanzamento di riga per EOL, imposta port.NewLine = " \ n " ;;
http://msdn.microsoft. com / it-it / library / system.io.ports.serialport.newline.aspx
Vorrei commentare Elias Santos ma non ho abbastanza reputazione. Ci sono alcuni aspetti positivi nell'uso del metodo ReadExisting:
https : //msdn.microsoft.com/en-us/library/system.io.ports.serialport.readexisting (v = vs.110) aspx
Nota che questo metodo può lasciare byte iniziali finali nel file buffer interno, che rende il valore BytesToRead maggiore di zero.
Ho già riscontrato alcuni problemi con ReadExisting e questo è dovuto ai byte indesiderati. L'uso di Readline ha risolto questi problemi.
if (serialPort1->IsOpen){
if (serialPort1->BytesToRead>0){
this->textBox1->Text += serialPort1->ReadExisting();
}
}