2009-03-11 25 views
10

Estoy leyendo datos del puerto serie. Los datos salen de la escala. Ahora estoy usando Readline() y obteniendo datos incluso después de eliminar DiscardInBuffer(). ¿Cuál es la forma correcta de leer los datos del puerto serie? Hay tan pocos ejemplos en línea que siento que es como un Santo Grial que nadie ha descubierto.Puerto serie ReadLine vs ReadExisting o cómo leer los datos del puerto serie correctamente

¿Alguna ayuda, por favor?

Parece que el puerto serie es un niño caprichoso.

C#, mueca de dolor 5.0, HP thin client, 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 a tener en cuenta sobre mi solicitud es que empiezo el hilo (weighSample) cuando el cursor salta a la caja de texto. La razón para esto es que el peso también se puede escribir manualmente (parte de las req). Por lo tanto, no sé de antemano si un usuario va a presionar IMPRIMIR en la balanza o escribir el peso. En cualquier caso, después de que se adquieran los datos, salgo del hilo de trabajo. Además, tenga en cuenta que no estoy utilizando el evento de puerto serie DataReceived, ya que me dijeron que no es confiable.

Cualquier comentario/ideas de bienvenida. Esta es mi primera experiencia con puertos seriales.

+0

¿Qué idioma, sistema operativo, plataforma de hardware, etc.? – MarkusQ

+0

¿Qué tipo de datos estás leyendo? ¿Binario? ¿Texto? – Eddie

+0

Estoy leyendo datos de texto – sarsnake

Respuesta

4

tengo no tuvieron suerte con ReadLine de trabajo. Simplemente haga una lectura en un búfer local cuando los datos estén disponibles y luego use un hilo separado para escanear los datos y encontrar saltos de línea usted mismo.

+0

pregunta rápida: he sondeado la escala que ya se está ejecutando en el hilo existente. ¿Todavía necesito un hilo separado para escanear los datos? publicaré el código cuando llegue al trabajo. – sarsnake

+0

Generalmente enciendo un hilo de trabajo que hace las lecturas del puerto y los coloca en un buffer de aplicación. Cuando coloca datos en el búfer, establece un evento que señala el hilo del analizador para ir a buscar líneas de datos y luego elevar otro evento a la aplicación de consumo. Es posible que ya tengas uno de estos. – ctacke

+0

por lo que en total tiene 2 hilos: un hilo principal y un hilo trabajador? ¿Cuál es la diferencia entre el comportamiento de bloqueo y no bloqueo? ¿Está el bloqueo de lectura()? – sarsnake

8

Depende de qué carácter (s) de final de línea (EOL) es para sus datos de entrada. Si sus datos están orientados a la línea, ReadLine es una función válida que debe usar, pero es posible que desee examinar la propiedad NewLine y asegurarse de que esté configurada correctamente para sus datos de entrada.

Por ejemplo, si sus salidas escala salto de línea EOL para luego establecer port.NewLine = "\n";

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.newline.aspx

+0

¿Qué depende de la configuración del dispositivo? – sarsnake

+0

Estoy leyendo los datos de la escala. ¿Este valor (Newline) tiene que corresponderse con el formato de escala en este caso? Ahora estoy configurado para \ r \ n que es el estándar. – sarsnake

+0

Muchas gracias. Uso el .NewLine establecido en "\ r" porque el escáner me lo envía al final y con .ReadLine() obtengo exactamente lo que esperaba. Excelente solución. –

0
if (serialPort1->IsOpen){ 
    if (serialPort1->BytesToRead>0){ 
     this->textBox1->Text += serialPort1->ReadExisting(); 
    } 
} 
+0

Explique por qué cree que esta respuesta de solo código ayuda a resolver la pregunta. – PMF

1

Me gustaría comentar a Elias Santos pero no tengo suficiente reputación. Hay también algunas precauciones al usar el método ReadExisting:

https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readexisting(v=vs.110).aspx

Tenga en cuenta que este método puede dejar bytes finales de plomo en el búfer interno , lo que hace que el valor BytesToRead mayor que cero.

He enfrentado algunos problemas con ReadExisting antes y esto se debe a los bytes no deseados. El uso de Readline solucionó esos problemas.

+1

Tenga en cuenta que está bien agregar otra respuesta disputando otra siempre que dé otra sugerencia y la formatee como una respuesta, lo cual ha hecho. – cybermonkey

Cuestiones relacionadas