2010-02-17 26 views
5

Tengo una aplicación de prueba WPF para evaluar la comunicación de puerto serie basada en eventos (frente al sondeo del puerto serie). El problema es que el evento DataReceived parece no estar funcionando en absoluto..NET SerialPort Evento DataReceived que no se activa

Tengo un formulario WPF muy básico con un TextBox para la entrada del usuario, un TextBlock para la salida, y un botón para escribir la entrada al puerto serie.

Aquí está el código:

public partial class Window1 : Window 
{ 
    SerialPort port; 

    public Window1() 
    { 
     InitializeComponent(); 

     port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 
     port.DataReceived += 
      new SerialDataReceivedEventHandler(port_DataReceived); 
     port.Open(); 
    } 

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     Debug.Print("receiving!"); 
     string data = port.ReadExisting(); 
     Debug.Print(data); 
     outputText.Text = data; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Debug.Print("sending: " + inputText.Text); 
     port.WriteLine(inputText.Text); 
    } 
}

Ahora, aquí están los factores que complican:

  1. El portátil que estoy trabajando no tiene puertos serie, así que estoy usando un pedazo de software llamado Virtual Serial Port Emulator para configurar un COM2. VSPE ha trabajado admirablemente en el pasado, y no está claro por qué solo funcionaría mal con la clase SerialPort de .NET, pero lo menciono por las dudas.

  2. Cuando pulso el botón en mi forma de enviar los datos, la ventana de mi Hiperterminal (conectado en COM2) muestra que los datos está llegando. Sí, desconecto Hyperterminal cuando quiero probar la capacidad de mi formulario para leer el puerto.

  3. He intentado abrir el puerto antes de conectar el evento. Ningún cambio.

He leído otra publicación aquí donde alguien más está teniendo un problema similar. Nada de esa información me ha ayudado en este caso.

EDIT:

Aquí está la versión de la consola (modificado de http://mark.michaelis.net/Blog/TheBasicsOfSystemIOPortsSerialPort.aspx):

class Program 
{ 
    static SerialPort port; 

    static void Main(string[] args) 
    { 
     port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 
     port.DataReceived += 
      new SerialDataReceivedEventHandler(port_DataReceived); 
     port.Open(); 

     string text; 
     do 
     { 
      text = Console.ReadLine(); 
      port.Write(text + "\r\n"); 
     } 
     while (text.ToLower() != "q"); 
    } 

    public static void port_DataReceived(object sender, 
     SerialDataReceivedEventArgs args) 
    { 
     string text = port.ReadExisting(); 
     Console.WriteLine("received: " + text); 
    } 
}

Esto debería eliminar cualquier preocupación de que se trata de una cuestión Threading (creo). Esto tampoco funciona. Una vez más, Hyperterminal informa los datos enviados a través del puerto, pero la aplicación de la consola no parece activar el evento DataReceived.

editar # 2:

me di cuenta que tenía dos aplicaciones separadas que se deben enviar y recibir desde el puerto serie, por lo que decidió intentar ejecutar de forma simultánea ...

Si yo escriba en la aplicación de la consola, se dispara el evento DataReceived de la aplicación WPF, con el error esperado de subprocesamiento (que sé cómo manejar).

Si escribo en la aplicación WPF, el evento DataReceived de la aplicación de consola se dispara y se hace eco de los datos.

Supongo que el problema está en alguna parte de mi uso del software VSPE, que está configurado para tratar un puerto serie como entrada y salida. Y a través de algunas rarezas de la clase SerialPort, una instancia de un puerto serie no puede ser tanto el emisor como el receptor. De todos modos, creo que está resuelto.

Respuesta

0

Sólo puedo suponer que el problema era de hecho con el virtual Programa Emulador de puerto serie. esto NO quiere decir que haya un problema con ese software: VSPE me ha funcionado muy bien hasta ahora. Pero hubo algún conflicto entre mi código y cómo configuré el conector VSPE.

3

No puedo asegurarlo, pero podría haber un problema de enhebrado. WPF maneja el enhebrado de manera diferente, y el sondeo del puerto virtual es asincrónico, creo. ¿Has probado esto con una aplicación de Windows Forms o consola para probar que puede funcionar?

+0

Consulte la versión de la consola anterior. Sin suerte. – Klay

2

Uso exactamente la misma configuración, funciona perfectamente ahora pero tuve que resolver muchos problemas para llegar allí.

Aquí es por eso que mi declaración inicial se parece a:

comControl = new SerialPort(); 

//This is important - determine your min nb of bytes at which you will fire your event, mine is 9 
comControl.ReceivedBytesThreshold = 9; 

//register the event handlers 
comControl.DataReceived += new SerialDataReceivedEventHandler(OnReceive); 
comControl.PinChanged += new SerialPinChangedEventHandler(OnPinChanged); 

I seperated el puerto abierto y métodos de puertos cercanos, ya que a menudo verificar si el puerto COM se ha cerrado.

public bool OpenPort() 
{ 
    try 
    { 
     //must keep it open to maintain connection (CTS) 
     if (!comControl.IsOpen) 
     { 
      comControl.Open(); 
      comControl.RtsEnable = true; 
     } 
    } 
    catch (Exception e) 
    { 
     //error handling here 
    } 
} 

Por último, compruebe que el controlador de puerto COM virtual está instalado correctamente y que está utilizando el puerto correcto, un plug and play para mi adaptador no era suficiente. Si desea crear una especie de control que le permitirá elegir los puertos disponibles en tiempo de ejecución, el siguiente comando le dará los puertos disponibles:

System.IO.Ports.SerialPort.GetPortNames() 
+0

Después de su edición, veo que ha resuelto algunas fallas, pero mencionó que "Y a través de algunas rarezas de la clase SerialPort, una instancia de un puerto serie no puede ser tanto el emisor como el receptor" Esto no es cierto. La clase SerialPort puede ser tanto el emisor como el receptor. Ya que afirmas que las cosas parecen funcionar de alguna manera, no elaboraré :) – Roast

+0

Bueno, definitivamente parece que la rareza no está en la clase SerialPort, sino en el acoplamiento con el software del puerto serial virtual. – Klay

+0

+1 - Configurar el pin RTS en habilitado fue algo que olvidé. Me olvidé del control de flujo de hardware. –

0

También he tenido un problema similar al ejecutar dicho controlador desde un Formulario, aunque no VSPE simplemente un SP simple. Creo que esto fue un problema del modelo STA porque se modificó para incluirlo en una aplicación de consola.

0

¡También uso VSPE! Funciona maravillosamente. Estaba teniendo el mismo problema y la forma en que lo arreglé fue para hacer que los dos puertos COM sean PARES en VSPE en lugar de simplemente crear dos puertos virtuales COM

0

Me encontré con un problema igualmente extraño recientemente, pero solo en algunas máquinas. Como se observó en Dave Swersky, esto puede haber sido un problema de subprocesamiento, especialmente si se ejecutaba con .NET 4.0 o posterior.

En .NET 4.0, el controlador de eventos se desencadena en un subproceso de ThreadPool y, en determinadas circunstancias, puede haber un retraso considerable antes de que ocurra. (En mi código, que había estado funcionando perfectamente en .NET 2.0, se observaron problemas tan pronto como nos actualizamos a .NET 4.5. El controlador de eventos a menudo se activaría mucho más tarde de lo esperado, y en ocasiones no se desencadenaría en todo!)

Llamar a ThreadPool.SetMinThreads(...) con un mayor valor para los hilos de terminación hizo que el problema desapareciera tan rápido como había llegado. En el contexto de nuestra aplicación ThreadPool.SetMinThreads(2, 4) fue suficiente. En las máquinas donde se observó el problema, los valores por defecto (como se obtiene llamando ThreadPool.SetMinThreads) eran ambos 2.

7
port.DtrEnable = true; 

Esto resolvió que para mí, la bandera DataTransmitReady no se ha habilitado, por lo que no se ha recibido datos.

+1

Esto funcionó para mí también después de 5 horas laboriosas de jugar con un equilibrio conectado a una tableta. El saldo de una compañía (OHaus) se estaba comunicando bien sin esta línea, el saldo de la siguiente compañía (Sartorius) no. – jaredbaszler

0

Hace dos días tuve el mismo problema y fue un gran dolor de cabeza porque necesitaba entregar la aplicación hoy. Entonces ... después de demasiada googleashion, supuse que el problema era otra cosa y no mi código.

Mi solución es desinstalar McAfee antivirus y todas las cosas relacionadas con esto. Cuando vi los registros de McAfee, tenía registros sobre los hilos de detención y supuse que el SerialDataReceivedEventHandler() se ejecutaba en un hilo.

Espero que esta solución funcione para usted. Saludos.

Cuestiones relacionadas