Forum: Mikrocontroller und Digitale Elektronik Datenübertragung MC <-> PC mit C#


von Reinhard #. (gruebler)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich habe hier einen ATmega88, der über ein
FT232-Modul (19200Baud) mit meinem PC unter
Win10 kommuniziert.
Es werden Zahlen und binäre Daten in beide Richtungen
geschickt. Die Verbindung PC-> MC klappt ohne
Probleme. Die andere Richtung klappt aber nicht.
Es sollen zwei 12Bit-Werte von AD-Wandlungen und
ein binäres Signal übertragen werden. Ich nutze einen
ASCII-String, in dem die Zahlen als ASCII-Zeichen
übertragen werden. Die Analogwerte übertrage ich
zwei mal pro Sekunde. Den Binärwert nur wenn er
sich ändert.

Die Zahlen kommen an und werden richtig angezeigt.
    ####   ABER   ####
Wenn die Übertragung läuft, verzögern sich die
Anzeige der Werte immer mehr.
Es ist so, als wenn der
PC die Daten in einem internen Buffer verwahrt und sie
nach und nach abarbeitet. Die Verzögerungen liegen im
mehrstelligen Sekundenbereich.

Hier der Programmteil im C#-Programm der die Daten
empfängt
1
 private void spoUSB_DataReceived(object sender,
2
                                 SerialDataReceivedEventArgs e)
3
         {
4
            int Wert;
5
            double Wert_inV;
6
            string EBuffer = spoUSB.ReadLine();
7
            
8
            //Aus den Zeichen 1...4 Den Wert wieder nach int wandeln
9
            Wert = Convert.ToInt16(EBuffer.Substring(1, 4));
10
            Wert_inV = (double)Wert * 0.00489;
11
12
            switch ((char)EBuffer[0])
13
            {
14
                case 'T':  //es ist der Steuercode der Taste
15
                    {
16
                        if (Wert == 0) lblIndiTaster.Visible = false;
17
                        if (Wert  > 0) lblIndiTaster.Visible = true;
18
                    }
19
                    break;
20
                case '1':  //es ist der Steuercode vom Analogeingang 1
21
                    txtAusgabe1.Text = String.Format("{0:F2}V", Wert_inV);
22
                    break;
23
                case '2':  //es ist der Steuercode vom Analogeingang 2
24
                    txtAusgabe2.Text = String.Format("{0:F2}V", Wert_inV);
25
                    break;
26
            }         
27
        }

Im Anhang die Einstellung des COM-Ports.

Hat einer eine Idee, wie ich die Verzögerung
aus der Anzeige bekomme?

von Rene K. (xdraconix)


Lesenswert?

Läßt du den Receiver in einem eigenen Thread laufen?

von Reinhard #. (gruebler)


Lesenswert?

Rene K. schrieb:
> Läßt du den Receiver in einem eigenen Thread laufen?

Hallo Rene
Ich verstehe deine Frage nicht so ganz.
Der oben dargestellte Code ist die
Ereignis-Methode des Virtuellen-COM-Ports.

Aber ich hatte gerade die rettende Idee. Verstehe
aber immer noch nicht warum sie Funktioniert. (-?

Biher läuft es so:
AD1 Wandlung, Funktion für die Übertragung aufrufen
sofort danach
AD2 Wandlung, Funktion für die Übertragung aufrufen

Jetzt habe ich in die Funktion für die Übertragung
eine kleine Verzögerung von 20ms eingebaut.
Es vergeht also jetzt eine kleine Weile bis die
nächste Übertragung erfolgen kann.
Und, "Oh Wunder" die Daten kommen ohne fühlbare
Verzögerung auf dem PC-Bildschirm an.

von Max M. (maxmicr)


Lesenswert?

Ich lese mit 500.000 Baud 8-bit AD-Werte, mit C# hab ich das so gelöst, 
ohne Event:
1
            SerialPort s = new SerialPort("COM4", 500000);
2
            int i = 0;
3
            int[] data = new int[SIZE];
4
5
            s.Open();
6
7
            while(i < SIZE)
8
            {
9
                data[i] = s.ReadByte();
10
                i++;
11
            }
12
13
            s.Close();

Die *ReadByte()* Methode wartet solange, bis ein neues Byte empfangen 
wurde.

von Rene K. (xdraconix)


Lesenswert?

Und was ist wenn i nie größer/gleich SIZE wird? Warum auch immer... z.b. 
ein Byte verschluckt etc. Dann geht es nie aus deiner Schleife raus. 
Dein Programm steht und du kannst nichteinmal mehr eine 
Benutzerinteraktion durchführen um die Messung abzubrechen o.ä.

von THOR (Gast)


Lesenswert?

Du könntest mal gucken ob
SerialPort.ReceivedBytesThreshold
höher einzustellen hilft.

Abgesehen davon läuft DataReceived in einem eigenen Thread (RTFM, was in 
diesem Fall für "Read the fuckin msdn" steht). GUI Elemente zu 
manipulieren kann einerseits das langsame Verhalten erklären, ist aber 
auch generell ohne geeignete Maßnahmen ne doofe Idee.

Dass dein SpoUSB offensichtlich ne globale Variable ist, ist auch 
verkehrt.

Das object sender ist dein SpoUSB, musst du nur casten.

von HmmJa (Gast)


Lesenswert?

Kallo,

ich würde als allererstes mal klären, ob die beobachtete Verzögerung 
tatsächlich eine Verzögerung aller empfangenen Werte ist, oder ob 
zwischendurch Fehler entstehen und deshalb kein Event kommt.

Das kann man machen, indem man alle Fehler abfängt :-) oder man sendet 
an Stelle der ADC-Werte mal fortlaufende Zahlen. Dann wird sich zeigen, 
ob auch alle Zahlen tatsächlich ankommen.

Das Empfangen von binären Werten mit ReadLine() taugt natürlich nichts.

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.