Forum: Mikrocontroller und Digitale Elektronik Thermometer mit NTC: Berechnung der Temperatur funktioniert nicht


von Sebastian D. (--sebi--) Benutzerseite


Lesenswert?

Ich möchte ein Thermometer mit einem NTC bauen.
Aber die Berechnung der Temperatur funktioniert nicht. Ich möchte den 
ADC Wert ermitteln(klappt), Die Temperatur daraus ausrechnen (klappt 
nicht), und die Temperatur per RS232 an meinen Laptop schicken(klappt).
Bei meinem Laptop kommt immer nur "25.01" oder "-273,15" an.
Am ADC ist der NTC und ein 10k Pullup angeschlossen.
Das ist der Code:
1
#define F_CPU 1000000
2
3
#include <stdio.h>
4
5
//#include <avr/interrupt.h>
6
7
8
//#include "General.h"
9
10
#include "RS232.c"
11
12
#include <util/delay.h>
13
14
#include <math.h>
15
16
//#include "RS232.h"
17
18
//#include "Delay.h"
19
20
uint16_t ADC_Read(uint8_t channel)
21
22
{
23
24
    ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
25
26
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
27
28
  while (ADCSRA & (1<<ADSC) );    // auf Abschluss der Konvertierung warten
29
30
    return ADCW;                    // ADC auslesen und zurückgeben
31
32
}
33
34
int main (void)
35
36
{
37
38
39
40
    RS232_Init ();
41
42
    ADMUX = (1<<REFS0);      // VCC als Referenz
43
44
      ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
45
46
      ADCSRA |= (1<<ADEN);                  // ADC aktivieren
47
48
    printf ("Hello world...\n");
49
50
    char itoabuf[20];
51
52
    char dtostrfbuf[20];
53
54
    int raw;
55
56
    float temp;
57
58
    while (1)
59
60
    {
61
62
        _delay_ms(100);    
63
64
        _delay_ms(100);
65
66
        _delay_ms(100);
67
68
        _delay_ms(100);
69
70
        _delay_ms(100);
71
72
        _delay_ms(100);
73
74
        _delay_ms(100);
75
76
        _delay_ms(100);
77
78
        _delay_ms(100);
79
80
        _delay_ms(100);
81
82
        raw=ADC_Read(0);
83
84
        temp=(1282088/(4300+ln(raw/(1023-raw))*298.16))-273.15;
85
 //Hier wird die Temperatur berechnet
86
        dtostrf(temp,3,1,dtostrfbuf);
87
 //float zu char[]
88
        printf(dtostrfbuf);
89
90
        printf("\n");
91
92
        itoa(raw,itoabuf,10);
93
94
        printf(itoabuf);
95
96
        printf("\n");
97
98
    }
99
100
}

von eProfi (Gast)


Lesenswert?

Muss man, damit ln funktioniert, nicht noch etwas anderes als math.h 
einbinden / einstellen ?

von Jemand (Gast)


Lesenswert?

Ist "ln" nicht der Logarithmus und über welchen Temperaturbereich soll 
die Messung sein ?
Welche Werte nimmt "raw" an, also bevor es in die Temperatur umgerechnet 
wird.
Einfacher als diese Floatberechnung wäre erstmal eine Tabelle, die für 
einen bestimmten ADC-Wert den entsprechenden Temperaturwert hat.

von Sebastian D. (--sebi--) Benutzerseite


Lesenswert?

raw nimmt den richtigen Wert an. z.B. 528. Wenn ich darauf die 
Temperatur mit dem Taschenrechner berechne, komme ich auch auf die 
richtige Temperatur.

von Stefan W. (wswbln)


Lesenswert?

Bist Du sicher, dass die Lib eine funktionierende ln()-Funktion hat?

Ich habe das damals so gemacht und es funktionietrte:
1
#define V_ref  5.0      // 5V
2
3
// NTC-thermistor defines
4
#define Beta  3977.000    // the Beta-value for the NTC sensor
5
#define R_th  10000.00    // the thermistor resistance @ 25 degree Celsius
6
#define T_amb  298.0000    // the temperature in Kelvin for 25 degree Celsius
7
#define T_zero  273.0000    // the temperature in Kelvin for 0 degree Celsius
8
9
.
10
.
11
.
12
13
    ADCSRA |= (1<<ADSC);        //Start conversion
14
  while (ADCSRA & (1<<ADSC)) {}    //wait until converstion completed
15
    
16
    V_ADC = (ADC * V_ref)/1024;        // calculate the voltage over the NTC
17
  Temperature = (Beta / ((log(V_ADC/(V_ref-V_ADC))/log(exp(1))) + (Beta/T_amb))) - T_zero;

von MaWin (Gast)


Lesenswert?

> temp=(1282088/(4300+ln(raw/(1023-raw))*298.16))-273.15;


Schreib 1023.0 und überlege mal wirklich ob floating point so schlau auf 
einem uC ist.

von Pete K. (pete77)


Lesenswert?

Hast Du auch dem Linker gesagt, dass er die Floating-Point Bibliothek 
mit einbinden soll?



Sebastian Deppisch schrieb:
> #include "RS232.c"

Btw., C-Programme werden nicht included

von Peter (Gast)


Lesenswert?

Moin,

ich kenn mich nich so genau mit dem AVR aus, aber die math.h lib hat 
meines Wissens keine "ln" Funktion, sondern nur eine "log" bzw. "log10" 
Funktion. Das entspricht auch so in etwa dem Original der Formel aus der 
Lego-NXT Sammlung. Also mal ausprobieren:
=(1282088/(4300+LOG(RAW/(1023-RAW))*298,16))-273,15

ABER, hast Du auch den gleichen NTC-Widerstand ??

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> Moin,
>
> ich kenn mich nich so genau mit dem AVR aus, aber die math.h lib hat
> meines Wissens keine "ln" Funktion, sondern nur eine "log" bzw. "log10"

log IST der ln


1
  raw / (1023-raw)

einfach mal mit Ganzzahlarithmetik ausprobieren, was da rauskommt.
Oder um es so zu sagen: Wenn er auf dem Taschenrechner diesen 
Teilausdruck hier ausrechnet, dann nach der Division alle Kommastellen 
wegwerfen. Dann sieht sein Ergebnis auf dem Taschenrechner nämlich auch 
plötzlich ganz anders aus. Zb wird alles für raw kleiner 512 zu einer 
schnöden 0 (was für den ln dann wieder gar nicht gut ist)

von Peter (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> log IST der ln

Danke für den Hinweis. Der OP hat aber "ln" in seiner Berechnung. Das 
sollte doch eher schief gehen, oder ?
Der Hinweis mit der Ganzzahlarithmetik ist deshalb interessant, weil 
jetzt auch klar wird, warum "MaWin" vorgeschlagen hat, mit 1023.0 zu 
rechnen. Dadurch wird der gesamte Ausdruck eine Floatberechnung. Oder 
sehe ich das falsch ?

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> Karl heinz Buchegger schrieb:
>> log IST der ln
>
> Danke für den Hinweis. Der OP hat aber "ln" in seiner Berechnung. Das
> sollte doch eher schief gehen, oder ?


Nochmal:
In Programmiersprachen ist die Funktion log der Logarithmus zur Basis e 
(vulgo der 'natürliche Logarithmus', vulgo ln). Der Logarithmus zur 
Basis 10 schreibt sich meistens log10.


> jetzt auch klar wird, warum "MaWin" vorgeschlagen hat, mit 1023.0 zu
> rechnen. Dadurch wird der gesamte Ausdruck eine Floatberechnung. Oder
> sehe ich das falsch ?

Das siehst du richtig.

von Sebastian D. (--sebi--) Benutzerseite


Lesenswert?

Danke. Ich werde es mal mit X.0 probieren

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Deppisch schrieb:
> Danke. Ich werde es mal mit X.0 probieren

Und das hier lesen

http://www.mikrocontroller.net/articles/FAQ#Datentypen_in_Operationen

und darüber nachdenken, was da alles daraus folgt.

von Sebastian D. (--sebi--) Benutzerseite


Lesenswert?

Also es funktioniert jetzt.
Vielen Dank.
Und µC Programmieren klappt bei mir jetzt auch unter Linux.
@Peter
Woher hast du die Formel?
Die ist doch von meiner Homepage, und die Formel hab ich so erstellt.
http://mylegopage.my.funpic.de/index.php?page=selbstbau&sub=ntc-nxt
Und da es meine ist, hab ich sogar nicht nur den gleiche, sondern auch 
den selben NTC ;)

von Reinhard Kern (Gast)


Lesenswert?

Sebastian Deppisch schrieb:
> Woher hast du die Formel?
> Die ist doch von meiner Homepage, und die Formel hab ich so erstellt.

Was immer du damit sagen willst - es gibt eine Formel für das Verhalten 
eines NTC, die steht in Wikipedia und in jedem einschlägigen Datenblatt. 
Die muss man für die Anzeige nach T auflösen, und wie das halt in der 
Mathematik so ist, kommt dabei IMMER das Gleiche heraus. U.a. deswegen 
gibt es auch keine Patente auf mathematische Formeln, jedenfalls bisher 
nicht.

Gruss Reinhard

von Sebastian D. (--sebi--) Benutzerseite


Lesenswert?

Das ist mir schon klar, aber 
"=(1282088/(4300+LOG(RAW/(1023-RAW))*298,16))-273,15"(so wie Peter es 
geschrieben hat) Habe ich so auf meiner Homepage stehen.

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.