Zdarzenie .NET SerialPort DataReceived nie zostało uruchomione


Mam aplikację testową WPF, aby ocenić komunikację zdarzeń portu szeregowego (w porównaniu do badania portu szeregowego). Problem polega na tym, że wydarzenie Datareceped w ogóle nie działa.
Mam bardzo prosty formularz WPF z TextBox do wprowadzania danych przez użytkownika, TextBlock do wyjścia i przyciskiem do zapisywania danych wejściowych do portu szeregowego.
Oto kod:
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);
}
}

Więc oto czynniki komplikujące:
  • Laptop, nad którym pracuję, nie ma portów szeregowych, więc używam oprogramowania o nazwie Virtual Serial Port Emulator do konfiguracji COM2. VSPE działało dobrze w przeszłości i nie jest jasne, dlaczego miałoby działać tylko z klasą .NET SerialPort, ale wspominam o tym na wszelki wypadek.
  • Kiedy klikam przycisk w moim formularzu, aby przesłać dane, okno programu HyperTerminal (połączone z portem COM2) pokazuje, że dane są przetwarzane. Tak, wyłączam program hyperterminal, gdy chcę przetestować zdolność mojego formularza do odczytu portu.
  • Próbowałem otworzyć port przed podłączeniem zdarzenia. Bez zmian.

Przeczytałem tutaj kolejny post, w którym ktoś inny ma podobny problem. Żadna z tych informacji nie pomogła mi w tej sprawie.

EDIT

:
Oto wersja konsoli (zmieniona z

http://mark.michaelis.net/Blog ... Port. aspx
http://mark.michaelis.net/Blog ... .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);
}
}

Powinno to usunąć wszelkie obawy, że jest to problem z przesyłaniem strumieniowym (myślę). To też nie działa. Ponownie Hyperterminal zgłasza dane przesłane przez port, ale aplikacja konsoli nie wydaje się uruchamiać zdarzenia DataReceived.

EDIT #2:

Zdałem sobie sprawę, że mam dwie osobne aplikacje, które muszą jednocześnie wysyłać i odbierać z portu szeregowego, więc postanowiłem spróbować uruchomić je w tym samym czasie ...
Jeśli wpiszę aplikację konsolową, zdarzenie DataReceived aplikacji WPF zostanie wyzwolone z oczekiwanym błędem przesyłania strumieniowego (z którym wiem, jak sobie radzić).
Jeśli wpiszę aplikację WPF, zdarzenie aplikacji konsoli DataReceived jest wyzwalane i powtarza dane.
Myślę, że problem leży gdzieś w używaniu oprogramowania VSPE, które jest skonfigurowane do obsługi pojedynczego portu szeregowego zarówno dla wejścia, jak i wyjścia. Ze względu na dziwne cechy klasy SerialPort, pojedyncza instancja portu szeregowego nie może być jednocześnie nadawcą i odbiorcą. W każdym razie myślę, że problem został rozwiązany.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

port.DtrEnable = true;

To rozwiązało problem dla mnie, flaga DataTransmitReady nie była włączona, więc żadne dane nie zostały odebrane.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie mogę powiedzieć na pewno, ale może być problem z wątkami. WPF obsługuje strumienie inaczej, a odpytywanie portu wirtualnego jest asynchroniczne, jak przypuszczam. Czy próbowałeś tego z Windows Forms lub aplikacją konsoli, aby udowodnić, że w ogóle może działać?
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Używam dokładnie tej samej konfiguracji, teraz działa świetnie, ale musiałem rozwiązać wiele problemów, aby się tam dostać.
Oto dlaczego moje wstępne stwierdzenie wygląda następująco:
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);

Oddzieliłem metody open port i close port, ponieważ często sprawdzam, czy plik com.
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
}
}

Na koniec upewnij się, że twój sterownik portu wirtualnego Com jest poprawnie zainstalowany i że używasz właściwego portu, funkcja plug and play nie była wystarczająca dla mojej karty. Jeśli chcesz stworzyć jakąś kontrolę, która pozwoli ci wybrać porty dostępne w czasie wykonywania, poniższe polecenie da ci dostępne porty:
System.IO.Ports.SerialPort.GetPortNames()
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Mogę tylko założyć, że problem naprawdę dotyczył emulatora wirtualnego portu szeregowego. NIE oznacza to, że jest problem z tym oprogramowaniem: VSPE do tej pory działało bardzo dobrze. Ale był pewien konflikt między moim kodem a sposobem, w jaki skonfigurowałem złącze VSPE.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Podobny problem miałem też uruchamiając taki sterownik z formularza, choć nie ma VSPE, tylko zwykły SP.
Wydaje mi się, że był to problem z modelem STA, ponieważ przeniesienie go do aplikacji konsolowej zostało dość naprawione.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Niedawno napotkałem ten sam dziwny problem, ale tylko na niektórych komputerach. Jak zaznaczono

Dave.
https://stackoverflow.com/users/34796/dave-swersky
Powolny, może to być problem z strumieniowo, zwłaszcza jeśli używasz .NET 4.0 lub nowszego.
W programie .NET 4.0 program obsługi zdarzeń działa w puli wątków iw pewnych okolicznościach może wystąpić znaczne opóźnienie, zanim to nastąpi. (W moim kodzie, który działał dobrze pod .NET 2.0, problemy zostały zauważone zaraz po uaktualnieniu do .NET 4.5. Program obsługi zdarzeń często uruchamiał się znacznie później, niż oczekiwano, a czasami w ogóle nie działał!)
Połączenie
ThreadPool.SetMinThreads(...)
http://msdn.microsoft.com/en-u ... .aspx
przy wysokiej wartości dla wątków uzupełniających problem znikał tak szybko, jak się pojawił. W kontekście naszej aplikacji wystarczył
ThreadPool.SetMinThreads (2, 4)
. Na maszynach, na których zaobserwowano problem, wartości domyślne (uzyskane przez wywołanie
ThreadPool.SetMinThreads
http://msdn.microsoft.com/en-u ... s.aspx) były równe 2.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ja też używam VSPE! To naprawdę działa świetnie. Miałem ten sam problem i naprawiłem go, tworząc dwa porty com PAIR w VSPE zamiast po prostu tworzyć dwa wirtualne porty com
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dwa dni temu miałem ten sam problem, a to był duży ból głowy, ponieważ musiałem dziś dostarczyć aplikację. Więc ... Po za dużo Google zasugerowałem, że problem był w drugim, a nie w moim kodzie.
Moje rozwiązanie było

Kasować

McAfee Antivirus i wszystko, co jest z nim związane. Kiedy zobaczyłem magazyny McAfee, mieli rekordy na temat zatrzymywania strumieni, a ja zasugerowałem, że serialdatareceteDeventhandler () działa w strumieniu.
Mam nadzieję, że to rozwiązanie zadziała dla Ciebie. Z poważaniem.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Używam wirtualnego sterownika portu szeregowego. Ten problem zajmuje mi cały dzień. Na koniec napraw to, tworząc kilka portów. Jeden port wysyła wiadomość, a drugi odbiera wiadomość zamiast używać tego samego portu do wysyłania i odbierania wiadomości. Myślę, że tak działa emulator modemu zerowego.
Dim mySerialPort As SerialPort = New SerialPort("COM1")
Dim mySerialPort2 As SerialPort = New SerialPort("COM2")Sub Main()
SerialPortCommunicate()
End SubPublic Sub SerialPortCommunicate()
mySerialPort.BaudRate = 9600
mySerialPort.Parity = Parity.None
mySerialPort.StopBits = StopBits.One
mySerialPort.DataBits = 8
mySerialPort.Handshake = Handshake.None
mySerialPort.DtrEnable = True
mySerialPort.RtsEnable = True mySerialPort2.BaudRate = 9600
mySerialPort2.Parity = Parity.None
mySerialPort2.StopBits = StopBits.One
mySerialPort2.DataBits = 8
mySerialPort2.Handshake = Handshake.None
mySerialPort2.DtrEnable = True
mySerialPort2.RtsEnable = True AddHandler mySerialPort2.DataReceived, AddressOf DataReceivedHandler mySerialPort.Open()
mySerialPort2.Open() mySerialPort.Write("Hello World") Console.WriteLine("Press any key to continue...")
Console.WriteLine()
Console.ReadKey()
mySerialPort.Close()
mySerialPort2.Close()
End SubPrivate Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs)
Dim sp As SerialPort = CType(sender, SerialPort)
Dim indata As String = sp.ReadExisting()
Console.WriteLine("Data Received:")
Console.Write(indata)
End Sub

Wynik:
Otrzymane dane:
cześć wszystkim
Naciśnij dowolny klawisz, aby kontynuować ...

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się