Forum: PC-Programmierung C# + ZedGraph: Delay bei der Darstellung seriell empfangenen Daten


von theSePP (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit meiner C# Software, die Daten über eine 
serielle Schnittstelle einliest, speichert und dann in einem Zedgraph 
Diagramm dargestellt werden. Das Problem besteht darin, dass die Daten 
im Hauptfenster mit nur kleiner Verzögerung (wegen der Schnittstelle) 
dargestellt werden, sobald das Diagramm Fenster aufgemacht wird aber ein 
zunehmender Delay entsteht.

Die Daten werden in Form1 gespeichert. Mittels Button wird dann die neue 
aufgerufen. Ihr übergebe ich die eingelesenen Daten mittels

>Form2 f2 = new Form2(data);
>f2.ShowDialog();

Komischerweise ist generell nach dem Starten des Diagramms ein 
zunehmender Delay erkennbar (also auch wenn das Diagramm schon wieder 
beendet wurde).

Vielleicht hat jemand nen Ansatz der mir hilft das Problem zu lösen.

Gruß
SePP

von Andreas W. (Gast)


Lesenswert?

Zedgraph verbraucht je nach menge der punkte unterschiedlich lange um 
datan anzuzeigen und es braucht lange. Wenn du dann noch glimbim 
anschaltest (z.B farbverlauf, symbole) dann braucht er noch länger.

was für ein Delay entsteht genau? Die Daten aus der Schnittstelle werden 
doch in einen Buffer geschrieben. Zeit ist gerade unter Windows sehr 
relativ, gerade mit .net.

von theSePP (Gast)


Lesenswert?

Klar ist zeit hier relativ und Daten werden gepuffert. Deshalb seh ich 
ja eine Änderung auch erst viel später (nach 15s+ hab ich eine 
Verzögerung von über 3s drin). Ich stelle z.Z. 7 Kurven (Ziel sind 
eigentlich 10) mittels RollingPointPairList dar und haben eine Sample 
Intervall von 100ms.

Vielleicht liegt es auch daran das mein Rechner zu lahm ist, aber davon 
geh ich mal nicht aus (3Ghz Celeron mit 512mb sollten denke ich 
reichen).

von theSePP (Gast)


Lesenswert?

Habe mein Problem gelöst, nachdem ich mich nochmal mit der Seriellen 
Schnittstelle beschäftigt habe. Hier wurden die Daten nur scheinbar 
schnell genug erfasst. Zedgraph war NICHT an der Verzögerung schuld. 
Habe auch nochmal ein paar Optimierung bei der Zedgraph Darstellung 
gemacht und nun bin ich erstmal ganz zufrieden. :-)

von Olek (Gast)


Angehängte Dateien:

Lesenswert?

Ist zwar nicht mehr aktuell hier, aber mich würde die Lösung schon 
interssieren bzw. wie es verbessert wurde.

Ich habe momentan ein ähnliches Problem. Ich zeichne über 75min Daten 
von der Seriellenschnittsetlle auf und das je Sekunde vier Datenpackete. 
Es wird live mit ZedGraph gezeichnet. Am anfang läuft die Sache noch 
flot, jedoch wird es gegen Ende langsam träge. Bis zu einer Sekunde 
nachlauf drin.

Es läuft bei mir so ab:

im µC:

->Messdaten erfassen (1,5ms)

Loop
{
  -> PC bereit?
     -> Daten an PC senden
}

in VB:

Loop
{
  ->Daten von der Seriellenschnittstelle holen
  ->mit ZedGraph zeichnen
  ->µC sagen das neue Daten kommen können
}


Ein Datenpacket hat 2 Byte.

die Übertragung erfolgt mit 9600 Baud, somit 9600 Bit/s und d.h. könnte 
ich ja in der Sekunde 533 von den Packeten schicken bzw. ein Packet in 
2ms.

Macht allso alles mit Messung zusammen ca. 14ms und den Rest der Zeit 
verbingt der µC mit warten auf den Rechner. Ist ja net grade prickelnd 
wie ich finde, da man da locker mehr rausholen könnte.

Mein WehWeh bei ZedGraph ist nun, dass der mir wie Ox vorm Berg bei 
jedem neuen Punkt alle davorgehenden Punkte auch neu zeichnet, was ja 
nicht Sinn der Sache ist bei 18000 Punkten.

Ich könnte die Daten buffern, jedoch ists dann hin mit "live" 
zeichen.... wobei es dann mehr live wäre als jetzt glaub ich.

so!Bin ich noch zu blöd und habe die Funktion, welche nur die neuen 
Punkte zeichnet, nicht gefunden oder gibt es diese nicht und ich muss 
mir einen eigenen Graphen programmieren der das kann.... bin aber nur 
Bachelor(FH) und zu faul. Außderdem gefällt mir der schnickSchnack von 
ZedGrpah der schon da ist.

Kurz zu den Daten die ich hochgeladen habe.
Die Daten wurden ohne Warten des µC aufgezeichnet! Also das Maximum was 
bei der Lösung drin ist.
Das Bildchen soll mal zeigen wie der Spass ausieht. Die Text-datei zeigt 
mein Problem schon eher.
Die ersten vier Spalten interessieren net. Die letzte Spalte ist die 
Zeit in Sekunden. Es ist zu erkennen wie der Rechner da noch mitkommt, 
da Zeiten doppelt auftauchen, geht man ganz zum Ende der Spalte schluckt 
der schon ne Sekunde. Wenn man den Rechner noch mit was ablenkt schluckt 
der noch mer Sekunden.

Jemand schon dahingehend mit ZedGraph erfahrung gesammelt und weiss wie 
ich das zeichnen ohne Buffer schneller hinbekommen könnte?

von Sebastian (Gast)


Lesenswert?

Hi!

Ich grab den Thread mal aus, denk ich ist sinnvoller als einen neuen 
Fred zu starten, da meine Frage genau hier anschließt: der TO shrieb: 
"... Habe mein Problem gelöst, nachdem ich mich nochmal mit der 
Seriellen
Schnittstelle beschäftigt habe. Hier wurden die Daten nur scheinbar
schnell genug erfasst..."

Ich habe genau dasselbe Problem, dass am Anfang alles super schnell 
läuft und dann nach ca. 15 Sekunden 5 Sekunden Verzögerung auftreten und 
so weiter.

Daher würde mich interessieren, was hier beim Einlesen der COM-Portdaten 
zu berücksichtigen war/ist.

Vielleicht ist der TO ja noch hier unterwegs, oder jemand anderer weiß 
Rat.

Danke, Sebastian

von Mat T. (tmat)


Lesenswert?

Hi, hab das gleiche Problem.

Sende mit 38400 Baud Daten an den PC - in einem beliebigen 
Terminalprogramm z.b. Termie (geschrieben in C#) werden alle Daten 
sofort angezeigt.

In meinem selbstgeschriebenen, mittlerweile etwas komplexeren Programm 
kommen die oben beschriebenen Verspätungen zustande.

Allerdings bei einer Messung von z.b. ~45min beträgt die Verzögerung bis 
zu einigen Minuten. Der uC sendet in dieser Zeit definitiv nichts mehr.

Wäre auch an einer Lösung oder Ansatz interessiert.

danke, grüße
Mat

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mat T. schrieb:
> Wäre auch an einer Lösung oder Ansatz interessiert

Ein Ansatz wäre mal

Mat T. schrieb:
> mittlerweile etwas komplexeren Programm

auf das nötigste zu reduzieren. Und dann ggf. mal den Code hier posten.

von Mat T. (tmat)


Lesenswert?

Hallo,

danke für den Tipp. Hab in einem anderen Forum ein ähnliches Problem 
gefunden und es mit diesem Lösungsansatz versucht.

Mein Code vereinfacht dargestellt:
1
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
2
        {
3
            try
4
            {
5
                 empfangen = serialPort1.ReadLine();
6
                 // Do Domething
7
                
8
            }
9
            catch (Exception ex)
10
            {
11
                MessageBox.Show(ex.Message);
12
            }
13
        }

müsste meiner Meinung nach bei jedem Datenpaket das kommt ein Interrupt 
auslösen bzw. in diese Routine springen.
Comport ist eingestellt auf '\n' Terminierung und der Controller schickt 
es auch immer hinten dran.

So meine Theorie ...

Hab dann diesen Code gefunden und es jetzt so umgebaut und bisher 
funktioniert das wie gewünscht.
1
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
2
        {
3
            try
4
            {
5
                while (serialPort1.BytesToRead > 0)
6
                {
7
                    empfangen = serialPort1.ReadLine();
8
                    // Do Something
9
                }
10
            }
11
            catch (Exception ex)
12
            {
13
                MessageBox.Show(ex.Message);
14
            }
15
        }

für die die eventuell auch das gleiche Problem haben :)

danke und gruß
Mat

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mat T. schrieb:
> Hab dann diesen Code gefunden

Und hoffentlich auch verstanden warum das so funktioniert ;)

von Mat T. (tmat)


Lesenswert?

Läubi .. schrieb:
> Mat T. schrieb:
>> Hab dann diesen Code gefunden
>
> Und hoffentlich auch verstanden warum das so funktioniert ;)

hehe, ich hoffs mal ;)

hab mir ja wie oben beschrieben erwartet, dass pro gesendetem Text mit 
'\n' Abschluss einmal diese Empfangsroutine aufgerufen wird.

wenn während der Abarbeitung wieder Daten eintreffen, können die eben 
auch schon ausgelesen werden.

oder so irgendwie :)

gruß Mat

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mat T. schrieb:
> oder so irgendwie :)

Passt schon so irgendwie ;)

Das Problem wird einfach sein, das durchaus mehr als eine Zeile 
empfangen wird.
Wenn du aber immer nur eine Zeile liest, kann sich ein Rückstau bilden, 
was dazu führt das es für die Applikation so aussieht als würden die 
Daten verspätet eintreffen.

Du solltest aber beachten, dass hierdurch die Empfangsfunktion 
theoretisch beliebig lange in der Schleife verweilen kann.

Vermutlich wäre es besser, dass das Empfangen in einem Thread 
geschieht. und dieser einfach wenn nix mehr EMpfangen wird schläft, und 
einfach nur durch das "neue Daten Event" aufgeweckt wird.

von Mat T. (tmat)


Lesenswert?

glaub der Comport läuft eh in einem extra Thread, da ich zumindest nicht 
direkt auf die GUI zugreifen kann und über Invokes gehen muss.

Hab auch schon überlegt, wenn sich z.b. der Controller aufhängt bzw. 
Fehlsignale bekommt, kann er auch "relativ oft" ;) Daten senden, was 
dann meine GUI abwürgen würde, zumindest wenns im gleichen Thread ist.

darübernachdenk

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.