Forum: Mikrocontroller und Digitale Elektronik asin() Merkwürdige Beobachtung


von Efthi (Gast)


Lesenswert?

Hallo Leute,
ich habe eine merkwürdige Verhaltensweise des asin() in meinem code
entdeckt. Wenn ich die Variablen (zwei float Werte jeweils zwei
verschiedene Werte die mittels asin() errechnet werden) global
definiere berechnet der asin() faltsch (einen sehr kleinen Wert mit
10E-36), definiere ich die Variablen lokal rechnet er richtig.
Wie könnte mann dieses Verhalten erklären?

Gruß
Efthi

von Gernot F. (gernotfrisch)


Lesenswert?

Gibt's die lokale Var mit dem gleichen Namen nochmal??

von Efthi (Gast)


Lesenswert?

Nein

von Karl heinz B. (kbucheg)


Lesenswert?

Zeig mal den Code

von Efthi (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang der Code. Wenn ich die Variable fGraValueX und fGraValueY mit
X und Y ersetze funktioniert es. Das ist merkwürdig.

von Karl heinz B. (kbucheg)


Lesenswert?

In der Tat. Zumal im ganzen Code keine Variable 'X' bzw.
'Y' vorkommt.

von Efthi (Gast)


Lesenswert?

Im code den du hast stehen die eigentliche Variablen die ich nutzen
will. Ich habe die Variblen fGraValueX und fGraValueY ersetzt durch X
und Y. Dann funktioniert es.

von Efthi (Gast)


Lesenswert?

Könnte es an der Länge der Variablen liegen die ich dem asin() übergäbe?

von Dietmar (Gast)


Lesenswert?

Hast du den Definitionsbereich beachtet?

Gruß

Dietmar

von Efthi (Gast)


Lesenswert?

Ja, klar -1 und 1. Wird auch im Code abgefangen.

von Ingo (Gast)


Lesenswert?

> //calculate a gravitation value
> fGraValueX = (fCountsX - 1024)/819;
> fGraValueY = (fCountsY - 1024)/819;

versuche hier mal statt 819 -> 819.0 zu schreiben. könnte sein, dass
keine umwandlung in float passiert, weil der wert (fCountsX - 1024) und
819 keine floats sind.

von Marco S (Gast)


Lesenswert?

Uuuaahhh. Horrorcode.

So kriegt man seinen Flash voll. Da wären z.B. die switch-statements,
die immer READ-CHANNEL zurückgeben. Der Wertebereich wird mit
if(fCountsX >= 1842) und if(fGraValueX>1) gleich doppelt überwacht.
Dann wird einer float-variablen natürlich ein float-wert zugeordnet,
der zuvor int und davor float war fDecimValueX = (int)fDecimValueX
(soll wohl im prinzip floor(x) sein). Dieser float-Wert wird nach int
gewandelt und wie folgt verarbeitet: iPhysValueX = fDecimValueX. Da
iPhysValueX nur innerhalb der Datei sichtbar ist, endet die Berechnung
hier im Nirvana.

Der Compiler wird dir wohl das alles wegoptimieren und dann bleibt eben
nichts übrig. Vielleicht wirds besser wenn du
extern int iPhysValueX, iPhysValueY;
schreibst.


Gruß
Marco

von Efthi (Gast)


Lesenswert?

<if(fCountsX >= 1842) und if(fGraValueX>1) gleich doppelt überwacht.>
Hast recht ist nicht nötig


<Dann wird einer float-variablen natürlich ein float-wert zugeordnet,
der zuvor int und davor float war fDecimValueX = (int)fDecimValueX
(soll wohl im prinzip floor(x) sein). Dieser float-Wert wird nach int
gewandelt und wie folgt verarbeitet: iPhysValueX = fDecimValueX. Da
iPhysValueX nur innerhalb der Datei sichtbar ist, endet die Berechnung
hier im Nirvana.>

Für die Berechnung des asin() benötige ich einen float Wert.
Die Variablen iPhysValueX und iPhysValueY werden weiter im CAN-stack
verarbeitet und da benötige ich nunmal int. Das ist nur ein c-file vom
ganzen Projekt.

von Efthi (Gast)


Lesenswert?

Hi Ingo,
hab es versucht. Klappt leider nicht.

von Marco S (Gast)


Lesenswert?

Wie durch extern im Kommentar angedeutet, gibt es wohl irgendwo in einem
anderem Programmmodul die int-Variable iPhysValueX.

/*--------------------------------------------------------------------*/
/*  external data
*/
/*--------------------------------------------------------------------*/
extern float fGraValueX, fGraValueY;
extern float fDecimValueX, fDecimValueY;
extern int iPhysValueX, iPhysValueY;

...

void mainVTI(){
 float fCountsX = (float)readsca (READ_X_CHANNEL_VTI);
 float fCountsY = (float)readsca (READ_Y_CHANNEL_VTI);

 fGraValueX = (fCountsX - 1024)/819;
 fGraValueY = (fCountsY - 1024)/819;

 if(fGraValueX>1)
   fGraValueX = 1;
 else if(fGraValueX<-1)
   fGraValueX = -1;

 if(fGraValueY>1)
   fGraValueY = 1;
 else if(fGraValueY<-1)
   fGraValueY = -1;

#if VTI_XY == 1
 CLI(); //disable all interrupts to avoid miscount
 fDecimValueX = asin(fGraValueX) * (180.0/M_PI); // calculates angle of
y-axis inclination
 fDecimValueX = fDecimValueX * 100;

 fDecimValueY = asin(fGraValueY) * (180.0/M_PI); // calculates angle of
x-axis inclination
 fDecimValueY = fDecimValueY *100;
 SEI();//re-enable interrupts

 iPhysValueX = (int) fDecimValueX;
 iPhysValueY = (int) fDecimValueY;

 CanOpenInterface();
#endif /* VTI_XY == 1 */
}

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.