Forum: Mikrocontroller und Digitale Elektronik Butterfly Natürlicher Logarithmus?


von bluewhile (Gast)


Lesenswert?

Hallo,

ich bin erneut am verzweifeln, nach dem ich es nun endlich geschaft habe 
den NTC des Butterflys auszulesen fehlt nur noch der letzte Schritt: das 
Umwandeln des ADC-Wertes in Celsius. Dazu habe ich in der Manual (S.22) 
eine Formel gefunden:
1
volatile double ADC_Out(uint16_t adc)
2
{
3
    return ((4250/(log(adc/(1024-adc))+(4250/298)))-273);
4
}

Wenn ich nun
1
#include <math.h>
einbinde kommt folgender Fehler:

gcc plug-in: Error: Object file not found on expected location 
C:\Users\Paul\Desktop\AVRBUTTERFLY\default\main.elf


Was mache ich falsch?

von Serieller (Gast)


Lesenswert?

Möglicherweise hast du die Mathelibrary nicht dazu gelinkt und die 
Funktion log() ist dem Linker unbekannt und es wurde deshalb kein 
main.elf erzeugt.

Da sollte es aber eine entsprechende Fehlermeldung des Linkers gegeben 
haben. Hast du bereits alle Fenster/Tabs in der IDE (AVR-Studio?) darauf 
abgesucht?

von Serieller (Gast)


Lesenswert?


von bluewhile (Gast)


Lesenswert?

Man muss dazu sagen, dass ich normalerweise Java programmiere (und darin 
auch mein Abitur mache) und vollkommen neu in C bin. Habe nun wie in dem 
Link beschrieben die libm Bibliothek eingebunden und werde das mal 
testen....

von bluewhile (Gast)


Lesenswert?

statt
1
utoa()
 verwende ich nun
1
dtostre( ADC_Out(ADC_Read(0)),buffer,10)
, aber ich habe wohl noch irgendwo einen Fehler in der formel amsonsten 
scheint es zu funktionieren - DANKE!

von DerAlbi (Gast)


Lesenswert?

log(adc/(1024-adc))

adc ist eine Ganzahl. 1024 ist eine Ganzahl. Die ganze Berechung ist 
also ganzzahlig. Erst das Ergenis wird zu float konvertiert. Da findet 
sich ordentlich numerisches fehlerpotential.

Bleib lieber bei Java, spielkind ;-) Nee scherz :-D
caste alles du float und gut ist.

-->  log( ((float)adc) / (1024.0f-adc) )

von bluewhile (Gast)


Lesenswert?

jaja ;D hab es nun endlich zum laufen gebracht:
1
volatile float ADC_Out(uint16_t adc)
2
{
3
    return (float)(4250.0/(log((-1.0*adc)/(adc-1024.0))+(4250.0/298.0))-273.0);
4
  
5
}

PAAAAAAAAAAARTYYYYYYY :D

von eProfi (Gast)


Lesenswert?

Danke für das Posten der Lösung.

Von den 16k des atMega169 dürfte jetzt nicht mehr allzuviel frei sein.
Dashalb wird in der Originalversion eine Tabelle verwendet.

Alternative:
Beitrag "ADC-Wert z.B. in Spannung umrechnen und dezimal ausgeben mittels Tabellen, auch Linearisieren"
Beitrag "Temperaturmessung mit NTC"



(float) ist überflüssig,  1.0  ebenso

return 4250.0/(log(-adc/(adc-1024.0))+(4250.0/298.0))-273.0;
gleichbedeutend mit
return 4250.0/(log(adc/(1024.0-adc))+(4250.0/298.0))-273.0;
oder noch kürzer:
return 4250/(log(adc/(1024.0-adc))+(4250.0/298))-273;

Probe:
ADC    temp
  0  -273.000 (undefiniert, da +unendlich)
 64    94.848
128    72.084
192    59.150
256    49.871
320    42.439
384    36.070
448    30.345
512    25.000
576    19.840
640    14.695
704     9.388
768     3.686
832    -2.783
896   -10.778
960   -22.555
999   -36.266

von Purzel H. (hacky)


Lesenswert?

Dabei ist der Log() gar nicht so schwierig :
http://www.ibrtses.com/embedded/logarithms.html
aber wenn die Leute die ganze math Library dabei haben wollen...

von eProfi (Gast)


Angehängte Dateien:

Lesenswert?

Wer wissen will, wie die Tabelle der Butterfly-Software berechnet wird, 
im Anhang das Programm dazu.

Zur Auswertung bietet sich eine binäre Suche an, da die Tabelle stetig 
fallend ist.
Ich würde auch nicht auf positive und negative Temperaturen 
unterscheiden, sondern alles in eine Tabelle packen (wie bei 
Fahrenheit), dann bei negativen Werten ein '-' drucken und den Wert 
invertieren:
  if(t<0){printf("-");t=-t;}

Außerdem am Schluß ein Ansatz, wie man die Genauigkeit mittels 
Interpolation verbessern kann.
Außerdem wird in der BF-Software der ADC 8 mal addiert, um genauer zu 
werden, danach wird aber durch 8 dividiert - das hätte ich weggelassen.

Hier die Original-Tabellen:
1
__flash int TEMP_Celcius_pos[] =    // Positive Celcius temperatures (ADC-value)
2
        {                           // from 0 to 60 degrees
3
            806,796,786,775,765,754,743,732,720,709,697,685,673,661,649,
4
            636,624,611,599,586,574,562,549,537,524,512,500,488,476,464,
5
            452,440,429,418,406,396,385,374,364,354,344,334,324,315,306,
6
            297,288,279,271,263,255,247,240,233,225,219,212,205,199,193,
7
            187,
8
        };
9
10
__flash int TEMP_Celcius_neg[] =    // Negative Celcius temperatures (ADC-value)
11
        {                           // from -1 to -15 degrees
12
            815,825,834,843,851,860,868,876,883,891,898,904,911,917,923,
13
        };
14
     
15
__flash int TEMP_Farenheit_pos[] =  // Positive Farenheit temperatures (ADC-value)
16
        {                           // from 0 to 140 degrees
17
        938, 935, 932, 929, 926, 923, 920, 916, 913, 909, 906, 902, 898, 
18
        894, 891, 887, 882, 878, 874, 870, 865, 861, 856, 851, 847, 842, 
19
        837, 832, 827, 822, 816, 811, 806, 800, 795, 789, 783, 778, 772, 
20
        766, 760, 754, 748, 742, 735, 729, 723, 716, 710, 703, 697, 690, 
21
        684, 677, 670, 663, 657, 650, 643, 636, 629, 622, 616, 609, 602, 
22
        595, 588, 581, 574, 567, 560, 553, 546, 539, 533, 526, 519, 512, 
23
        505, 498, 492, 485, 478, 472, 465, 459, 452, 446, 439, 433, 426, 
24
        420, 414, 408, 402, 396, 390, 384, 378, 372, 366, 360, 355, 349, 
25
        344, 338, 333, 327, 322, 317, 312, 307, 302, 297, 292, 287, 282, 
26
        277, 273, 268, 264, 259, 255, 251, 246, 242, 238, 234, 230, 226, 
27
        222, 219, 215, 211, 207, 204, 200, 197, 194, 190, 187, 
28
        };

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.