mikrocontroller.net

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


Autor: Gerry L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lutz,

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

Gruß
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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.

...

Autor: Branko Golubovic (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
 #define ADC_VREF_TYPE 0x00  //External VREF
 //#define ADC_VREF_TYPE 0x40  //AVCC mit externem Kondesator an VREF PIN
 //#define ADC_VREF_TYPE 0xc0  //Interne 2,56V Spanung referentz

//#define ADC_PRESCALER  0x01  //Prescaler 2
//#define ADC_PRESCALER  0x02  //Prescaler 4
//#define ADC_PRESCALER  0x03  //Prescaler 8
//#define ADC_PRESCALER  0x04  //Prescaler 16
//#define ADC_PRESCALER  0x05  //Prescaler 32
//#define ADC_PRESCALER  0x06  //Prescaler 64 
 #define ADC_PRESCALER  0x07  //Prescaler 128
 
// Inhalt von ADCW Register bei 0°C, Aus KTY81.xls lesen
#define  NULL_KTY81  300

unsigned char LCD_Buffer[21]

//############################################################################
// Routine Initialisiert ADC
void adc_init(void)
//############################################################################
{
// ADC initialization
// ADC Clock frequency:SYSCLK/ADC_PRESCALER
// ADC Voltage Reference: ADC_VREF_TYPE

ADMUX=ADC_VREF_TYPE;

ADCSRA=(1<<ADEN)|ADC_PRESCALER;

}

//########################################################################
// Routine liest Ein Analog eingang
//########################################################################
signed int read_adc(unsigned char adcinput) 
{
// ADC Inpit und Aref-Quelle auswählen
ADMUX=adcinput | ADC_VREF_TYPE;

// Starte AD Konversion
ADCSRA|=1<<ADSC;

while ((ADCSRA & (1<<ADIF))==0);// Warte  bis AD Konversion fertig ist
ADCSRA|=(1<<ADIF);  // Lösche ADC Interrupt Flag

return ADCW;
}


//########################################################################
// Liest Temperatur von  KTY81 Sensor
// Rückgabewert ist Temperatur(°C) * 2
// z.B. 0=0°C; 50=25°C; 37=16,5°C; -8=-4°C usw.
//########################################################################
signed int read_KTY81(unsigned char ADC_input)
{
signed int Temperatur;

  Temperatur=read_adc(ADC_input);
  Temperatur-=NULL_KTY81;
  
return Temperatur;

}

//########################################################################
// Zeigt Temperatur auf LCD; Messberech -20°C bis 100°C; Auflösung 0,5°C
//########################################################################
void temperatur2LCD(unsigned char ADC_input)

{signed int Temperatur;
    Temperatur=read_KTY81(ADC_input);
    itoa(Temperatur/2,Buffer,10); // Zeigt Ganze°C mit Vorzeichen         
    lcd_puts(LCD_Buffer);
    lcd_puts(".");  // Zeigt Dezimalpunkt
    itoa(abs(5*(Temperatur%2)),Buffer,10); //Zeigt Nachkommastelle ohne Vorzeichen
    lcd_puts(LCD_Buffer); 
    lcd_puts("\xde\x43  ");// Zeigt "°C"
}


Branko

Autor: Gerry L. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.