Forum: Mikrocontroller und Digitale Elektronik Problem mit Funktion asin() aus math.h


von Tom (Gast)


Lesenswert?

Hallo zusammen,

ich habe folgendes Problem:

ich muss aus einigen Werten einen Winkel errechnen.

Die nötige Formel lautet: winkel=asin((d_out-d_out_null)/sens). Die 
Werte sehen z. B. so aus: d_out=1500, d_out_null=1024, sens=1638. Die 
einige Variable ist d_out im Bereich von 0d bis 2047d.

Mein Problem ist nun, dass die Funktion asin() nicht funktioniert. D. h. 
ich bekomme als ergebnis lediglich den Wert des Arguments, nicht aber 
den Arcussinus daraus. math.h ist allerdings included.

Equipment:

STK500,
AVR Studio 4.13
ATmega8

Was mache ich falsch??

Danke und Gruß

Tom

von X. Y. (jtr)


Lesenswert?

Poste mal den Codeabschnitt.

von Tom (Gast)


Lesenswert?

Anbei der Code:

Dieses Programm macht nicht mehr, als dass SCA_wert und asin() auf dem 
Display ausgegeben werden um Fehler zu suchen.

***********************************************************************+

//HEADERDATEIEN
#include <avr/io.h>
#include <util/delay.h>
#include <avr/own_lcd.h>
#include <avr/own_uart.h>
#include <avr/interrupt.h>
#include <avr/stdint.h>
#include <math.h>

//FESTLEGUNG UNABHÄNGIGER TYPENNAMEN
typedef unsigned int uint16;
typedef signed int sint16;
typedef unsigned char uint8;
typedef signed char sint8;

//DEFINITION GLOBALER VARIABLEN
volatile uint8 SCA_L; //unteres Register vom SCA
volatile uint8 SCA_H; //oberes Register vom SCA
uint16 SCA_HH; //oberes Register nach Bitmanipulation
uint16 SCA_LL; //unteres Register nach Bitmanipulation
double SCA_wert=0;
double winkel;

uint8 taus;
uint8 hun;
uint8 zehn;
uint8 ein;

uint8 taus_;
uint8 hun_;
uint8 zehn_;
uint8 ein_;



//FUNKTIONSPROTOTYPEN
void nm_intro (void);
uint8 runden(double);



//SERVICEROUTINE FÜR EMPFÄNGERINTERRUPT
SIGNAL(SIG_UART_RECV)
{
  //Einlesen zweier Werte über RS232 und Übergabe an Hilfsvariablen
  getch();
  SCA_H = got_cha;
  getch();
  SCA_L = got_cha;
  cli();  //Alle Interrupts global sperren
}




//HAUPTPROGRAMM
int main (void)
{
  lcd_init(); //Initialisieren des Displays
  nm_intro(); //Anzeige nach Start des Controllers
  initusart(); //RS232 initialisieren (in own_uart.h)

  lcd_clear();
  set_cursor(0,1);

  while(1)
  {


    SCA_HH = (SCA_H<<3);
    SCA_LL = (SCA_L>>5);

    SCA_wert=SCA_HH+SCA_LL;

    winkel = asin(((SCA_wert-1024)/1638));


                  //nachfolgend Visualisierung für Fehlersuche
                  winkel = winkel*1000;

    set_cursor(0,1);
    taus_=(SCA_wert/1000);
    lcd_data(taus_+0x30);
    hun_=(SCA_wert-(taus_*1000))/100;
    lcd_data(hun_+0x30);
    zehn_=(SCA_wert-(taus_*1000)-(hun_*100))/10;
    lcd_data(zehn_+0x30);
    ein_=(SCA_wert-(taus_*1000)-(hun_*100)-(zehn_*10));
    lcd_data(ein_+0x30);


    set_cursor(0,2);
    taus=(winkel/1000);
    lcd_data(taus+0x30);
    hun=(winkel-(taus*1000))/100;
    lcd_data(hun+0x30);
    zehn=(winkel-(taus*1000)-(hun*100))/10;
    lcd_data(zehn+0x30);
    ein=(winkel-(taus*1000)-(hun*100)-(zehn*10));
    lcd_data(ein+0x30);


    UCSRB |= (1<<RXCIE);  //Empfängerinterrupt frei
    sei();          //Alle Interrupts global frei
  }
  return 0;
}

von Bruno (Gast)


Lesenswert?

Mit der funktion gab es schon öfter Probleme.

Beitrag "asin() Merkwürdige Beobachtung"

Beitrag "asin() Probrlem"

vllcht hilft dir das weiter.

von lkmiller (Gast)


Lesenswert?

Gegeben deine Beispielwerte:
>d_out=1500, d_out_null=1024, sens=1638
Was kommt da zurück?
Was würdest du erwarten?

von Tom (Gast)


Lesenswert?

Danke für Eure Rückmeldungen.

@Bruno:
Die genannten Threads haben mir leider nicht weiter geholfen. Daran hab 
ich natürlich auch schon gedacht.....

@lkmiller:
für die genannten Werte bekomme ich 0.29 zurück (also genau den Wert des 
Arguments). Erwarten würde ich aber den Arcussinus, also 16.9

Noch Einfälle??

von Johannes M. (johnny-m)


Lesenswert?

Tom wrote:
> für die genannten Werte bekomme ich 0.29 zurück (also genau den Wert des
> Arguments). Erwarten würde ich aber den Arcussinus, also 16.9
Nö. Die Rückgabewerte der Funktion liegen im Bereich -pi/2...pi/2 
(Bogenmaß!). Und der Arcussinus von 0,29 ist nunmal zufälligerweise 
ungefähr 0,29 (0,2949, um etwas genauer zu sein, was mit 180°/pi 
multipliziert 16,8938 ergibt...). Vielleicht hättest Du mal andere Werte 
ausprobieren sollen...

von Johannes M. (johnny-m)


Lesenswert?

Übrigens: Wenn ich Probleme mit einer Bibliotheksfunktion habe, dann ist 
der erste Schritt, in der Dokumentation der Bibliothek nachzuschauen. 
Hättest Du den entsprechenden Blick in die AVR-libc-Doku geworfen, dann 
hättest Du ziemlich schnell gemerkt, dass da unmöglich 16,XYZ rauskommen 
kann...

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.