Forum: PC-Programmierung [C#] Serial Port Abfage fehlerhaft


von Christoph H. (christoph_b)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe ein kleines Programm geschreiben das über den Serial Port einen 
String an ein RFM22B Funk Modul sendet. Das andere Modul empfängt den 
String und sendet ihn als Kontrolle zurück. Dabei soll je nach dem was 
zurück kommt die Farbe des Sende Knopfs geändert werden.

Leider funktioniert die Auswertung des Empfangsstrings nicht so wie ich 
mir das vorstelle. Teilweise wird der String falsch empfangen.

Einen Fehler der RFM Module schließe ich aus da ich wenn ich den String 
über ein Terminal Modul sende auch immer richtig zurückkommt.

Habe das C# Programm einmal angehängt.

Gruß Christoph

von Bernd H. (geeky)


Lesenswert?

Direkt den Rückgabewert von .ReadExisting() zu nehmen macht auch keinen 
Sinn.
Da könnte statt "Messer_ON\n" auch nur "Me" drin stehen und beim 
nächsten Aufruf dann "sser_ON" und später noch "\n".

Du müsstest dir den Rückgabewerte von ReadExisting() an irgendeinen 
String (z.B. "ReceivedUntilNow") dranhängen und diesen nach 
vollständigen Zeilen durchsuchen, z.B. so:
1
// Empfangspuffer
2
        private string ReceivedString = "";
3
4
        private List<string> ExtractCompleteLines()
5
        {
6
            // Vollständige Zeilen sammeln:
7
            List<string> completeLines = new List<string>();
8
9
            // Zeichen in der Zeile bisher:
10
            string currentLine = "";
11
12
            // Aktuellen Empfangspuffer durchgehen:
13
            for (int i=0; i<ReceivedString.Length; i++)
14
            {
15
                if (ReceivedString[i] == '\n')
16
                {
17
                    // Zeilenende gefunden
18
                    // currentLine enthält nun vollständige Zeile                    
19
                    completeLines.Add(currentLine.Trim());
20
                    currentLine = "";
21
                }
22
                else
23
                {
24
                    // Zeichen in currentLine aufsammeln
25
                    currentLine += ReceivedString[i];
26
                }
27
            }
28
29
            // Für Zeichen die jetzt immer noch in currentLine hängen muss ein Zeilenende noch kommen
30
            ReceivedString = currentLine;
31
32
            return completeLines;
33
        }
34
35
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
36
        {
37
            ReceivedString+= serialPort1.ReadExisting();
38
            List<string> RxStrings = ExtractCompleteLines();
39
40
            foreach (string RxString in RxStrings)
41
            {
42
                switch (RxString)
43
                {
44
                    case "Messer_ON\n":
45
                        bt_Messer.BackColor = Color.Red;
46
                        pb_Messer.BackColor = Color.Red;
47
                        maehwerk = false;
48
                        break;
49
...

In ReceivedString wird einfach erstmal alles was so reinkommt 
drangehängt und dient einfach als Puffer.
Die ExtractCompleteLines() geht über ReceivedString drüber und sammelt 
da komplette Zeilen raus (die anschließend in ReceivedString nicht mehr 
drin sind)

btw:
serialPort1_DataReceived läuft NICHT im GUI-Thread!
Auf GUI-Elemente darf aber in der Regel nur vom GUI-Thread zugegriffen 
werden. D.h. z.B. bt_Messer.BackColor = Color.Red kann zu Exceptions 
führen!
siehe z.B.: 
http://www.codeproject.com/Articles/52752/Updating-Your-Form-from-Another-Thread-without-Cre

von Christoph H. (christoph_b)


Lesenswert?

Danke Bernd für die Hilfe. Es klappt nun.

Dachte immer das nur anspringt wenn ein \n ankommt.
Werde mir morgen das mal genauer anschauen und mich bei fragen melden 
:-)

Gruß Christoph

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.