PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Funktionen: sin(); cos(); tan(); ... aus math.h



Kaiser-F
28.09.2005, 13:45
Hallo Leute!

Ich gerade voll am proggen, und bin auf ein "Nebenproblem" gestoßen.

Ich will eine Drehzahlangabe graphisch als Zeiger darstellen. ( Auf nem LCD versteht sich ).

um icht jeden einzelnen wert, von 0-360° abspeichern zu müssen,
was ziemlich viel Flash kostet, will ich die werte berechnen lassen.

Habe dazu viele Infos in meinen C-Buch ( C von A bit Z ) gefunden.

In der Headertadei math.h sollen sich diese mathematischen Funktionen befinden:

double sin( double zahl );
double cos( double zahl );
double tan( double zahl );
double asin( double zahl );
double acos( double zahl );
double atan( double zahl );
double sinh( double zahl );
double cosh( double zahl );
double tanh( double zahl );
double log( double zahl );
double log10( double zahl );

usw...


Die frage ist nun, ob das bei den AVRs auch funktionert?

Die Header math.h ist vorhanden, und der Compiler nimmt das Ganze auch an.

Nur rauskommen tut nur 0:


x = (double) tan( ( double ) 70 );

USART_transmit( x );

Wisst Ihr evtl. mehr darüber?

tan70 sollte 2.47 sein. also müsste er 2 senden....

PicNick
28.09.2005, 14:09
Grad oder Bogenmaß ?

Kaiser-F
28.09.2005, 14:12
Gradmaß, sorry hab ich nicht erwähnt....

PicNick
28.09.2005, 14:18
Viele dieser Funktionen hätten afaik gerne Bogenmaß als Input

Kaiser-F
28.09.2005, 14:27
hmmm,

aber

x = (double) tan( ( double ) 1.0 );

gibt er auch 0 aus....

und bei 70 nüsste halt dann mit Bogenmaß 1.22 rauskommen, da 70 ja ca. 22mal p(3.14) ist.

Hast du schonmal mit diesen Funktionen gearbeitet?

Kaiser-F
28.09.2005, 14:30
Hast du schonmal mit diesen Funktionen gearbeitet?


War nicht böse gemeint... Will damit fragen ob die Funktionen überhaupt funktionieren mit den AVRs... Ansonsten muss ich selbst eine Funktion Programmieren um den Sinus zu berechnen....

FÜRCHT!

PicNick
28.09.2005, 14:36
..War nicht böse gemeint...

Ach was, ich bitte dich.
Ich verwend' sowas schon im Mengen, allerdings auf dem PC, da mir der AVR etwas leid tut.
Man müßt jetzt mal nachlesen, was es zu lesen gibt.

Bist du sicher, daß er nicht die ADDRESSE von dem double will ?

double funktion (double* value)

Kjion
28.09.2005, 15:43
Will damit fragen ob die Funktionen überhaupt funktionieren mit den AVRs...

Ja, tun sie. Und zwar sehr gut.

Wie oben schonmal gesagt erwarten sie die Werte im Bogenmaß.

Sowas steht zum Beispiel in dem Code für meinen Laufroboter:

/* Berechnung des Winkels um den das Bein angehoben wird */
a = sqrt( z * z + b * b ); // 250 µS
hebeWinkel = asin( ( FUSSLAENGE * sin(dtemp2) ) / a ) / M_PI * 180; // 840 µS
dtemp = 180 - asin( b / a ) / M_PI * 180 - hebeWinkel; // 310 µS
if ( z < 0)
dtemp = (-1) * dtemp - 2 * hebeWinkel; // 15 µS
dtemp = (dtemp / 180 ) * 255; // 55 µS

MfG Kjion

SprinterSB
28.09.2005, 16:01
Nö, die Prototypen sind zB

extern double sin(double __x) __ATTR_CONST__;


um icht jeden einzelnen wert, von 0-360° abspeichern zu müssen, was ziemlich viel Flash kostet, will ich die werte berechnen lassen.
Die trigonometrischen Routinen und allgemein float-Arithmetik braichen auch nicht gerade wenig Flash -- und zudem auch Rechenzeit und auch RAM. Übrigens implementiert die avr-libm nur den SFmode (also float). Die Prototypen sind allerdings wie oben, so daß hin- und hergewandelt wird. Die Genauigkeit von double hat man nicht.


x = (double) tan( ( double ) 70 );

USART_transmit( x );
Besser:
double x;
x = tan (70.0); Du bist sicher, daß dein USART_transmit (double) das macht, was du denkst? Und daß du die richtige libm.a verwendest?

tan70 sollte 2.47 sein. also müsste er 2 senden.
tan(70.0) ist 1.2219....

Kaiser-F
28.09.2005, 17:50
Vielen vielen Dank für eure Hilfe!

Schätze mal dass es daran lag, dass ich tan(70); geschrieben habe, und nicht tan(70.0);

der Vektor wurde mir nicht ausgegeben...
Wär aber fast ein Fehler von mir gewesen.

Nochmals danke!

@Sprinter;

tan(70) ist tatsächlich 1,221959918 :oops:

PicNick
28.09.2005, 18:56
Du hattest doch geschrieben (s.o):
x = (double) tan( ( double ) 70 );
heißt das, beim GCC funktioniert casting nicht ?

Pascal
28.09.2005, 19:49
bei mir funktioniert das casting mit dem gcc schon, ich verwende aber nur ganze Zahlen
vielleicht liegts auch daran

Übrigens implementiert die avr-libm nur den SFmode (also float)

also gehts vielleicht, wenn man nach float castet, ist aber nur ne Vermutung

PicNick
29.09.2005, 10:12
Dann hat aber die h-file nicht zu der Lib dazugepaßt. Ah so.

SprinterSB
29.09.2005, 10:28
Dann hat aber die h-file nicht zu der Lib dazugepaßt. Ah so.
Doch die Header passen schon zur Implementierung der libm. Nur ist die Genauigkeit eben nicht die, wie man sie von double gewohnt ist, sondern nur die von float.

PicNick
29.09.2005, 11:11
Moment, macht mich nicht wirre:
Function prototype (z.B):


double tan( double zahl );



hmmm,
aber
x = (double) tan( ( double ) 1.0 );
gibt er auch 0 aus....

Gibt's nur eine Erklärung:
Er hat ( double ) 1.0 gecastet, d.h. 8 Byte
d.s. im Intel-Format (Low sign. first)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f
das gibt nur NULL, wenn er jetzt nur das single (float) davon liest, also die ersten 4
0x00, 0x00, 0x00, 0x00
und das entspricht single 0.0
und dann ist der tangens auch null

also ---> function prototype <nix passt> library


edit : mit gewohnheit hatt das nix zu tun

SprinterSB
29.09.2005, 17:05
Vielleicht geht's ja einfach mit float?

#define FLOAT_TYPE_SIZE 32
/* A C expression for the size in bits of the type `float' on the
target machine. If you don't define this, the default is one word. */

#define DOUBLE_TYPE_SIZE 32
/* A C expression for the size in bits of the type `double' on the
target machine. If you don't define this, the default is two
words. */

PicNick
29.09.2005, 17:46
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 32
Ziemlich einheitlich.

Ich nehm' mal davon mit, daß da einige Fallstricke gespannt sind. Vorsicht scheint angebracht. Na ja.

Kjion
30.09.2005, 15:03
Ich nehm' mal davon mit, daß da einige Fallstricke gespannt sind. Vorsicht scheint angebracht. Na ja.

So schlimm ist's gar nicht. Man muss nur in Gedanken alle "double" zu "float" machen, dann stimmt wieder alles und man kann ganz normal damit arbeiten.

MfG Kjion

PicNick
30.09.2005, 15:11
.. in Gedanken alle "double" zu "float"..
Ich sag jetzt aber lieber nix.

nollsen
02.10.2005, 14:13
hi,

wie groß wird der zeiger überhaupt auf dem display?
er müsste schon ziemlich groß sein dass sich die verwendung der sin und cos funktionen lohnt; der avr kann nämlich nur software-floating point berchnungen,
bei den tinys wird selbst die multiplikation softwaremäßig gemacht

Maverick89
29.04.2008, 11:32
Hi

Hab ein Problem mit der log-Funktion: am AT Tiny26 (der natürlich für solche rechnungen blöd ist, aber es muss sein), wenn ich Log einbinde wächst mein programm um das zweifache des verfügbaren Speichers!!!

Wie kommt das? Wie mache ich es kleiner?

Ich verwende das aktuelle release von WinAVR und AVR Studi4, -Os ist an

SprinterSB
01.05.2008, 09:04
Float-Berechnungen sind sehr aufwändig, und das das in einen ATtiny26 net reinpasst wundert mich net...

log kann man auch einfacher berechnen, schau mal da für eine einfache Alternative:

http://de.wikipedia.org/wiki/Logarithmus#Berechnung_einzelner_Bin.C3.A4rziffern