Forum: Mikrocontroller und Digitale Elektronik Probleme mit float Berechnung


von Hans Peter (Gast)


Lesenswert?

Hallo!

Ich verwenden den AT32UC3C (AVR Studio6) und berechne in meinem Programm 
float variablen. Das Ganze hat immer funktioniert, nun bin ich auf ein 
neues Board (eigene Hardware) umgestiegen und habe auf einmal Probleme 
mit den float-Variablen.

Hier der Code:
1
void SamplingTimerCallback()
2
{
3
  float voltage = 5.5;
4
  
5
  for (U8 i = 0; i < TEMP_CONTROL_NUM_CONTROLS; i++)
6
  {
7
    control_array[i].Ta_counter++;
8
    if(control_array[i].Ta_counter > control_array[i].Ta * 100 )      // sampling time is reached, * 100 because Ta is adjusted in s, and this callback function is called every 10ms -> * 1000/10
9
    {
10
      S16 adc_value = GetAdcValue(control_array[i].channel_ID);
11
      if(adc_value != ADC_NOT_READY)
12
      {
13
        voltage = (adc_value * TEMP_CONTROL_REF_VOLTAGE) / TEMP_CONTROL_ADC_RANGE;
14
        float res_ntc = TEMP_CONTROL_R_SERIES_NTC / ((TEMP_CONTROL_VOLTAGE_DIVIDER/voltage) - 1);
15
        
16
        // differntiate between different NTCs for carousel temp and heatsinks temp:
17
        float temp_ntc = 0.0;
18
        if(i==0)
19
        {
20
          temp_ntc = (TEMP_CONTROL_NTC_B_VALUE_1 * TEMP_CONTROL_NTC_NOMINAL_TEMP) / (TEMP_CONTROL_NTC_B_VALUE_1 + ( log(res_ntc / TEMP_CONTROL_NTC_NOMINAL_VALUE) * TEMP_CONTROL_NTC_NOMINAL_TEMP)) - 273.15;
21
        }
22
        else
23
        {
24
          temp_ntc = (TEMP_CONTROL_NTC_B_VALUE_2 * TEMP_CONTROL_NTC_NOMINAL_TEMP) / (TEMP_CONTROL_NTC_B_VALUE_2 + ( log(res_ntc / TEMP_CONTROL_NTC_NOMINAL_VALUE) * TEMP_CONTROL_NTC_NOMINAL_TEMP)) - 273.15;
25
        }
26
        // --------------------------------------------------------------------------
27
        
28
        control_array[i].actual_value = temp_ntc;
29
        
30
        PID_control(&control_array[i]);
31
        
32
        control_array[i].ControlFunction(control_array[i].controlled_variable);
33
        
34
        control_array[i].Ta_counter = 0;  
35
      }
36
37
    }
38
  }
39
  TimerRestart(SamplingTimer);
40
}

das Ganze wird einfach alle 10ms aufgerufen und float werte (z.B. 
voltage) berechnet. Alle float variablen haben jedoch sehr hohe werte 
und stimmen überhaupt nicht.

voltage = (adc_value * TEMP_CONTROL_REF_VOLTAGE) / 
TEMP_CONTROL_ADC_RANGE;
adc_value ist ein normaler S16, dessen wert auch immer stimmt (1345)
TEMP_CONTROL_REF_VOLTAGE ist eine Konstante mit 2.345 definiert
TEMP_CONTROL_ADC_RANGE ist eine Konstante mit 2048 definiert.

für voltage kommt jedoch immer die Zahl 1065353216 raus, keine Ahnung 
warum!
Kann mir dabei jemand weiterhelfen?

Danke, lG

von Purzel H. (hacky)


Lesenswert?

Und weshalb muss man float in eibnen timer rechnen ? Die gezeigten float 
Rechnungen dienen dem benutzerinterface und brauchen daher nur mit 
Userinterface Geschwindigkeit neu berechnet werden.

Zum Problem. Der UC3C hat eine FPU, andere ev nicht, dann macht es die 
Library. Allenfalls in dieser Richtung weitersuchen.

Dann sich Zwischnewerte per UART oder so ausgeben lassen um den fehler 
zu finden.

: Bearbeitet durch User
von Hans Peter (Gast)


Lesenswert?

Siebzehn Zu Fuenfzehn schrieb:
> Zum Problem. Der UC3C hat eine FPU, andere ev nicht, dann macht es die
> Library. Allenfalls in dieser Richtung weitersuchen.

Ich verwende weiterhin den gleichen Controller.
Keine Ahnung, warum das nicht mehr funktioniert :(

von Hans Peter (Gast)


Lesenswert?

es ist übrigens egal, wie groß adc_value ist. der wert von voltage 
bleibt imme rgleich, kann sich das jemand erklären?

von Peter II (Gast)


Lesenswert?

Hans Peter schrieb:
> es ist übrigens egal, wie groß adc_value ist. der wert von voltage
> bleibt imme rgleich, kann sich das jemand erklären?

wo siehst du denn den wert? Im Debugger, wenn ja mal ohne Optimierung 
testen.

von Hans Peter (Gast)


Lesenswert?

ja im Debugger. Hab keine Optimierung an!

von Hans Peter (Gast)


Angehängte Dateien:

Lesenswert?

Um das Ganze einfacher zu machen:
Hab nun zum test in der Main aingefügt:

float a = 5.3;
float b = 2.4;
float c = a*b;

Wenn ich unmittelbar nach diesen 3 Zeilen einen Breakpoint setzte, und 
mir die werte anschaue:
a= 1084856730
b= 1075419546
c= 1095468320

Siehe Anhang!
Schön langsam verstehe ich die Welt nicht mehr...

Bitte um Hilfe!
Danke!

von Peter II (Gast)


Lesenswert?

Hans Peter schrieb:
> Schön langsam verstehe ich die Welt nicht mehr...

sicher das du ohne Optimierung arbeitest?

Verwende mal die Variabel C ( z.b in einem Printf )

printf("%f", c );

von Hans Peter (Gast)


Lesenswert?

Peter II schrieb:
> printf("%f", c );

wo wird dass dann ausgegeben?

von Peter II (Gast)


Lesenswert?

Hans Peter schrieb:
> wo wird dass dann ausgegeben?

ist egal, spiel keine rolle. Ist nur das der optimiere es nicht 
wegoptimiert.

von Hans Peter (Gast)


Lesenswert?

ok, das hab ich jetzt gemacht, was soll ich daraus sehen?

von Hans Peter (Gast)


Lesenswert?

wenn ich volatile vor float setze, habe ich das gleiche Problem. Meines 
wissens dürfte er mit volatile deklarierte variablen nicht 
wegoptimieren, also liegts nicht an der Optimierung. :(

von Martin M. (mama)


Lesenswert?

Hier wird einfach der Speicherwert des Floats angezeigt.
Ggf. kann man dies im Debugger umstellen.

Gibt man bei folgendem Link z.B. 5.3 ein, kommen genau die oben 
angegebenen 0x40a9999a == 1084856730 raus:
http://www.h-schmidt.net/FloatConverter/IEEE754.html

von Hans Peter (Gast)


Lesenswert?

WOW!
warum wird denn hier auf einmal der speicherwert angezeigt?
das heißt, es ist nur ein anzeigefehler, im Hintergrund wird richtig 
gerechnet?

Wie kann ich denn den tatsächlichen wert anzeigen lassen?

Ihr seid wirklich spitze!

von Hans Peter (Gast)


Lesenswert?

Hat jemand damit schon Erfahrung gemacht?
Wie kann ich denn den aktuellen Wert rausfinden?

von Hans Peter (Gast)


Lesenswert?

Hmmm, bin ich wirklich der einzige, der damit Probleme hat?

von Hans (Gast)


Lesenswert?

Vielleicht handelt es sich um dieses Problem:
http://asf.atmel.com/bugzilla/show_bug.cgi?id=3429

Zur Not könntest Du den Wert testweise mit sprintf in einen String 
speichern und Dir den im Debugger anschauen.

von Werner M. (Gast)


Lesenswert?

Hans Peter schrieb:
> Wie kann ich denn den tatsächlichen wert anzeigen lassen?

Float sind Bits, die genauso im Speicher liegen, wie die anderen 
Variablen auch. Wie du die Bits interpretierst und anzeigen läßt, bleibt 
dir überlassen. Int kannst du auch als Dezimal, Hex, Binär oder sonstwie 
anzeigen lassen.

von DirkB (Gast)


Lesenswert?

Hans Peter schrieb:
> Hmmm, bin ich wirklich der einzige, der damit Probleme hat?

Nein. Das Problem tauchte hier schon öfter auf.

von Hans Peter (Gast)


Lesenswert?

DirkB schrieb:
> Nein. Das Problem tauchte hier schon öfter auf.

Und warum finde ich dann nichts diesbezüglich bzw. kann jemand posten, 
woran das wirklich liegt?

Ist das Problem jenes, das Hans gepostet hat, das es also ein Bug im AVR 
Studio ist?

von Hans Peter (Gast)


Lesenswert?

Keiner eine weitere Idee bzw. Erfahrung damit?

von Hans Peter (Gast)


Lesenswert?

HAllo,

ich habe nun schon von einigen gehört, dass man das " Use GDB" Flag 
setzen kann, dann funktioniert es wieder. Aber bei mir nicht, wenn ich 
das aktiviere, bekomm ich beim Versuch zu debuggen andauernd 
Fehlermeldungen, der Debugger wird nicht mehr erkannt und das Atmel 
Studio stürzt dauernd ab.

Schön langsam reichts mir mit ATmel Studio, andauernd bringen sie neue 
Versionen raus, die mehr Bugs besitzen wie die alten. Beim 6.1. hat das 
nämlich einwandfrei funktioniert. Ich habe das schon öfters erlebt, dass 
in einer neuen Version auf einmal manche Dinge nicht mehr funktionieren, 
die in der alten Version einwandfrei funktioniert haben.

von Joachim B. (jar)


Lesenswert?

Hans Peter schrieb:
> Schön langsam reichts mir mit ATmel Studio, andauernd bringen sie neue
> Versionen raus, die mehr Bugs besitzen wie die alten.

ich weiss warum ich immer noch mit 4.18 arbeite

wozu updaten wenns geht ?

von m.n. (Gast)


Lesenswert?

Joachim B. schrieb:
> ich weiss warum ich immer noch mit 4.18 arbeite
>
> wozu updaten wenns geht ?

Aber die 4.19 könntest Du Dir doch schon gönnen!

von Joachim B. (jar)


Lesenswert?

m.n. schrieb:
> Joachim B. schrieb:
>> ich weiss warum ich immer noch mit 4.18 arbeite
>>
>> wozu updaten wenns geht ?
>
> Aber die 4.19 könntest Du Dir doch schon gönnen!

hatte ich versucht, aber da gab es auch ein Problem, -> verdrängt ....

wieder 4.18 installiert, geht !

ich progge  gleiche Projekte an 5 Rechnern und da ist es optimal wenn es 
an allen gleich läuft

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@m.n. (Gast)

>> ich weiss warum ich immer noch mit 4.18 arbeite
>> wozu updaten wenns geht ?

EBEN! Mach ich auch so!

>Aber die 4.19 könntest Du Dir doch schon gönnen!

Nö, die hat Probleme mit dem AVR GCC da geht was nicht so richtig. Darum 
"nur" 4.18. Läuft wie geschmiert.

von m.n. (Gast)


Lesenswert?

Joachim B. schrieb:
> hatte ich versucht, aber da gab es auch ein Problem, -> verdrängt ....
>
> wieder 4.18 installiert, geht !

Interessant; werde ich mir für den Fall merken, dass es mal haken 
sollte.

Für AVR32 aber wohl keine Lösung, da diese noch nicht unterstützt werden 
(oder ich es mal wieder nicht raffe und auch nicht brauche).
Auch die ATtiny441/841 sind dort nicht bekannt; das stört mich am 
meisten.

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.