2010-02-17 16 views
5

tetiklenmediğini I (yoklama vs seri port) olay tabanlı seri port iletişimi değerlendirmek için bir WPF test uygulaması var. Sorun şu ki DataReceived olayı hiç ateş etmiyor gibi görünüyor. .NET SerialPort DataReceived olay

Ben

kullanıcı girişi için bir TextBox, çıkış için bir TextBlock ve seri port girişi yazmak için bir düğme ile bir çok temel WPF form var. İşte

kod: Şimdi

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); 
    } 
}

, burada zorlaştıran faktörler şunlardır:

  1. Ben hiçbir seri bağlantı noktası vardır çalışıyorum dizüstü, bu yüzden bir parça arasında kullanıyorum COM2 kurmak için Virtual Serial Port Emulator yazılımı denir. VSPE geçmişte takdire şayan bir şekilde çalıştı ve neden sadece .NET'in SerialPort sınıfında arızalanabileceği net değil, fakat durumun sözünü ettim. Ben veri göndermek için benim formdaki düğme vurduğunda

  2. , (COM2 üzerinde bağlı) benim HyperTerminal pencere verileri elde ettiğini göstermektedir. Evet, formumun bağlantı noktasını okuma yeteneğini test etmek istediğimde Hyperterminal'in bağlantısını kesiyorum.

  3. Ben olayı kablolama önce port açarak denedim. Değişiklik yok.

Başka birinin burada benzer bir sorunu olduğu başka bir gönderi okudum. Bu bilginin hiçbiri bu durumda bana yardımcı olmadı.

DÜZENLEME:

İşte (http://mark.michaelis.net/Blog/TheBasicsOfSystemIOPortsSerialPort.aspx değiştirilmiş) konsol versiyonu: Bu da Threading sorun (Sanırım) olduğunu herhangi bir endişe ortadan kaldırmak gerekir

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); 
    } 
}

. Bu da işe yaramıyor. Yine, Hyperterminal bağlantı noktası aracılığıyla gönderilen verileri raporlar, ancak konsol uygulaması DataReceived olayını tetiklemiyor gibi görünüyor.

DÜZENLEME # 2:

ben göndermek ve seri porttan almalı hem iki ayrı uygulamanın gerektiğini anladı, bu yüzden aynı anda çalıştıran denemeye karar verdi ...

I Eğer Konsol uygulamasına, WPF uygulaması DataReceived olayı, beklenen iş parçacığı hatasıyla (nasıl başa çıkılacağını bildiğim) yazılır.

WPF app, konsol uygulaması DataReceived olay yangınlar içine yazın ve veriyi yankıları edin. Sorunu tahmin ediyorum

giriş ve çıkış hem de bir seri portu tedavisinde kurulur VSPE yazılımı, benim kullanımı yerdedir. Ve SerialPort sınıfının bazı gariplikleri sayesinde, bir seri portun bir örneği hem gönderici hem de alıcı olamaz. Her neyse, sanırım çözüldü.

cevap

0

Ben sadece tahmin edebiliriz: Eğer çalışma sırasında bulunması portları almak sağlayacak bir nevi kontrolünü oluşturmak istiyorsanız, aşağıdaki komutu kullanılabilir bağlantı noktaları size verecektir Seri Port Emulator programı. Bu yazılımla ilgili bir sorun olduğunu söyleyemem: VSPE şimdiye kadar benim için çok iyi çalıştı. Ancak kodum ile VSPE konektörünü nasıl kurduğum arasında bir çelişki vardı.

3

Kesin olarak söyleyemem ama bir iş parçacığı sorunu olabilir. WPF, iş parçacığını farklı şekilde ele alır ve sanal bağlantı noktasının yoklaması eşzamanlı değildir. Bunu hiç işe yarayabildiğini kanıtlamak için bir Windows Forms veya konsol uygulamasıyla denediniz mi?

+0

Yukarıdaki konsol sürümüne bakın. Şanssız. – Klay

2

Aynı kurulumu kullanıyorum, şimdi mükemmel çalışıyor ancak oraya ulaşmak için birçok sorunu çözmek zorunda kaldım. com portu kapalı olup olmadığını ben sık sık kontrol beri

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); 

Ben açık port ve yakın liman yöntemleri ayrılmış: my ön açıklama benziyor nedeni işte

olduğunu.

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 
    } 
} 

Son olarak, sanal Com Port sürücüsü düzgün yüklendiğini doğrulamak ve doğru port, bir eklenti kullandığınızı ve benim adaptör yeterli değildi için oynarlar. Sorun Sanal ile gerçekten olduğunu

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

Düzenlemenizi yaptıktan sonra, bazı kıvrımlar çalıştığınızı görüyorsunuz, ancak siz "SerialPort sınıfının bazı gariplikleri sayesinde, bir seri portun bir örneği hem gönderen hem de alıcı olamaz" şeklinde konuştu. Bu doğru değil. SerialPort sınıfı hem gönderen hem de alıcı olabilir. Her şey bir şekilde antrenman yapıyor gibi görünüyor yana, ben ayrıntılı değil :) – Roast

+0

Peki o zaman kesinlikle gariplik SerialPort sınıfında değil, sanal seri port yazılımı ile birleştirme içinde olduğu gibi geliyor. – Klay

+0

+1 - RTS pinini Etkin olarak ayarlamak, unuttuğum bir şeydi. Donanım akış kontrolünü unuttum. –

0

Böyle bir sürücüyü bir Formdan çalıştırırken de benzer bir sorunla karşılaştım, ancak VSPE sadece düz SP. Bunun bir STA modeli sorunu, sabit bir konsol uygulamasına dahil edilmek üzere taşınması gerektiğine inanıyorum.

0

VSPE'yi de kullanıyorum! Bu harika çalışıyor .. Ben de aynı sorunu yaşıyordum ve ben bu iki com portları sadece iki sanal com bağlantı noktaları oluşturmak yerine VSPE içinde bir ÇİFT yapmak

0

Son zamanlarda benzer garip bir problemle karşılaştım ama sadece bazı makinelerde. Dave Swersky belirtildiği gibi, özellikle .NET 4.0 veya sonraki sürümleri altında çalışıyorsanız, bu bir iş parçacığı sorun olabilir.

.NET 4.0'da, olay işleyicisi bir ThreadPool iş parçacığı üzerinde tetiklenir ve belirli koşullar altında, bu gerçekleşmeden önce önemli bir gecikme olabilir. (.NET 2.0 altında tam olarak çalışmış olan kodumda, .NET 4.5'e yükselttiğimizde sorunlar gözlemlendi. Olay işleyicisi genellikle beklenenden çok daha sonra tetiklenecek ve bazen tetiklenmeyecekti. all!)

ThreadPool.SetMinThreads(...) numaralı telefonun çağrılması tamamlanma iplikleri için daha büyük bir değere sahip olarak, sorun geldiği andan itibaren kayboldu. Uygulamamızın içeriğinde ThreadPool.SetMinThreads(2, 4) yeterliydi. (ThreadPool.SetMinThreads arayarak elde gibi) sorun, varsayılan değerler gözlenmiştir makinelerde hiçbir veri alındığı, bu benim için çözülmüş hem 2.

7
port.DtrEnable = true; 

, DataTransmitReady bayrağı etkin değildi idi.

+1

Bu, bir tablete bağlı bir balans ile 5 saat çalkantılı saatin ardından da benim için çalıştı. Bir şirketin dengesi (OHaus) bu hat olmadan gayri resmi olarak iletişim kuruyordu, bir sonraki şirketin dengesi (Sartorius) değildi. – jaredbaszler

0

İki gün önce aynı problemi yaşadım ve büyük bir baş ağrıyordu çünkü uygulamayı bugün vermem gerekiyordu. Yani .. çok fazla googleashion sonra konu başka bir şey olduğunu ve benim kodum olduğunu varsayalım.

Benim çözümüm, idi, McAfee antivirüs ve bununla ilgili her şeyi kaldırın. McAfee'nin günlüklerini gördüğümde durma iş parçacıkları hakkında kayıtlar vardı ve ben SerialDataReceivedEventHandler() iş parçacığı içinde çalıştığını varsaydım.

Umarım bu çözüm sizin için çalışır. Saygılarımızla.