Forum: Mikrocontroller und Digitale Elektronik STM32F4 adc atan2 problem


von Li W. (kwilly_d)


Lesenswert?

Hallo Liebe Leute,

von einem Beschleunigungssensor wollte ich den Winkel ausrechnen.
Ich messe über ADC1 ADC2 die 2 Beschleunigungen und weise diese an atan2 
zu.
1
 
2
float aX = (float)ADC_GetConversionValue(ADC1);  
3
float aZ = (float)ADC_GetConversionValue(ADC2);  
4
5
printf("aX: %f \n", aX);
6
printf("aZ: %f \n", aZ);
7
8
/*bis hier funktioniert problemlos*/
9
10
float winkel = (float)atan2(aZ, aX);

/* hier wenn ich aZ, aX als Variable zuweise rechnet atan2 weiter nicht 
mehr. arm-none-eabi kompiliert ohne problem. wenn ich das elf datei auf 
controller lade, passiert im µcontroller leider nichts, als würde alles 
stehen bleiben. */
1
float winkel = (float)atan2(10, 10);
/* wenn ich da oben so als variable 10 zuweise, funktioniert ganz gut. 
*/

was habe ich falsch gemacht.

Entschuldigung für mein fehlerhaftes Deutsch.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Verwende mal die float-Version "atan2f" anstelle der double-Version 
"atan2", da deine Eingabe und Ausgabewerte onehin float sind und die FPU 
außerdem nur "float" kann, aber nicht "double".

von Li W. (kwilly_d)


Lesenswert?

ok mache ich gleich

von Li W. (kwilly_d)


Lesenswert?

so eine Fehlermeldung kriege ich. atan2 gab es diese nicht.

warning: incompatible implicit declaration of built-in function 'atan2f' 
[enabled by default]

von Dr. Sommer (Gast)


Lesenswert?

Das ist eine Warnung. Hast du #include <math.h> oder -lm vergessen?

von Li W. (kwilly_d)


Lesenswert?

die sind schon dabei. auch flag

von Li W. (kwilly_d)


Lesenswert?

1
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb-interwork  -Os  -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DMANGUSTA_DISCOVERY -DUSE_USB_OTG_FS -DHSE_VALUE=8000000 -I./ -I./ -I../Libraries/CMSIS/Include -I../Libraries/STM32F4xx_StdPeriph_Driver/inc/ -I../Libraries/STM32_USB_Device_Library/Class/hid/inc -I../Libraries/STM32_USB_Device_Library/Core/inc/ -I../Libraries/STM32_USB_OTG_Driver/inc/  -Wl,-T,stm32_flash.ld main.c init.c syscalls.c stm32f4xx_it.c system_stm32f4xx.c stm32f4_discovery.c printf.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c startup_stm32f4xx.s  -lc -lm -o prog.elf
2
main.c: In function 'getAccY':
3
main.c:174:19: warning: incompatible implicit declaration of built-in function 'atan2f' [enabled by default]
4
arm-none-eabi-objcopy -O ihex prog.elf prog.hex

das hier ist der ausgabe vom makefile

von Li W. (kwilly_d)


Lesenswert?

Dr. Sommer schrieb:
> Verwende mal die float-Version "atan2f" anstelle der double-Version
> "atan2", da deine Eingabe und Ausgabewerte onehin float sind und die FPU
> außerdem nur "float" kann, aber nicht "double".

achso, warum double aus mysteriösen Gründen nicht funktionierte.

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> das hier ist der ausgabe vom makefile
Füge mal noch -std=c99 zu den Flags hinzu. Eigentlich sollte es die 
Funktion geben:
http://en.cppreference.com/w/c/numeric/math/atan2
Bei mir funktioniert das auch mit dem gcc-arm-embedded.

Li Wang schrieb:
> achso, warum double aus mysteriösen Gründen nicht funktionierte.
Funktionieren schon, aber sehr ineffizient da die CPU nur 
single-precision-float (32bit) unterstützt, du aber die 
double-precision-float (64bit) Funktion aufrufst, die dann alles in 
Software, ohne FPU, rechnen muss.

von Li W. (kwilly_d)


Lesenswert?

mkey

von Li W. (kwilly_d)


Lesenswert?

main.c:174:5: warning: implicit declaration of function 'atan2f' 
[-Wimplicit-function-declaration]
main.c:174:19: warning: incompatible implicit declaration of built-in 
function 'atan2f' [enabled by default]
main.c: In function 'SerialEmpfangen':
main.c:191:9: warning: implicit declaration of function 'PrintChar' 
[-Wimplicit-function-declaration]
arm-none-eabi-objcopy -O ihex prog.elf prog.hex

jetzt funktioniert nicht mal usart. :(

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> jetzt funktioniert nicht mal usart. :(
Dir fehlen ziemlich sicher ein paar #include Anweisungen...

von Li W. (kwilly_d)


Lesenswert?

Dr. Sommer schrieb:
> Li Wang schrieb:
>> jetzt funktioniert nicht mal usart. :(
> Dir fehlen ziemlich sicher ein paar #include Anweisungen...

wenn ich -std=c99 Flag entferne geht usart

von Li W. (kwilly_d)


Lesenswert?

hat das Problem mit FPU Konfiguration zu tun? evtl mit newlib .
 davon weiss ich so gut wie nix

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> wenn ich -std=c99 Flag entferne geht usart
Wohl weil C dann weniger streng ist. Füge die fehlenden #include 
Anweisungen in deinem Quellcode hinzu.

von Li W. (kwilly_d)


Lesenswert?

funktioniert immer noch nicht
hab allerdings nötige headers schon inkludiert

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> funktioniert immer noch nicht
> hab allerdings nötige headers schon inkludiert
Dann machst du was falsch. Zeige den aktuellen Code und die komplette 
aktuelle Ausgabe von "make".

von Li W. (kwilly_d)


Lesenswert?

arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mlittle-endian 
-mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb-interwork  -Os 
-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DMANGUSTA_DISCOVERY -DUSE_USB_OTG_FS 
-DHSE_VALUE=8000000 -I./ -I./ -I../Libraries/CMSIS/Include 
-I../Libraries/STM32F4xx_StdPeriph_Driver/inc/ 
-I../Libraries/STM32_USB_Device_Library/Class/hid/inc 
-I../Libraries/STM32_USB_Device_Library/Core/inc/ 
-I../Libraries/STM32_USB_OTG_Driver/inc/  -Wl,-T,stm32_flash.ld main.c 
init.c syscalls.c stm32f4xx_it.c system_stm32f4xx.c stm32f4_discovery.c 
printf.c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c 
../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c 
startup_stm32f4xx.s  -lc -lm -std=c99 -o prog.elf
main.c: In function 'getAccY':
main.c:175:5: warning: implicit declaration of function 'atan2f' 
[-Wimplicit-function-declaration]
main.c:175:12: warning: incompatible implicit declaration of built-in 
function 'atan2f' [enabled by default]
arm-none-eabi-objcopy -O ihex prog.elf prog.hex

von Dr. Sommer (Gast)


Lesenswert?

Okay jetzt noch den Source Code.

von Li W. (kwilly_d)


Lesenswert?

1
 
2
#include <stdio.h>
3
#include <stm32f4_discovery.h>
4
#include "config.h"
5
#include <stdbool.h>
6
#include <math.h>
7
#include <stdlib.h>
8
#include <string.h>
9
10
int main(void)
11
{
12
    all_config();
13
    
14
    
15
    
16
    while (1){
17
        
18
        GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
19
        GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
20
        GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
21
        GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
22
    
23
        float angle = getAccY();
24
        printf("angle %f \n",angle);
25
       
26
    }
27
    return 0;
28
}
29
30
float getAccY(void) {
31
32
33
    float accXval = getValueADC2()*327/409600;
34
    float accZval = getValueADC3()*327/409600;
35
    return atan2f(accXval, accZval);
36
}
37
void Delay(__IO uint32_t nCount)
38
{
39
  while(nCount--)
40
  {
41
  }
42
}
43
#ifdef  USE_FULL_ASSERT
44
45
void assert_failed(uint8_t* file, uint32_t line)
46
{ 
47
  while (1)
48
  {
49
  }
50
}
51
#endif

: Bearbeitet durch User
von Li W. (kwilly_d)


Lesenswert?

ich glaube es liegt evtl. bei fpu configuration

von Dr. Sommer (Gast)


Lesenswert?

Das kann nicht der richtige Code sein. Diese Datei hat keine Zeile 175 
(wegen *main.c:175:5:* warning: implicit declaration of function 
'atan2f').
Der Code funktioniert bei mir mit -std=c99 und ohne.

Li Wang schrieb:
> ich glaube es liegt evtl. bei fpu configuration
Die hat keinen Einfluss auf den Compiler.

von Li W. (kwilly_d)


Lesenswert?

ich habe im makefile "-mfloat-abi=softfp" mit hard fpu getauscht 
geschrieben.

es geht mit warnung aber hauptsache es funktioniert. danke Herr Dr. 
Sommer! :)

von Li W. (kwilly_d)


Lesenswert?

aber warum das so ist, würde ich sehr gerne wissen.

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> aber warum das so ist, würde ich sehr gerne wissen.
Wenn du den tatsächlichen *vollständigen* Code und die dazugehörigen 
make-Ausgabe zeigen würdest (als Anhang!), könne man das vielleicht 
sagen.

von RP6conrad (Gast)


Lesenswert?

Die Messwerte das du von sensoren bekommst sind normal doch integer ? 
Versuche mal Ax und Ay als integer zu deklarieren. Vermutlich akzeptiert 
atan2() nur integers. Bei mir funtioniert das so problemlos (discovery 
stm32F100).

von Dr. Sommer (Gast)


Lesenswert?

RP6conrad schrieb:
> Versuche mal Ax und Ay als integer zu deklarieren. Vermutlich akzeptiert
> atan2() nur integers.
Quatsch. Wie gesagt ist atan2 für double und atan2f für float. Ax und Ay 
als integer zu deklarieren würde zum Genauigkeitsverlust führen da er ja 
dividiert. Jetzt sehe ich aber gerade dass er die Division komplett als 
Integer rechnet, daher mal folgendermaßen abändern:
1
float accXval = ((float) getValueADC2())*327.f/409600.f;

von Li W. (kwilly_d)


Lesenswert?

die warnung war deswegen da ich oben
1
 float atan2f(float y, float x);
funktionsprototyp nicht deklariert habe. ich vergesse es oft.

von Li W. (kwilly_d)


Lesenswert?

>
1
float accXval = ((float) getValueADC2())*327.f/409600.f;

ja das ist es.

danke

von Li W. (kwilly_d)


Lesenswert?

eine dumme Frage.

float a = 10.1;
float a = 10.1f;
float a = (float)101/10;

sind das alle selbe oder? welche Deklaration ist besser?

Viele Grüße aus Innsburg

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> die warnung war deswegen da ich oben
>  float atan2f(float y, float x); funktionsprototyp nicht deklariert
> habe. ich vergesse es oft.
Das braucht man auch seit ca. 30 Jahren nicht mehr zu machen. Du musst 
nur "#include <math.h>" schreiben, denn die math.h enthält eben diesen 
Funktionsprototyp. Das funktioniert so auch normalerweise...

Li Wang schrieb:
> float a = 10.1;
Diese definiert einen double vom Wert 10.1 und konvertiert diesen in 
einen float.
> float a = 10.1f;
Diese definiert direkt einen float mit dem Wert 10.1 und ist daher am 
besten.
> float a = (float)101/10;
Das ist viel zu umständlich und fehleranfällig.

von Li W. (kwilly_d)


Lesenswert?

Dr. Sommer schrieb:
> Li Wang schrieb:
>> die warnung war deswegen da ich oben
>>  float atan2f(float y, float x); funktionsprototyp nicht deklariert
>> habe. ich vergesse es oft.
> Das braucht man auch seit ca. 30 Jahren nicht mehr zu machen. Du musst
> nur "#include <math.h>" schreiben, denn die math.h enthält eben diesen
> Funktionsprototyp. Das funktioniert so auch normalerweise...

math.h ist schon dabei.
ich müsste den prototyp schreiben sonst meckert der compiler

> Li Wang schrieb:
>> float a = 10.1;
> Diese definiert einen double vom Wert 10.1 und konvertiert diesen in
> einen float.
>> float a = 10.1f;
> Diese definiert direkt einen float mit dem Wert 10.1 und ist daher am
> besten.
>> float a = (float)101/10;
> Das ist viel zu umständlich und fehleranfällig.

super danke!!

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> math.h ist schon dabei.
> ich müsste den prototyp schreiben sonst meckert der compiler
Das kann gar nicht sein, das muss funktionieren. Welchen Compiler 
genau verwendest du? Zeig doch mal ein komplettes Beispiel mit 
komplettem Code...

von Li W. (kwilly_d)


Lesenswert?

Dr. Sommer schrieb:
> Li Wang schrieb:
>> math.h ist schon dabei.
>> ich müsste den prototyp schreiben sonst meckert der compiler
> Das kann gar nicht sein, das muss funktionieren. Welchen Compiler
> genau verwendest du? Zeig doch mal ein komplettes Beispiel mit
> komplettem Code...

summon-arm-toolchain bzw. arm-none-eabi-gcc
ich bin in c anfänger.
mein komplete Code ist zu doof und lächerlich. ich will nicht dass Ihr 
vor Lachen stirbt.

von Dr. Sommer (Gast)


Lesenswert?

Li Wang schrieb:
> mein komplete Code ist zu doof und lächerlich. ich will nicht dass Ihr
> vor Lachen stirbt.
Na, jeder hat so angefangen. Kürze ihn halt soweit dass das Problem noch 
auftritt.

Li Wang schrieb:
> summon-arm-toolchain bzw. arm-none-eabi-gcc
summon kenne ich nicht, aber mit dem gcc-arm-embedded von 
https://launchpad.net/gcc-arm-embedded funktioniert es definitiv, und 
sollte auch mit jedem Compiler der C99 unterstützt funktionieren...

von Karl (Gast)


Lesenswert?

Summon-arm hat einen Bug was die Konvertierung von float nach double 
angeht. Weg mit dem Mist. Hab ich auch hier ins Wiki geschrieben.

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.