Hallo, ich dachte, man kann mit dem WINAVR-GCC einfach floats verwenden und damit rechnen wie bei jedem anderen compiler... folgendes hab ich definiert: #include <math.h> float x,y,jamp,jalpha; jalpha = atan(y/x); jamp = sqrt(x*x + y*y); Es kommt nix heraus, was ich fuer richtig halten koennte... Was macht man um auf einem uC mit asin, cos, sin usw rechnen zu koennen?(Rechenzeit relativ wurscht) mg, Johannes
zB: y = 20.567 und x = 60.1 aber auch ganz einfach mit y=3 und x=6 kann ichs nicht nachvollziehen...
wer hat schon einmal mit der asin, atan, sin oder cos-Funktion gearbeitet die mit WINAVR mitgeliefert wird? kann man float-Variablen auf dem ATMega16 verwenden? oder muss man da irgendwie tricksen? Johannes
Du weisst schon dass man in Radiant rechnet und nicht Grad? Die Routinen funktionieren.
int16_t x,y; float jalpha; .... x=10; y=5; jalpha = atan(y/x)*100; //atan(0.5)*100 = 0.4636*100 = 46.36 UDR = (uint8_t)(jalpha); //casten und auf UART schieben Uebertragen wird leider eine glatte Null anstatt 46. Wenn ich atan(1000) berechnen lasse (atan(1000)=1.569) dann kommt eine 100 rueber was auch stimmt. Meine Schlussfolgerung, die float Variablen werden im ATMega falsch gehandelt. Alles was kleiner als 1 ist bleibt offensichtlich eine Null; oder seht ihr da einen Fehler bei meinen Ueberlegungen? mg, Johannes
Genau. y/x mit int in der genannten Aufgabe ergibt: atan(y/x) = atan(5/10) = atan(0), solange y<x gilt. Aber es ist deklariert: double atan(double __x), so dass du atan(5.0/10.0) wählen musst. Gruß Marco
yuhuuuu! Dankeschoen. Tja, irgendwannmal hatte ich das ja "gelernt" gehabt, wie der compiler bei solchen Sachen arbeitet... ich denke jetzt hab ichs echt gelernt! mg, Johannes
Uebrigens: mit der atan() Funktion kann man meist nichts rechtes machen. Besser ist atan2(). Die bestimmt Dir dann auch noch den Quadranten richtig und den Fehler in der Division haettest Du auch nicht gemacht.
ich hab natuerlich den atan2 hergenommen... sorry, hab den code falsch abgeschrieben. dank, mg, Johannes
Seid gegruesst, die Variante mit der union gefaellt mir ganz gut, nur funktioniert sie nicht wie ich will. Hier meine relevanten CodeBeispiele vom Mikorcontroller. union UART_ANGLE { float ang; char aux[4]; }; volatile union UART_ANGLE angle; volatile float winkel[2]; .... //byte-Uebernahme aus dem Protokoll angle.aux[0] = rec_command[2]; angle.aux[1] = rec_command[3]; angle.aux[2] = rec_command[4]; angle.aux[3] = rec_command[5]; winkel = angle.ang; und wenn ich mir jetzt "winkel" anschaue steht da eine glatte Null, obwohl die Variablen angle.aux die vier bytes einer float-Variable sind (hab ich ueberprueft): angle.aux[0] = 0x41 angle.aux[1] = 0xA8 angle.aux[2] = 0x00 angle.aux[3] = 0x00 0x41 A8 00 00 is die Darstellung in hex der Zahl 10.5: Vorzeichenbit:0 Charakteristik:10000011 Mantisse: 0101000 00000000 00000000 was mach ich falsch? Oder: was gibt es sonst noch fuer Moeglichkeiten aus 4 einzelnen bytes eine float-Variable zu machen? Tipps sind wilkommen. Wenns mal funktioniert gibts den Code in der Sammlung. mg, Johannes
den Namen winkel hab ich fuers Forum geaendert... damits richtig ist denk euch anstatt der Zeile: winkel = angle.ang; diese hier: winkel[0] = angle.ang; sorry, Johannes
> was gibt es sonst noch fuer Moeglichkeiten aus 4 einzelnen > bytes eine float-Variable zu machen? Ne Menge. Im Ernst: float oder double binaer von einem Rechner zum anderen zu uebertragen ist 'Russisch Roulett'. Das kann gehen, wenn beide Compiler das gleiche Floatingpoint Format verwenden, muss aber nicht. Also: Hast Du schon ueberprueft ob der Sender und der Empfaenger das gleiche floating point Format benutzen?
Hallo Karl Heinz, ne, hab ich nicht überprüft. Wie macht man das? Der C-Code für den uC ist mit WinAVR compiliert und die serielle Schnittstelle am Rechner ist Standard. Vorlaeufig schick ich selbstgebastelte Befehle mit den 4bytes nach IEEE-Norm fuer einfache Genauigkeit (Beispiel siehe Beitrag oben). mg, Johannes
> Wie macht man das?
Indem Du Dir zb fuer ein paar Zahlen die
binaere Repräsentation (sprich: die Bytes)
auf beiden Systemen anschaust und vergleichst.
Sind sie identisch, dann ist das schon mal gut.
Wenn nicht: viel Spass.
Wenn du deine Ergebnisse mit printf() über die serielle Schnittstelle überträgst, kann es mit float auch zu problemen kommen, wenn du die falsche lib eingebunden hast (MAKEFILE). PRINTF_LIB = $(PRINTF_LIB_FLOAT) solltest du verwenden
Hallo zusammen, also mein Rechner und der uC stellen die floats beide in little endian darstellung dar. die bytes werden als "verkehrt" herum uebertragen. Habs getestet. Daran lag es auch, dass es nicht funktioniert hat mit der Uebertragung. Mein naechstes Problem ist die serielle Schnittstelle anzusprechen aus Windows; programmiere mit VisualC++. Mal sehen was es da alles im Forum schon gibt! Danke fuer eure Tipps und Hinweise. mg, Johannes
Ein kleines Programm das ueber ein Protocol einen float-Wert empfaengt gibt es in der Code Sammlung: http://www.mikrocontroller.net/forum/read-4-299980.html?reload=yes#299980 mg, Johannes
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.