2012-12-06 4 views
20

Ich habe hier eine Menge Fragen darüber gelesen, wie man Daten von seriellen Ports mit der .NET SerialPort Klasse liest, aber keiner der empfohlenen Ansätze hat sich für mich als vollkommen effizient erwiesen. HierWie kann man einen seriellen Port mit .NET Framework korrekt lesen?

ist der Code, den ich jetzt bin mit:

SerialPort port = new SerialPort("COM1"); 
port.DataReceived += new SerialDataReceivedEventHandler(MyDataReceivedHandler); 

Und der Event-Handler:

void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    int count = port.BytesToRead; 
    byte[] ByteArray = new byte[count]; 
    port.Read(ByteArray, 0, count); 
} 

Aber ich bin immer noch einige Daten fehlen manchmal. Ich habe versucht, die Daten im Event-Handler anders zu lesen, aber ohne Glück.

Da das .NET 4.5 neue Möglichkeiten bringt, einige asynchrone Aufgaben zu erledigen, wie die Methode ReadAsync, die für einen SerialPort-Stream verwendbar zu sein scheint, bin ich gespannt, welche Methode für diese Fälle empfohlen wird.

+3

Ihre Frage ist sehr vage. "Ich vermisse manchmal noch einige Daten" ist so, als würde ich Ihrem Mechaniker sagen "mein Auto macht manchmal ein komisches Geräusch" und fragt, wie viel es kostet, es zu reparieren. Vielleicht könnte [diese Antwort] (http://stackoverflow.com/a/2966357/62576) zu einer verwandten Frage helfen. Ich denke jedoch, dass Sie viel spezifischer sein müssen, wenn Sie Hilfe benötigen; so wie es ist, gibt es nicht viele, die nicht beantwortet werden können, wenn man sich andere Fragen zu diesem Thema ansieht. –

+0

Sie haben recht, ich werde ein reales Beispiel zusammenstellen, um besser zu veranschaulichen, was passiert ... –

+3

Die Implementierung eines seriellen Kommunikationsprotokolls über RS232 oder 485 ist eine wirklich, wirklich harte Aufgabe. Es erfordert viel Erfahrung. Ich habe dies seit guten alten DOS-Tagen implementiert und stehe immer noch in einigen üblichen Fallen. Warum versuchen Sie nicht, ein zuverlässiges Angebot von Drittanbietern für den Umgang mit der seriellen Kommunikation zu finden? Sie werden wahrscheinlich all die vielen, vielen, vielen Bugs gebügelt haben, die Sie in sich selbst fallen lassen werden :-) Wenn das eine Übung ist, dann machen Sie weiter mit der großen Zufriedenheit, endlich die serielle Kommunikation zu meistern! :-) – Loudenvier

Antwort

14

Könnten Sie versuchen, so etwas wie dies zum Beispiel denke ich, was Sie wollen, sind zu nutzen, ist die port.ReadExisting() Methode

class SerialPortProgram 
{ 
    // Create the serial port with basic settings 
    private SerialPort port = new SerialPort("COM1", 
     9600, Parity.None, 8, StopBits.One); 
    [STAThread] 
    static void Main(string[] args) 
    { 
     // Instatiate this 
     class new SerialPortProgram(); 
    } 

    private SerialPortProgram() 
    { 
     Console.WriteLine("Incoming Data:"); 
     // Attach a method to be called when there 
     // is data waiting in the port's buffer 
     port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); 
     // Begin communications 
     port.Open(); 
     // Enter an application loop to keep this thread alive 
     Application.Run(); 
    } 

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     // Show all the incoming data in the port's buffer 
     Console.WriteLine(port.ReadExisting()); 
    } 
} 

Oder Sie es tun wollen auf das, was Sie versuchen, zu tun, können Sie versuchen, dieses

public class MySerialReader : IDisposable 
{ 
    private SerialPort serialPort; 
    private Queue<byte> recievedData = new Queue<byte>(); 

    public MySerialReader() 
    { 
    serialPort = new SerialPort(); 
    serialPort.Open(); 
    serialPort.DataReceived += serialPort_DataReceived; 
    } 

    void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e) 
    { 
    byte[] data = new byte[serialPort.BytesToRead]; 
    serialPort.Read(data, 0, data.Length); 
    data.ToList().ForEach(b => recievedData.Enqueue(b)); 
    processData(); 
    } 

    void processData() 
    { 
    // Determine if we have a "packet" in the queue 
    if (recievedData.Count > 50) 
    { 
     var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue()); 
    } 
    } 

    public void Dispose() 
    { 
     if (serialPort != null) 
     { 
      serialPort.Dispose(); 
     } 
    } 
+1

Danke für deine Hilfe, ich ging schließlich mit 'ReadExisting' mit einer blockierenden Sammlung. Ich plane immer noch, die neue 'ReadAsync' Funktion zu versuchen, obwohl ... –

+0

nicht die Methode processData() einen Mutex benötigt? Ich meine, das Datenempfangs-Ereignis könnte erneut ausgelöst werden, wenn die ProcessData() noch läuft? nicht wahr? Wir könnten also zwei (oder sogar mehr?) Threads haben, die innerhalb der processData() -Methode laufen. –

+0

Ich habe es nicht in diesem Ausmaß versucht und basierend auf dem, was Yannick in seinem Kommentar erwähnt hat, denke ich, dass es so wäre macht keinen Unterschied, wenn er mit dem Lesen von Asynchron fortfahren würde – MethodMan

4

ich ähnlichen Code zu @MethodMan verwendet, aber ich hatte den Überblick über die Daten die serielle Schnittstelle halten wurde das Senden und für ein abschließendes Zeichen aussehen zu wissen, wenn die serielle Schnittstelle erfolgen sendete Daten.

private string buffer { get; set; } 
private SerialPort _port { get; set; } 

public Port() 
{ 
    _port = new SerialPort(); 
    _port.DataReceived += new SerialDataReceivedEventHandler(dataReceived); 
    buffer = string.Empty; 
} 

private void dataReceived(object sender, SerialDataReceivedEventArgs e) 
{  
    buffer += _port.ReadExisting(); 

    //test for termination character in buffer 
    if (buffer.Contains("\r\n")) 
    { 
     //run code on data received from serial port 
    } 
} 
0

Ich denke, verwenden Sie kein SerialDataReceivedEvent. Timer ist einer der besseren wählen, und nach einer konstanten Zeit, um Daten zu empfangen:

For i = 1 To Me.objSerialPort.BytesToRead 
    strReceiveData &= Convert.ToChar(Me.objSerialPort.ReadByte) 
Next i 
Verwandte Themen