www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik floats am Mega16


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: xy? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
x?
y?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zB: y = 20.567 und x = 60.1

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

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Fritz Ganter (fritzg)
Datum:

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

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int16_t ist schlecht ! Nimm doch einfach: float x,y;

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab natuerlich den atan2 hergenommen... sorry, hab den code falsch
abgeschrieben.

dank,
mg,
Johannes

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

mg,
Johannes

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.