Forum: PC Hard- und Software C# UART auslesen und am Bildschirm ausgeben


von Osti (Gast)


Lesenswert?

Hallo,

Ich verwende den MINI2440 Mikrocontroller und habe WinCE oben.


Ich will mit dem Mikrocontroller, mit der UART senden und empfangen..
Das senden habe ich schon einwandfrei zusammenbekommen, jedoch ist das 
empfangen das Problem..

Ich arbeite noch nicht sehr lange mit C#, deswegen kenne ich mich auch 
noch nicht extrem gut aus. Ich weiß zwar die Befehle zum empfangen, 
jedoch klappt es bei mir nicht so ganz.



Noch genauer was ich machen will:

Ich will mit einem anderen Gerät eine Verbindung aufbauen, dazu muss ich 
spezielle Strings (mehrere Hex-Werte) senden (insgesamt ca 6 
verschiedene). Jedesmal nachdem ich etwas sende, kommt ein Wert vom 
anderen Gerät zurück. Jedoch benötige ich nur den letzten String 
(wiederum Hex-Werte) den mir das Gerät sendet. In diesem String sind 
Daten drin die ich auswerten muss.

Und der Befehl "serialPort1.ReadExisting()" ließt einfach alles aus was 
gesendet wird und nicht nur den bestimmten String was ich benötige..

Der auszuwertende String hat 94 Hex-Werte von denen ich die Hex-Werte 43 
und 44 benötige
(Der fertige Wert wird so berechnet: power = (data2[44] << 8) + 
data2[43]; )
Die Dezimalzahl was sich danach ergibt will ich dann auf dem Display 
ausgeben..



Zusammenfassung:
Ich muss warten bis ein bestimmter String über die UART kommt mit 
94-Hex-Werten. Von diesem berechne ich mir die Daten die ich benötige 
(power = (data2[44] << 8) + data2[43]; ). Und diese will ich dann als 
Dezimalzahl am Display ausgeben..

Das was ich unbedingt wissen muss ist, wie ich das programmiere, dass 
ich nur den letzten String mit den 94-Hex-Werten herausbekomme.
Und dass ich dann die Werte als Dezimalzahlen am Display ausgeben kann.




Bitte um rasche Hilfe..
Und bitte keine unnötigen Kommentare warum ich das machen will, wenn ich 
mich eh nicht auskenne oder so.
Ich interessiere mich einfach dafür und irgendwie finde ich einfach 
nicht das was ich dafür brauche..

Ich bedanke mich schon einmal für eure Hilfe ;)


Mfg. Osti

von Peter II (Gast)


Lesenswert?

> Das was ich unbedingt wissen muss ist, wie ich das programmiere, dass
> ich nur den letzten String mit den 94-Hex-Werten herausbekomme.

es muss doch wohl erstmal festgelegt werden was der letzte wert ist? 
Gibt eien eine ende zeichen (z.b. CR/LF ) oder gibt es eine 
Längenangabe? Wenn es das alles nicht gibt kann man auch nicht der 
letzte zeichen sinnvoll auswerten.

von Osti (Gast)


Lesenswert?

Das was mir gesendet wird ändert immer den Wert, aber die länge von dem 
String ist immer gleich.. die 94 Hex-Werte..

Es läuft so ab:


1.Senden:

 68 00 00 68 00 00 00 00 80 00 06 86 00 16

1.Empfang:

 03 16 00 00 AA AA 68 0C 0C 68 C8 00 00 00 40 00 06 D9 B6 3E 77 57 52 31 
31 2D 30 34 30 1E

2.Senden:

 68 00 00 68 00 00 00 00 80 00 01 81 00 16

2.Empfang:

 05 16 00 00 AA AA 68 0C 0C 68 C8 00 00 00 40 00 01 D9 B6 3E 77 57 52 31 
31 2D 30 34 30 19 05

3.Senden:

 68 06 06 68 00 00 00 00 80 00 03 D9 B6 3E 77 C8 00 8F 03 16

3.Empfang:

 16 00 00 AA AA 68 04 04 68 C8 00 00 00 40 00 03 D9 B6 3E 77 4F

4.Senden:

 68 06 06 68 00 00 00 00 80 00 03 D9 B6 3E 77 C8 00 8F 03 16

4.Empfang:

 03 16 00 00 AA AA 68 04 04 68 C8 00 00 00 40 00 03 D9 B6 3E 77 4F 03

5.Senden:

 68 04 04 68 00 00 00 00 80 00 0A 3C DB 71 4F 61 02 16

6.Senden:

68 03 03 68 00 00 C8 00 00 00 0B 0F 09 00 EB 00 16

5.Empfang:

 13 16 00 00 00 AA AA 68 4B 4B 68 C8 00 00 00 40 00 0B 0F 09 00 01 00 3C 
DB 71 4F 01 00 00 00 A5 00 A6 00 08 07 20 00 E7 00 85 13 A0 01 48 03 F0 
13 B8 0B E6 00 84 13 40 03 5A 22 AB 01 8F 0A 0D 02 DB 00 0A 17 00 00 82 
F1 00 00 FE F6 00 00 16 00 00 00 0D 00 00 00 D9 B6 3E 77 07 00 10



Die Sendedaten sind immer gleich.. Die Empfangsdaten ändern sich..
Aber mich interessiert nur die letzten Empfangsdaten (5.Empfang)

Das andere Gerät schickt immer nur etwas, wenn es vorher etwas bekommen 
hat..

von Osti (Gast)


Lesenswert?

und es gibt soweit ich weiß kein Ende-Zeichen...

von Peter II (Gast)


Lesenswert?

du musst immer alles Empfangen, du kannst nichts überspringen! Wo ist 
das Problem wenn du alles einliest und dann den anfangs wegschmeist?

von Osti (Gast)


Lesenswert?

meinst du, einfach alles einmal speichern und dann die Hex-Zahlen, die 
ich brauche von dem gesamten Blödsinn raussuchen?

            string data = serialPort1.ReadExisting();
            string acpower;
            char[] data2 = new char[199];
            data2 = null;
            data2 = data.ToCharArray();

            int power;
            power = (data2[149] << 8) + data2[148];

            acpower = power.ToString();

            textBox1.Text = "Leistung:" +acpower;


kann ich das dann so machen?

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> kann ich das dann so machen?

nein.

> string data = serialPort1.ReadExisting();
der buffer vom SerialPort wird nicht so gross sein das dort 200zeichen 
reinpassen - du musst das ganze in einer schleife oder im eventu 
einlesen. Du kannst nicht einfach davon ausgehen das alles auf einmal 
kommt.

>             char[] data2 = new char[199];
>             data2 = null;
>             data2 = data.ToCharArray();
was soll der unsinng, erst variabel anlegen, dann wieder löschen und 
schon wieder überscheiben - eventuell ist mal #c lernen?

char[] data2 = data.ToCharArray();

macht das gleiche.

> die ich brauche von dem gesamten Blödsinn raussuchen?
nein man sollte die Daten verstehen und das gesamte Prokoll umsetzten, 
denn das ganze wird kein Blödsinn sein. Dann ist es auch einfach an die 
benötigten Daten ranzukommen.

von Osti (Gast)


Lesenswert?

Ja, sry.. ich arbeite noch nicht so lange mit c#..

Wie soll ich die ganzen Empfänge aufteilen?

Besser gesagt.. wie programmiere ich das was du meinst? ;)

von Peter II (Gast)


Lesenswert?

ich kenn nicht die daten die übertragen werden damit sollte man sich als 
erstes beschäftigen - gibt es dafür eine Doku?

String data = "";
while( data.Lengh < 199 ) {
   data += serialPort1.ReadExisting();
}

so in der art, das ist aber immer noch unschön, weil das Programm 
blockiert wenn keine neuen daten kommen.

von Osti (Gast)


Lesenswert?

Peter II schrieb:
> ich kenn nicht die daten die übertragen werden damit sollte man sich als
> erstes beschäftigen - gibt es dafür eine Doku?

was meinst du damit?

vl könnte ich es so machen:


serialPort1.Write("\x68\x00\x00\x68\x00\x00\x00\x00\x80\x00\x06\x86\x00\ 
x16");
data += serialPort1.ReadExisting();
                serialPort1.Write("\x68\x00\x00\x68\x00\x00\x00\x00\x80\x00\x01\x81\x00\ 
x16");
data += serialPort1.ReadExisting();
                serialPort1.Write("\x68\x06\x06\x68\x00\x00\x00\x00\x80\x00\x03\xD9\xB6\ 
x3E\x77\xC8\x00\x8F\x03\x16");
data += serialPort1.ReadExisting();
                serialPort1.Write("\x68\x06\x06\x68\x00\x00\x00\x00\x80\x00\x03\xD9\xB6\ 
x3E\x77\xC8\x00\x8F\x03\x16");
data += serialPort1.ReadExisting();
                serialPort1.Write("\x68\x04\x04\x68\x00\x00\x00\x00\x80\x00\x0A\x3C\xDB\ 
x71\x4F\x61\x02\x16");
System.Threading.Thread.Sleep(500); //weil hier nichts empfangen wird
                serialPort1.Write("\x68\x03\x03\x68\x00\x00\xC8\x00\x00\x00\x0B\x0F\x09\ 
x00\xEB\x00\x16");
data += serialPort1.ReadExisting();


//und nacher auswerten und ausgeben

char[] data2 = data.ToCharArray();
int power;
power = (data2[149] << 8) + data2[148];

acpower = power.ToString();

textBox1.Text = "Leistung:" +acpower;




wie wärs damit?

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> vl könnte ich es so machen:
>
> serialPort1.Write("\x68\x00\x00\x68\x00\x00\x00\x00\x80\x00\x06\x86\x00\ x16");
> data += serialPort1.ReadExisting();

nein, weil du bei aufruf von ReadExisting() nicht sicherstellen kannst 
das schon alle daten überhaupt da sind.

Noch einmal die Frage gibt es eine Doku zu dem Datenprotokoll?

von Osti (Gast)


Lesenswert?

Peter II schrieb:
> Noch einmal die Frage gibt es eine Doku zu dem Datenprotokoll?

Was meinst du damit?


Und was wenn ich einfach das
data = serialPort1.ReadExisting();
von Anfang an mitlaufen lasse. Dass ich einfach alles was ich während 
dem Sendevorgang bekomme speicher..

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> Was meinst du damit?

Wo ist dann beschrieben was die zeichen die du empfängst und sendest
machen?

> ReadExisting();

Das liest alles zeichen du bis JETZT im empfangspuffer vorhanden sind. 
Wenn das gerät in dieser zeit noch daten sendet dann bekommst du sie 
erst beim nächsten aufrufe.

Serial ist so langsam, das es durchaus passieren kann das noch nicht mal 
1 zeichen vorhanden ist, wenn du gleich nach dem senden aufrufst.

von Osti (Gast)


Lesenswert?

Es gibt keine Beschreibung.. ich habe den Verbindungsaufbau und alles 
mit dem SerialDataLogger aufgezeichnet.

Die ersten dürften nur für den Verbindungsaufbau sein und im letzten 
sind alle möglichen Daten drin enthalten..


aber so müsste es ja eig funktionieren oder?

data = null;
data = serialPort1.ReadExisting();

serialPort1.Write("\x68\x00\x00\x68\x00\x00\x00\x00\x80\x00\x06\x86\x00\ 
x16");
                System.Threading.Thread.Sleep(500);
                serialPort1.Write("\x68\x00\x00\x68\x00\x00\x00\x00\x80\x00\x01\x81\x00\ 
x16");
                System.Threading.Thread.Sleep(500);
                serialPort1.Write("\x68\x06\x06\x68\x00\x00\x00\x00\x80\x00\x03\xD9\xB6\ 
x3E\x77\xC8\x00\x8F\x03\x16");
                System.Threading.Thread.Sleep(500);
                serialPort1.Write("\x68\x06\x06\x68\x00\x00\x00\x00\x80\x00\x03\xD9\xB6\ 
x3E\x77\xC8\x00\x8F\x03\x16");
                System.Threading.Thread.Sleep(500);
                serialPort1.Write("\x68\x04\x04\x68\x00\x00\x00\x00\x80\x00\x0A\x3C\xDB\ 
x71\x4F\x61\x02\x16");
                System.Threading.Thread.Sleep(500);
                serialPort1.Write("\x68\x03\x03\x68\x00\x00\xC8\x00\x00\x00\x0B\x0F\x09\ 
x00\xEB\x00\x16");
                System.Threading.Thread.Sleep(500);

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> aber so müsste es ja eig funktionieren oder?

nein, denn jetzt liest du ja überhaupt nicht mehr? Und warten sollte man 
möglichst vermeiden. Etweder warten man zu lang und das Programm ist zu 
langsam oder man wartet zu kurz und es geht nicht mehr. Warten ist also 
die schlechtestet Lösung.

> Es gibt keine Beschreibung.. ich habe den Verbindungsaufbau und alles
> mit dem SerialDataLogger aufgezeichnet.
mich sicherheit wird es eine geben, die Frage ist ob man da rankommt.

Was ist das für ein Gerät?

von Osti (Gast)


Lesenswert?

Ein SunnyBoy Wechselrichter

Peter II schrieb:
> nein, denn jetzt liest du ja überhaupt nicht mehr?

warum sollte ich jetzt nicht mehr lesen?

von Peter II (Gast)


Lesenswert?

Auch deine Auswertung von Empfangen und senden ist "vermutlich" 
Ferhlerhaft. Denn beim 3. Empfang fangen die daten mit 16 00 00 an. 
sonst fangen sie aber immer mit 05(oder 03) 16 00 00 an.

Und wenn man genauer hinschaut, dann sieht man das der Empfang 2 die 05 
am ende enthält.

Finde also erstmal die bedeutung der Daten raus, erst dann kann man 
sinnvoll Programmieren.

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> warum sollte ich jetzt nicht mehr lesen?

weil im code nach dem senden nichts man von ReadExisting steht?

von Osti (Gast)


Lesenswert?

Die Auswertung ist richtig, ich habe die Leistung schon mit dem Laptop 
auslesen können.
Ich habe mit hterm einfach die Verbindung aufgebaut und alles hat super 
funktioniert..

von Peter II (Gast)


Lesenswert?

noch etwas :

serialPort1.Write("\x68\x00\x00\x68\x00\x00\x00\x00\x80\x00\x01\x81\x00\ 
x16");

ist auch fehlerhaft, du sendest einen String und damit handelst du dir 
Probleme mit der Zeichsatzkonvertung ein.

Wenn ich das jetzt richtig sehen dann werden die daten auch nicht als 
Hex sonder binär übertragen, damit solltest du eh nicht ReadExisting 
verwenden weil das nur bei Strings immer funktioniert.

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> Die Auswertung ist richtig, ich habe die Leistung schon mit dem Laptop
> auslesen können.

nein ist sie nicht, das denkst du nur weil du dich noch nicht mit diesen 
daten beschäftigt hast.

> Ich habe mit hterm einfach die Verbindung aufgebaut und alles hat super
> funktioniert..

Dabei hast du ja überhaupt nicht die empfangen daten verwendet, wie 
willst du da erkennen was zu welchen block gehört.

Also noch einmal der Tip: Finde erstmal raus wie ein "Datenpacket" 
aussieht (also wo es anfängt, wo die länge steht ob es eine Prüfsumme 
gibt) Dann fange an zu programmieren.

von Osti (Gast)


Lesenswert?

mit hterm habe ich ganz normale hexzahlen mit dem Befehl bekommen

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> mit hterm habe ich ganz normale hexzahlen mit dem Befehl bekommen

es war ja nur ein Hinweis, wenn du in den Zahlebreich über 128 kommst, 
kann macht dir die UTF8 kodierung zu schaffen.

Du hast ja schon selber geschrieben, das du nicht viel erfahrung mit C# 
hast, dann glaube wenigsten den leuten die es schon länger machen.

von Osti (Gast)


Lesenswert?

etwas anderes..

irgendwie funktioniert das umconvertieren nicht..


            string tmp = serialPort1.ReadExisting();
            string acpower;
            char[] data = tmp.ToCharArray();

            int power;
            power = (data[1] << 8) + data[0];

            acpower = power.ToString();
            // Set text to TextBox
            textBox1.Text = acpower;

und wenn ich dann "A0 01" schicke sollte da Dezimal "416" rauskommen

aber am Display wird mir "319" angezeigt..

Weißt du was hier falsch ist?

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> und wenn ich dann "A0 01" schicke sollte da Dezimal "416" rauskommen

ich vermute das ist genau das Problem was ich gesagt habe, du wandelst 
Unicode in int um - das kann nicht gut gehen. C# hat im String kein 
ASCII mehr sondern unicode.

Also verwende keine Stings wenn du keinen Text übertragen willst.

Stell es auf byte arrays um, dann sparst du dir die Convertiung.

von Osti (Gast)


Lesenswert?

kannst du bitte mal schreiben wie du es machen würdest?

von Peter II (Gast)


Lesenswert?

data byte[] = new byte[ serialPort1.BytesToRead ];
serialPort1.Read( data, 0, byte.length );

int power;
power = (data[1] << 8) + data[0];


nur blind getippt, können also noch fehler drin sein.

von Osti (Gast)


Lesenswert?

Peter II schrieb:
> data byte[] = new byte[ serialPort1.BytesToRead ];
data byte[]? das geht so nicht..
wenn dann byte[] data = ...

> serialPort1.Read( data, 0, byte.length );
kennt er byte.length nicht

und wenn ich das so mache:

            byte[] data = new byte[ serialPort1.BytesToRead ];
            string acpower;
            int power;
            power = (data[1] << 8) + data[0];

            acpower = power.ToString();
            // Set text to TextBox
            textBox1.Text = acpower;

und wieder was sende kommt am Display 0 raus

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> kennt er byte.length nicht

ist doch wohl klar was gemeint ist, ein bisschen mitdenken währe nicht 
schlecht.

http://msdn.microsoft.com/de-de/library/system.array.length(v=vs.80).aspx

serialPort1.Read( data, 0, byte.Length );


> und wenn ich das so mache:
> und wieder was sende kommt am Display 0 raus
ist doch klar, die legst ja auch keine Daten im Array ab. Weiss du 
überhaupt was diese code macht?

von Osti (Gast)


Lesenswert?

und wie soll ichs jz machen, dass es geht?

von Peter II (Gast)


Lesenswert?

> und wie soll ichs jz machen, dass es geht?

data byte[] = new byte[ serialPort1.BytesToRead ];
serialPort1.Read( data, 0, byte.Length );

int power;
power = (data[1] << 8) + data[0];

von Osti (Gast)


Lesenswert?

Peter II schrieb:
> data byte[] = new byte[ serialPort1.BytesToRead ];
> serialPort1.Read( data, 0, byte.Length );
>
> int power;
> power = (data[1] << 8) + data[0];

das geht so nicht

von Peter II (Gast)


Lesenswert?

Osti schrieb:
> das geht so nicht

was geht daran nicht? wie viele Daten werden dann gelesen, was steht im 
dem array drin?

Benutzt du zur diagnose wenigsten den debugger?

von Osti (Gast)


Lesenswert?

int bytesToRead = serialPort1.BytesToRead;

            byte[] b = new byte[bytesToRead];

            serialPort1.Read(b, 0, bytesToRead);

            int power;
            string acpower;
            power = (b[1] << 8) + b[0];

            acpower = power.ToString();
            // Set text to TextBox
            textBox1.Text = acpower;

so gehts ;)

von Osti (Gast)


Lesenswert?

Danke Peter ;)

Hast mich auf den richtigen Weg gebracht ;)
jz muss ich das nur mehr bischen weiterentwickeln ;)

von Osti (Gast)


Lesenswert?

Es hat sich jz noch ein Problem ergeben:

Das ist jz mein Code:

            int bytesToRead;
            string acpower;
            int power;
            bytesToRead = serialPort1.BytesToRead;

            byte[] b = new byte[bytesToRead];

            serialPort1.Read(b, 0, bytesToRead);

            power = (b[44] << 8) + b[43];

            acpower = power.ToString();

            textBox1.Text = acpower;


Aber ich habe folgendes Problem
Ich kann maximal 8 Byte senden.. sobald es mehr sind kommt ein Error
wenn ich meine 94 Hex-Werte sende, kann das Programm den richtigen Wert 
noch berechnen, aber es kommt danach sofort der Error und ich muss das 
Programm schließen..

Hast du eine Lösung für mich?

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.