Forum: Mikrocontroller und Digitale Elektronik floats am Mega16


von Johannes (Gast)


Lesenswert?

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

von xy? (Gast)


Lesenswert?

x?
y?

von Johannes (Gast)


Lesenswert?

zB: y = 20.567 und x = 60.1

aber auch ganz einfach mit y=3 und x=6 kann ichs nicht
nachvollziehen...

von Johannes (Gast)


Lesenswert?

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

von Fritz G. (fritzg)


Lesenswert?

Du weisst schon dass man in Radiant rechnet und nicht Grad?
Die Routinen funktionieren.

von Johannes (Gast)


Lesenswert?

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

von Michael (Gast)


Lesenswert?

int16_t ist schlecht ! Nimm doch einfach: float x,y;

von Marco S (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Johannes (Gast)


Lesenswert?

ich hab natuerlich den atan2 hergenommen... sorry, hab den code falsch
abgeschrieben.

dank,
mg,
Johannes

von Johannes (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

> 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?

von Johannes (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

> 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.

von Bernd (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

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

von Johannes (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.