Forum: Mikrocontroller und Digitale Elektronik @ Lutz zu ADC Werte berechnung


von Gerry L. (Gast)


Lesenswert?

Hallo Lutz,

ich bezieh mich mal auf den Thread zum ATtiny44 on Chip Temp
da schreibst Du
1
Oder Du nimmst einen einfachen Vorwiderstand, der etwa dem
2
Sensorwiderstand im Temperaturmeßbereich entspricht und mißt ihn genau
3
(KTY 2000 Ohm bei 20 Grad, Vorwiderstand auch 2000 Ohm =>
4
Spannungsteiler 1:1). Nun schaltest Du einfach einen Pin als Ausgang
5
(ergibt bei Dir etwa 3 V) und legst diesen Pin auf AREF. Über dem Sensor
6
mißt Du jetzt etwas mit dem ADC (512 oder was auch immer). Bedeutet, daß
7
über dem Vorwiderstand der Rest (1023-Meßwert) anliegt. Und nun: Du
8
kennst den Vorwiderstand und wie sich die beiden Spannungen zueinander
9
verhalten. Mit U_Vor/U_Sensor=R_Vor/R_Sensor und minimalem
10
mathematischem Geschick kannst Du jetzt den Widerstand des Sensors
11
ausrechnen lassen und mit der Formel des Datenblattes weiter die
12
Temperatur ausrechnen. Das ist Spannungsänderungsunabhängig, spart Dir
13
kalte Finger und das Eis kommt in den Drink ...
14
15
Gruß
16
Lutz

kannst Du mir das bitte etwas genauer erklären.

Alle Formeln die ich bisher gesehen habe brauchen zum rechnen die 
Refspannung. Egal ob diese gleich der VCC Spannung ist.
Nehmen wir mal an die Spannung ist 3V und ich erhalte ein ADC von 512
bei einen Teiler von 1:1 (KTY81-110 25°=1000 Ohm : 1000 Ohm).
Wenn ich nun eine der gängigen Formeln nehme erhalte ich einen recht 
zuverlässigen Wert. Aber sobald die Spannung sinkt, sinkt auch der ADC 
Wert und mein Ergebniss das ja als Berechnungsgrundlage 3V hat wird 
verfälscht.

Kannst Du mir hierfür ein Beispiel geben:

"U_Vor/U_Sensor=R_Vor/R_Sensor und minimalem mathematischem Geschick
kannst Du jetzt den Widerstand des Sensors ausrechnen lassen"

Was ist "U_Vor/U_Sensor" ?

Lieben Dank

Gerry

von Hannes L. (hannes)


Lesenswert?

Wenn die Versorgungsspannung, die auch als Referenzspannung genutzt wird 
und den Spannungsteiler (Vorwiderstand-Sensor) versorgt, sinkt, dann 
sinkt auch die am Spannungsteiler abgegriffene ADC-Spannung.

Sieh's mal so: Der Spannungsteiler (Vorwiderstand-Sensor) liefert eine 
(temperaturabhängige) Spannung, die man relativ zur Gesamtspannung in 
Prozent (zur Gesamtspannung) betrachten kann. Dabei ist die Höhe der 
Gesamtspannung (innerhalb des Bereiches, wo der fließende Strom den 
Sensor nicht erwärmt) nicht relevant, solange die Gesamtspannung auch 
als Referenz für den ADC genommen wird. Spannungsschwankungen 
kompensieren sich also.

Nutzt Du die interne Referenz, dann muss die Versorgungsspannung des 
Spannungsteilers (Vorwiderstand-Sensor) schon recht konstant sein. Oder 
der Sensor wird gleich an einer Konstantstromquelle betrieben.

...

von Branko Golubovic (Gast)


Angehängte Dateien:

Lesenswert?

Also meine Meinung nah ist die KTY einfachste und billigste 
Temperatursensor für Temperaturerfassung mittel einen µC mit ADC.
Entwicklung solche Sensoren stammt aus ende 70-Jahren.
Ich erinnere mich noch auf ELV Temperaturmessmoduln auf Basis von 
ICL7106/7 als Digital-Millivoltmeter.
KTY ist so konzipiert dass in Kombination mit einem 2k7 oder 3k 
Widerstand in weiteren Temperaturbereich von 0 bis 100°C einen  nahezu 
lineares Temperatur-Spannung verlauf hat.
Durch einstellbare Referenzspannung ist möglich  auf einem 
Millivoltmeter  anzeige in °C zu Bekommen.
Das eine Linearisierung von KTY mit 2k7 Widerstand nicht notwendig ist, 
ist leider nicht bekannt oder mit dem Zeit verloren gegangen ist, und 
sehr oft lese ich als Antwort auf die Frage
„welcher Temperatursensor?“ oft KTY, aber mit Konstantstromquelle und 
Linearisierung in µC.
Dass ist vollkommen falsche Einsatz.
KTY mit 2k7 Widerstand ist linear! Punkt.
Wenn noch Möglichkeit gibt Referenzspannug mit einem Spindelpoti fein 
einzustellen  ist möglich z.B.
beim AVR einen Auflösung von 0,5°C zu bekommen(siehe Anhang) d.h. 1LSB 
entspricht 0,5°C.
Dadurch ist keine Skalierung notwendig. Wichtig ist nur ADC-Wert  für 
0°C zu Bestimmen.
In dem Fall konnte Funktion für Temperaturmessung etwas so aussehen:
1
 #define ADC_VREF_TYPE 0x00  //External VREF
2
 //#define ADC_VREF_TYPE 0x40  //AVCC mit externem Kondesator an VREF PIN
3
 //#define ADC_VREF_TYPE 0xc0  //Interne 2,56V Spanung referentz
4
5
//#define ADC_PRESCALER  0x01  //Prescaler 2
6
//#define ADC_PRESCALER  0x02  //Prescaler 4
7
//#define ADC_PRESCALER  0x03  //Prescaler 8
8
//#define ADC_PRESCALER  0x04  //Prescaler 16
9
//#define ADC_PRESCALER  0x05  //Prescaler 32
10
//#define ADC_PRESCALER  0x06  //Prescaler 64 
11
 #define ADC_PRESCALER  0x07  //Prescaler 128
12
 
13
// Inhalt von ADCW Register bei 0°C, Aus KTY81.xls lesen
14
#define  NULL_KTY81  300
15
16
unsigned char LCD_Buffer[21]
17
18
//############################################################################
19
// Routine Initialisiert ADC
20
void adc_init(void)
21
//############################################################################
22
{
23
// ADC initialization
24
// ADC Clock frequency:SYSCLK/ADC_PRESCALER
25
// ADC Voltage Reference: ADC_VREF_TYPE
26
27
ADMUX=ADC_VREF_TYPE;
28
29
ADCSRA=(1<<ADEN)|ADC_PRESCALER;
30
31
}
32
33
//########################################################################
34
// Routine liest Ein Analog eingang
35
//########################################################################
36
signed int read_adc(unsigned char adcinput) 
37
{
38
// ADC Inpit und Aref-Quelle auswählen
39
ADMUX=adcinput | ADC_VREF_TYPE;
40
41
// Starte AD Konversion
42
ADCSRA|=1<<ADSC;
43
44
while ((ADCSRA & (1<<ADIF))==0);// Warte  bis AD Konversion fertig ist
45
ADCSRA|=(1<<ADIF);  // Lösche ADC Interrupt Flag
46
47
return ADCW;
48
}
49
50
51
//########################################################################
52
// Liest Temperatur von  KTY81 Sensor
53
// Rückgabewert ist Temperatur(°C) * 2
54
// z.B. 0=0°C; 50=25°C; 37=16,5°C; -8=-4°C usw.
55
//########################################################################
56
signed int read_KTY81(unsigned char ADC_input)
57
{
58
signed int Temperatur;
59
60
  Temperatur=read_adc(ADC_input);
61
  Temperatur-=NULL_KTY81;
62
  
63
return Temperatur;
64
65
}
66
67
//########################################################################
68
// Zeigt Temperatur auf LCD; Messberech -20°C bis 100°C; Auflösung 0,5°C
69
//########################################################################
70
void temperatur2LCD(unsigned char ADC_input)
71
72
{signed int Temperatur;
73
    Temperatur=read_KTY81(ADC_input);
74
    itoa(Temperatur/2,Buffer,10); // Zeigt Ganze°C mit Vorzeichen         
75
    lcd_puts(LCD_Buffer);
76
    lcd_puts(".");  // Zeigt Dezimalpunkt
77
    itoa(abs(5*(Temperatur%2)),Buffer,10); //Zeigt Nachkommastelle ohne Vorzeichen
78
    lcd_puts(LCD_Buffer); 
79
    lcd_puts("\xde\x43  ");// Zeigt "°C"
80
}


Branko

von Gerry L. (Gast)


Angehängte Dateien:

Lesenswert?

Branko, Du hast schon recht mit dem was Du sagst. Das Problem 
ursprünglich war aber das weder die interne Ref noch eine Konstante 
Stromquelle benutzt werden sollen. Und der Gedanke die VCC über einen 
Portpin an ARef zu legen habe ich aufgegriffen. Ebenso sollte der 
Bereich -20 bis + 30 relativ linear bzw. korrekt berechnet werden 
können.

Ich habe mal eine Tabelle angehangen die ich mir extra angelegt habe um 
mal mit verschiedenen Spannungsteilern zu spielen.

Hier ist schön erkennbar das bei der Berechnung eines Spannungsteilers 
1:1 es einfacher ist den AD durch 2 zu teilen und einen Offset zu 
subtrahieren.

Aber der optimalste Wert ist Tatsache 2k7. Hier kann sehr schön die 
Berechnungsgrundlage von 
http://www.sprut.de/electronic/temeratur/temp.htm übernommen werden. Nur 
wo steht das?

Ich werde den 1:1 Teiler vergessen und mir jetzt einen 2k7 besorgen und 
das Thema abschliessen.

von Lutz (Gast)


Lesenswert?

Hallo Gerry,

bin gerade bei einer Suche über diesen seinerzeit leider verpaßten 
Thread gestolpert und wollte die Leiche noch mal kurz vorkramen und 
meinen Ansatz erklären, da leider nicht alles rüberkam bzw. Du Dein Ziel 
nicht erreicht hast, da die Weiterverarbeitung der gemessenen Spannung 
nicht stimmte: Die Spannung kannst Du so nicht direkt zur 
Temperaturbestimmung verwenden.

ARef/PA0---+
           |
           |
PA1 -------+
           |
           1K
           |
PA2--------+
           |
          KTY
           |
           -
          GND

Die Schaltung meinte ich (aus altem Thread 
Beitrag "On-Chip Temperatur ATtiny").
Du hast hier einen Spannungsteiler. Die Spannung ARef/PA0 teilt sich 
über den beiden Widerständen 1K und KTY im Verhältnis ihrer 
Widerstandswerte zueinander auf. Dieses Verhältnis ist unabhängig von 
der Höhe der Spannung ARef/PA0, die sich ruhig ändern darf (aber 
natürlich nicht während einer Messung; da muß sie stabil sein!!!). 
Hatte Hannes schon erklärt.

Sagen wir Vorwiderstand 1K hat 1kOhm (wir vereinbaren, daß er außerhalb 
der Meßumgebung liegt und er daher keine Widerstandsänderung auf Grund 
der Temperaturänderung erfährt. Falls nicht, ist die Änderung auch nicht 
"sehr stark", alles eine Frage der gewünschten Gesamtgenauigkeit). Der 
temperaturabhängige Widerstand KTY ist unbekannt und wird folgendermaßen 
ermittelt: Du mißt jetzt mit dem ADC an PA2 über KTY z.B. den Wert 
ADCW=682. Da der ADC-Wert 1023 der Spannung ARef/PA0 entspricht (na 
klar, da über das Komparatorprinzip gemessen wird, entspricht die 
Referenzspannung dem maximal möglichen Meßwert, beim AVR also 1023), muß 
also 1023-682 = 341 über dem Widerstand 1k anliegen. Also sozusagen der 
Rest, der nicht über dem KTY abfällt. Da Du den Wert des Widerstandes 1k 
ja vorher z.B. mit einem Multimeter (klar, hat das auch einen Meßfehler) 
mit genau 1kOhm gemessen hast, kannst Du nun rechnen: KTY/682 = 1 
kOhm/341 (allgemein formuliert U1/U2=R1/R2; die Spannungen verhalten 
sich zueinander wie die Widerstände es tun). Umgestellt ("minimales 
mathematisches Geschick") ergibt das KTY = 1 kOhm * 682 / 341. Also hat 
KTY nun einen Widerstand von 2 kOhm. Jetzt schaust Du im Datenblatt des 
KTY, bei welcher Temperatur er einen Widerstand von 2 kOhm hat. Bei 
diesem Beispiel wären das ungefähr 127 Grad Celsius.

Beim KTY81-110 habe ich leider keine Formel wie z.B. beim KTY 10-6 von 
Infineon finden können (Datenblatt z.B. bei Reichelt). Damit könntest Du 
den AVR dann die Temperatur ausrechnen lassen. Du kannst natürlich auch 
selbst eine Formel anhand der Stützstellen aus dem Datenblatt Deines 
Sensors erstellen (auch ganz speziell nur für Deinen Meßbereich), 
Stichwort wäre z.B. Newtonsches Interpolationspolynom. Generell dabei 
natürlich die von Jörg erklärte Typdeklarationen/definitionen in C 
beachten (Integerdivision, float, cast etc.).

Ich hoffe, diese verspätete Antwort konnte Dir etwas weiterhelfen. Wie 
hast Du es letztendlich gelöst?

Gruß
Lutz

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.