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
> 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.
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..
du musst immer alles Empfangen, du kannst nichts überspringen! Wo ist das Problem wenn du alles einliest und dann den anfangs wegschmeist?
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?
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.
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? ;)
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.
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?
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?
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..
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.
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);
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?
Ein SunnyBoy Wechselrichter Peter II schrieb: > nein, denn jetzt liest du ja überhaupt nicht mehr? warum sollte ich jetzt nicht mehr lesen?
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.
Osti schrieb: > warum sollte ich jetzt nicht mehr lesen? weil im code nach dem senden nichts man von ReadExisting steht?
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..
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.
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.
mit hterm habe ich ganz normale hexzahlen mit dem Befehl bekommen
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.
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?
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.
kannst du bitte mal schreiben wie du es machen würdest?
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.
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
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?
> 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];
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
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?
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 ;)
Danke Peter ;) Hast mich auf den richtigen Weg gebracht ;) jz muss ich das nur mehr bischen weiterentwickeln ;)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.