Forum: PC-Programmierung [C#] Serialport Daten auslesen


von Christian (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Gemeinde,

ich versuche gerade zwei 16Bit ADC-Werte aus meinem dsPIC - via 
uart/FTDI RS232 - auszulesen. Leider gestaltet sich das ganze nicht so 
einfach wie erhofft. Um die Daten trennen und unterscheiden zu können 
verwende ich das folgende Format:

Messwert1   0x09    Messwert2     0x3B

Die 16Bit werden vom µC in zwei 8Bit aufgeteilt und verschickt 1. 
Highbyte dann Lowbyte. Die beiden Trennzeichen 0x09 und 0x3B werden 
ebenfalls als 16Bit-Werte versendet also: 0x0009 und 0x003B.

Um die Übertragung zu testen habe ich jeweils 20 Messwerte:

Messwert1 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]

und Messwert2 = Messwert1[i] + 5

Messwert2 = [5,6,7,8,9,10,11,12,13,14,15,....

Generiert und an den PC übertragen wollen.

Beim Test mit hterm sind genau die gewünschten Daten empfangen worden 
(Siehe Bild).

Wenn ich die Daten mit meinem Programm empfangen will kommen (Wie im 
Bild zu sehen "Irgendwelche" Werte heraus b.z.w. mehrmals meine 
verwendeten Trennzeichen).

Dies Bringt mich zu der Annahme, dass ich den serialport-Buffer nicht 
richtig auslese oder sich der Buffer nicht richtig füllt. Baudrate ect. 
ist alles korrekt gefühlt 100 mal überprüft. Auch die Puffergröße 
verändert mal so wie jetzt den recive nach zwei bytes ausgelöst mal nach 
allen 80 Empfangenen...Es kommen immer wieder diese Zeichen in 
undefinierter Reihenfolge und mir scheint zufällig. Bei dem MSDN-Sachen 
finde ich auch keine Hilfe. Ich hoffe einer von Euch weis Rat und kann 
mir weiterhelfen.

Da die Kommunikation über hterm bestens funktioniert gehe ich davon aus, 
dass die dsPIC-Software wie gewünscht funktioniert und ebenso die RS232 
Übertragung zum Rechner.

Mir ist bewusst, dass hier noch kein fertiges Übertragungsprotokoll 
vorliegt und ich hier sehr fehlen durch Verwechselung oder fehlerhafter 
Überdachung eines Zeichens einschleichen können doch dieses kleine 
Programm soll erst einmal dazu dienen die Messwerte einfach aus dem 
dsPIC heraus zu bekommen.

1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Linq;
7
using System.Text;
8
using System.Threading.Tasks;
9
using System.Windows.Forms;
10
using System.IO.Ports;
11
using System.Windows.Forms.DataVisualization.Charting;
12
13
14
namespace Masterthesis_Datenleser
15
{
16
    public partial class Form1 : Form
17
    {
18
        delegate void DisplayDelegate();
19
        int Recive_hb;
20
        int Recive_lb;
21
        double[] daten1 = new double[500];
22
        double[] daten2 = new double[500];
23
        int Recive_Value = 0;
24
        int count = 0;
25
        bool Data2_Flag = false;
26
        bool Start_Flag = true;
27
        double Bereich = 3.3 / 4096;
28
        //int[] egal = new int[1600];
29
        byte[] egal = new byte[1600];
30
31
        Series data_1 = new Series("U");
32
        Series data_2 = new Series("I");
33
34
35
        public Form1()
36
        {
37
            InitializeComponent();
38
            chart1.Series.Clear();
39
 
40
            string[] ports = SerialPort.GetPortNames();
41
            for (int i = 0; ports.Length > i; i++)
42
            {
43
                comboBox1.Items.Add(Convert.ToString(ports[i]) + Environment.NewLine);
44
            }
45
            try { comboBox1.Text = Convert.ToString(ports[0]); }
46
            catch { MessageBox.Show("Keine Com-Ports gefunden!"); }
47
48
        }
49
50
        private void label2_Click(object sender, EventArgs e)
51
        {
52
53
        }
54
55
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
56
        {
57
58
        }
59
60
        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
61
        {
62
63
        }
64
65
66
        private void button1_Click(object sender, EventArgs e)
67
        {
68
            richTextBox1.Clear();
69
70
            if (!serialPort1.IsOpen)
71
            {
72
                try { serialPort1.Open();
73
                serialPort1.DiscardInBuffer();      //Buffer löschen
74
                }
75
            catch
76
            {
77
                MessageBox.Show("Fehler", "Name Entry Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
78
            }
79
            }
80
            if (serialPort1.IsOpen)
81
            {
82
                serialPort1.DiscardInBuffer();
83
                Button_Port_Close.Enabled = true;
84
                Button_Port_Open.Enabled = false;
85
            } 
86
            
87
        }
88
89
        private void textBox1_TextChanged(object sender, EventArgs e)
90
        {
91
92
        }
93
94
        private void button2_Click(object sender, EventArgs e)
95
        {
96
            if (serialPort1.IsOpen)
97
            {
98
                serialPort1.Close();
99
                Button_Port_Close.Enabled = false;
100
                Button_Port_Open.Enabled = true;
101
            }
102
103
        }
104
105
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
106
        {
107
            if (serialPort1.IsOpen) serialPort1.Close();    
108
        }
109
110
        //private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
111
        //{
112
        //    RxString = _serialPort.ReadExisting();
113
        //    this.Invoke(new EventHandler(DisplayText));
114
        //}
115
116
        private void DisplayText()
117
        {
118
            Recive_Value = Recive_lb << 8;
119
            Recive_Value += Recive_hb;
120
121
            string s1 = Recive_lb.ToString("X");
122
            string s2 = Recive_hb.ToString("X");
123
            string s3 = Recive_Value.ToString("X");
124
            string s4 = Recive_Value.ToString("D");
125
126
            if (richTextBox1.InvokeRequired)
127
            {
128
                BeginInvoke(new DisplayDelegate(DisplayText));
129
            }
130
            else
131
            {
132
                richTextBox1.AppendText("\t" + s1 + "\t" + s2 + "\t" + s3 + "\t" + s4 + "\n");
133
134
                switch (Recive_Value)
135
                {
136
137
                    //case 0x01:
138
                    //    Start_Flag = true;
139
                    //    break;
140
141
                    case 0x09:
142
                        Data2_Flag = true;
143
                        break;
144
                    case 0x3B:
145
                        count++;
146
                        break;
147
                    default:
148
                        if (Data2_Flag == false)
149
                        {
150
                            daten1[count] = Recive_Value;
151
                        }
152
                        else
153
                        {
154
                            daten2[count] = Recive_Value;
155
                            Data2_Flag = false;
156
                        }
157
                        break;
158
                }
159
                if (count == 100)
160
                {
161
                    foreach (var series in chart1.Series)
162
                    {
163
                        series.Points.Clear();
164
                    }
165
                    
166
                    for (int i = 0; i < 100; i++)
167
                    {
168
                        daten1[i] = (daten1[i]) * Bereich;
169
                        daten2[i] = (daten2[i]) * Bereich;
170
                        data_1.Points.AddXY(i, daten1[i]);
171
                        data_2.Points.AddXY(i, daten2[i]);
172
                    }
173
                    try
174
                    {
175
                        chart1.Series.Add(data_1);
176
                        chart1.Series.Add(data_2);
177
                    }
178
                    catch { }
179
                    chart1.Series["U"].ChartType = SeriesChartType.Line;
180
                    chart1.Series["I"].ChartType = SeriesChartType.Line;
181
                    count = 0;
182
                }
183
            }
184
            
185
        }
186
187
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
188
        {
189
            //for (int i = 0; i < 1600; i++)
190
            //{
191
            //        Recive_lb = serialPort1.ReadByte(); //Lowbyte auslesen
192
            //        Recive_hb = serialPort1.ReadByte(); //Highbyte auslesen
193
            //        DisplayText();  //Anzeigen/Auswerten
194
                    
195
            //}
196
            Recive_lb = serialPort1.ReadByte(); //Lowbyte auslesen
197
            Recive_hb = serialPort1.ReadByte(); //Highbyte auslesen
198
            serialPort1.DiscardInBuffer();      //Buffer löschen
199
            DisplayText();  //Anzeigen/Auswerten
200
        }
201
202
        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
203
        {
204
205
        }
206
207
        private void chart1_Click(object sender, EventArgs e)
208
        {
209
210
        }
211
212
    }
213
}

von Peter II (Gast)


Lesenswert?

Christian schrieb:
> Ich hoffe einer von Euch weis Rat und kann
> mir weiterhelfen.

            Recive_lb = serialPort1.ReadByte(); //Lowbyte auslesen
            Recive_hb = serialPort1.ReadByte(); //Highbyte auslesen
            serialPort1.DiscardInBuffer();      //Buffer löschen

sollte man alles nicht in dem Event machen. Du solltest du nur genau die 
menge an Daten auslesen die auch da ist.

Wozu das Discard? Was ist wenn noch zeichen da sind, dann verlierst du 
sie doch.

mache doch einfach mal zu testen nur eine ausgabe:
1
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
2
{
3
for (int i = 0; i < serialPort1.BytesToRead(); i++) {
4
 Byte b = serialPort1.ReadByte();
5
 System.Diagnostic.Debug.WriteLine( b );
6
}
7
}

von Christian (Gast)


Lesenswert?

Hallo Peter,

die Ausgabe lautet:

0
0
0
9
0
0
0
59
0
1
0
9
0
6
0
59
0
2
0
9
0
7
0
59
0
3
0
9
0
8
0
59
0
4
0
9
0
9
0
59
0
5
0
9
0
10
0
59
0
6
0
9
0
11
0
59
0
7
0
9
0
12
0
59
0
8
0
9
0
13
0
59
0
9
0
9
0


die Ausgabe stimmt soweit, der erste Wert wird nicht korrekt gesendet, 
dass liegt wohl am µc-dort muss ich dann nochmal nachschauen, wenn der 
rest funktioniert.   59 entspricht der 0x3B und 9 der 0x09. Es sind 77 
genau Zeichen. Auf von den +fünf-Abständen sieht das richtig aus.

Peter II schrieb:
> Wozu das Discard? Was ist wenn noch zeichen da sind, dann verlierst du
> sie doch.

Ich wollte nur sichergehen den Buffer wirklich zu leeren.

Peter II schrieb:
> Recive_lb = serialPort1.ReadByte(); //Lowbyte auslesen
>             Recive_hb = serialPort1.ReadByte(); //Highbyte auslesen
>             serialPort1.DiscardInBuffer();      //Buffer löschen
>
> sollte man alles nicht in dem Event machen. Du solltest du nur genau die
> menge an Daten auslesen die auch da ist.

Ja ich weis :-) Wie Du siehst habe ich vorher 1600 Bytes erwartet und 
diese auswerten wollen, was ebenso gescheitert ist also wollte ich alles 
auf ein Minimum reduzieren...

von Christian (Gast)


Lesenswert?

Kommando zurück!

Ich habe nur zehn Bytes geschickt, also ist die Ausgabe vollkommen 
korrekt! Wenn ich 20 Werte sende funktioniert es auch wunderbar!

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.