Hallo, ich versuchs mal möglichst kurz zu machen. Ich hab mich schon über die besagte Thematik informiert. Leider gabs keine wirklich guten Lösungsansätze dafür... Also das Versenden des Single Wertes über UART als Binärstring klappt super, der erwartete Wert kommt beim AVR so an wie er soll. Nur leider klappt das rücklesen nicht. Dort wird ein gesendetes 0,004 zu 0,0029xxxx... Das ganze wird erst problematisch bei kleineren Zahlen nach dem Komma... Da das Versenden problemlos funktioniert, scheint evtl die VB Funktion BitConverter.ToSingle() Probleme zu verursachen... Gibts hier alternative Funktionen? Ich weiß das in jedem Prozessor die Gleitkommazahlen anders gehandhabt werden können, aber mit einer entsprechend guten Funktion müsste doch die AVR Darstellung der float Zahl wieder herstellbar sein. Eine 3 stellige Genauigkeit würde mir völlig ausreichen, obwohl float/single ja eine 7 stellige besitzen sollte... Schonmal danke MfG Basti
dann finde doch erstmal die genaue ursache. Las dir das sigle als HEX am PC anzeigen, dann übertrage es zum AVR. Lass es dir wieder als Wert und als Hex anzeigen. Wenn du es jetzt erneut zum PC überträgst dann sollte es ja noch der gleiche HEX wert sein. Wenn du jetzt BitConverter.ToSingle() aufrufst dann muss auch wieder das gleiche rauskommen.
Ja die Ursache liegt zwischen AVR zu PC (VB.net) Durch LCD am AVR seh ich ja, dass ein sinnvoller float angekommen ist... Dabei ist mir egal ob aus dem 0,004 -> 0,00398 geworden ist... Aber wenn ich das ganze zurück an den Rechner sende, verhaut es mir die Zahl um ~40% Achso das Senden in C (AVR) hab ich so veranstaltet:
1 | union konverterf |
2 | {
|
3 | unsigned char c[4]; //4 Byte |
4 | float f; //4 Byte |
5 | };
|
6 | |
7 | |
8 | void uart_putf(float data) |
9 | {
|
10 | union konverterf z; |
11 | |
12 | z.f = data; |
13 | |
14 | uart_putc(z.c[0]); |
15 | uart_putc(z.c[1]); |
16 | uart_putc(z.c[2]); |
17 | uart_putc(z.c[3]); |
18 | |
19 | |
20 | }/* uart_putf */ |
Das einlesen in VB über den besagten BitConverter und dem SerialPort Interface + SerialPort.Encoding = Encoding.GetEncoding(28591). Beide Baugruppen laufen bei mir schon seit nem Jahr "problemfrei"... heute hab ich solch kleine Zahlenwerte versenden wollen und da bin ich erstmal darauf gestoßen... :-/ MfG Basti
Bassti schrieb: > Aber wenn ich das ganze zurück an den Rechner sende, verhaut es mir die > Zahl um ~40% wenn du aber einen Wert zum AVR schickt und diesen gleich wieder zurück zum pc müssen bei PC erstmal die gleiche Daten (also diese 4bytes) ankommen. Hast du das geprüft?
So, hab mal nachgeschaut... Also zuerst was raus geht mit folgendem Hilfsmittel: MsgBox(BitConverter.ToUInt32(xxx)) Das Ergab in Hex umgerechnet: 3B83126F Dann das was der Controller Sendet mit HTerm abgefangen: 3B83126F Und nun was mein Programm draus macht... selbe Funktion wie oben UInt32: 3B3F126F kA was das soll :-/ genau in der Mitte stimmt was nicht...
welche gleitkommazahl soll denn die 3B83126F darstellen?
das kommt bei mir raus: byte[] a = new byte[4]; a[0] = 0x3B; a[1] = 0x83; a[2] = 0x12; a[3] = 0x6F; Single s = BitConverter.ToSingle(a, 0); //s = 4.534346E+28 a[3] = 0x3B; a[2] = 0x83; a[1] = 0x12; a[0] = 0x6F; Single s2 = BitConverter.ToSingle(a, 0); //s2 = 0.004
dann ist der Fehler evtl bei der Encoding.GetEncoding Zeile zu suchen... was stellst du denn für ein Code ein? Erstmal danke für deine Hilfe...
Bassti schrieb: > dann ist der Fehler evtl bei der Encoding.GetEncoding Zeile zu suchen... der Fehler ist das du überhaupt Enconding verwendest. Wenn du binary Daten austauscht dann hat das dort nichts zu suchen!
Wenn ich die Zeile auskommentiere hab ich aber den selben Fehler im float lesen und meine signed short variablen sind alle positiv... auch nicht viel besser... Jedenfalls würde ich die Funktion des BitConverters erstmal als Funktionsfähig bezeichnen... aber das Serialportinterface braucht noch die richte Codierung :-/
Bassti schrieb: > aber das Serialportinterface braucht noch > die richte Codierung nein braucht es nicht, du darst auf keinen fall ein String lesen, du musst ein byte array lesen! Und bytes haben keine codierung.
Ach verdammt, dafür müsste ich das komplette Programm umstricken :-/
Bassti schrieb: > Ach verdammt, dafür müsste ich das komplette Programm umstricken :-/ dann hast du aber kein sauberes design, normalweise sollte senden und empfangn zentral an einer stelle sein. von dort geht es dann mit eigenen Datentype und stukturen weiter. Zeig doch mal den code.
freu habs gerade noch hinbekommen... das erspart mir nen Haufen Arbeit... Also das mein VB Code nicht wirklich sauber ist, dass weiß ich... Ist mehr zusammen gegoogelt... bin eher C programmierer... demnächst wird das Tool noch auf C# portiert... obwohl das ja auch nicht viel mit C aufn AVR am Hut hat... Achso, hier die Lösung: Wenn ich dem Serial Port die Encodernummer 28591 zuweise, dann muss ich beim decodieren vom String in ein Byte arryer mit System.Text.Encoding.GetBytes auch die selbe encoding Nummer vorwählen... die stand noch auf default... :-/ peinlich peinlich... Danke für deine Mühe!!! MfG Basti
Bassti schrieb: > Achso, hier die Lösung: > Wenn ich dem Serial Port die Encodernummer 28591 zuweise das würde ich nicht als Lösung betrachten, mehr als Workaround. Die Verwendung von Strings ist hier einfach falsch und kann dir immer wieder probleme machen. Du hast keine Strings! du übeträgst einfach DATEN und diese speicher man nun mal nicht in strings sondern in byte arrays.
Mag sein, aber möchte gern die praktische Funktion SerialPort.ReadTo(abschlusszeichen) benutzen. (zu faul was selbst zu schreiben) Und wenn ichs hin und her codiere gehts ja auch erstmal, sollte man halt nur mit dem selben Encoder machen... =) Bei nächsten Projekt werd ich dann gleich mit Bytes anfangen...
Bassti schrieb: > Mag sein, aber möchte gern die praktische Funktion > SerialPort.ReadTo(abschlusszeichen) benutzen. (zu faul was selbst zu > schreiben) do { byte b = SerialPort.ReadByte(); data.add(b); } while( b != abschlusszeichen ) > Und wenn ichs hin und her codiere gehts ja auch erstmal, sollte man halt > nur mit dem selben Encoder machen... =) und du hast auch alle Steuerzeichen getestet? Du weist also genau wie dein codierung auf jedes Zeichen reagiert - dann ist ja gut. Ich würde mich nicht darauf verlassen.
wenn du mit SerialPort.ReadTo(abschlusszeichen) arbeitest wie stellst du überhaupt sicher das sich in deinem single sich das Abschlusszeichen nicht befindet?
darüber das der scalierungswert nur von 1 bis 0,001 geändert werden kann und das Abschlusszeichen sich nicht in dem Bereich befindet -> z.b. exponent Ich seh ein, dass es nur ne Notlösung ist... aber da es Hobbybereich betrifft werd ich nicht mehr alles auf Byte ummünzen... zumal es bald eine komplett neue Software gibt... Wie würde man denn am besten sicher stellen das es wirklich das Abschlusszeichen ist, wenn man alle float-varianten drin hat?
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.