This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| de:examples:sensor:thermistor [2011/10/11 17:00] – wittkoepper | de:examples:sensor:thermistor [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Thermistor ====== | ||
| + | |||
| + | // | ||
| + | |||
| + | ===== Theorie ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Ein Thermistor ist temperaturabhängiger Widerstand. Es gibt Thermistoren mit positiven und mit negativen Temperaturkoeffizienten. Der Widerstand von Thermistoren mit positiven Koeffizienten nimmt mit steigender Temperatur zu, bei Thermistoren mit negativen Koeffizienten steigt er mit sinkender Temperatur. Die dazugehörigen Abkürzungen sind PTC(// | ||
| + | |||
| + | Die Temperaturabhängigkeit des Widerstands verläuft nicht linear zu der Temperatur, was die Nutzung erschwert. Für genaue Temperaturmessungen bei größeren Temperaturschwankungen wird die exponentielle Steinhart-Hart Gleichung dritter Ordnung genutzt, da der Thermistorwiderstand nur innerhalb kleiner Temperaturbereiche linear ist. Für NTC Thermistoren gibts es folgende vereinfachte Steinhart-Hart-Gleichung mit dem Parameter B: | ||
| + | |||
| + | {{: | ||
| + | |||
| + | mit:\\ | ||
| + | * T< | ||
| + | * R< | ||
| + | * B - Parameter B. | ||
| + | |||
| + | Der Parameter B ist ein Koeffizient, | ||
| + | |||
| + | Normalerweise wird ein Spannungsteiler genutzt, um den Widerstand eines Thermistors zu messen. Dabei wird ein Widerstand durch einen Thermistor ausgetauscht wird und die Inputspannung ist konstant. Es wird die Outputspannung des Spannungsteilers gemessen, welche sich in Abhängigkeit der Widerstandsänderung des Thermistors verändert. Wenn Spannung anliegt, fließt Strom durch den Thermistor, wodurch sich dieser bedingt durch den Thermistorwiderstand aufheizt und damit den Widerstand verändert. Der durch das Aufheizen entstehende Fehler kann berechnet werden, jedoch ist es einfacher einen Thermistor zu nutzen, welcher einen hohen Widerstand hat und sich nicht so viel aufheizt. | ||
| + | |||
| + | Bei begrenzten Ressourcen und geringerem Anspruch auf Genauigkeit, | ||
| + | |||
| + | ===== Übung ===== | ||
| + | |||
| + | Das Sensormodul des HomeLab enthält einen NTC Thermistor mit nominellem Widerstand von 10 kΩ. Bei Temperaturen von 25 bis 50 °C ist der Parameter B des Widerstands 3900. | ||
| + | Ein Pin des Thermistors ist an die +5 V Betriebsspannung angeschlossen der andere an Kanal 2 (Pin PF2). Ein typischer 10 kΩ Widerstand ist auch am gleichen Pin des Mikrocontrollers und an die Masse angeschlossen. So entsteht zusammen mit dem Thermistor ein Spannungsteiler. Da hier ein NTC Thermistor genutzt wird, bei welchem der Widerstand sinkt wenn die Temperatur steigt, wird die Outputspannung des Spannungsteilers bei steigender Temperatur höher. | ||
| + | |||
| + | Während der Nutzung des AVR ist es nützlich, eine Tabelle mit den Temperaturwerten und den Werten des ADC zu verwenden, um die korrekte Temperatur zu finden. Es ist sinnvoll, für jede Gradzahl der gewünschten Temperaturstufe des Messbereichs den korrespondierenden ADC Wert aus der Tabelle herauszusuchen, | ||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // Tabelle zur Konvertierung von Temperaturwerten ind ADC Werte. | ||
| + | // Jedes Element des Arrays kennzeichnet ein Grad Celsius. | ||
| + | // Die Elemente beginnen bei -20 Grad und enden bei 100 Grad. | ||
| + | // Ein Array enthält 121 Elemente. | ||
| + | // | ||
| + | const signed short min_temp = -20; | ||
| + | const signed short max_temp = 100; | ||
| + | |||
| + | const unsigned short conversion_table[] = | ||
| + | { | ||
| + | 91, | ||
| + | 160, | ||
| + | 257, | ||
| + | 375, | ||
| + | 501, | ||
| + | 619, | ||
| + | 720, | ||
| + | 799, | ||
| + | 859, | ||
| + | 903, | ||
| + | 934, | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | Folgender Algorithmus kann genutzt werden um die mit den ADC Parametern korrespondierende Temperatur zu finden: | ||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // Konvertierung der ACD Werte in Grad Celsius: | ||
| + | // | ||
| + | signed short thermistor_calculate_celsius(unsigned short adc_value) | ||
| + | { | ||
| + | signed short celsius; | ||
| + | |||
| + | // Tabelle von hinten beginnend durchgehen: | ||
| + | for (celsius = max_temp - min_temp; celsius >= 0; celsius--) | ||
| + | { | ||
| + | // Ist der Wert aus der Tabelle gleich oder höher dem gemessenen | ||
| + | // Wert, ist die Temperatur mindestens so hoch wie die mit dem Element | ||
| + | // korrespondierende Temperatur. | ||
| + | if (adc_value >= conversion_table[celsius])) | ||
| + | { | ||
| + | // Da die Tabelle mit 0 beginnt, die Werte der Elemente jedoch mit -20, | ||
| + | // muss der Wert geshiftet werden. | ||
| + | return celsius + min_temp; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Wurde der Wert nicht gefunden, wird die minimale Temperaur ausgegeben. | ||
| + | return min_temp; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Der Algorithmus sucht den Bereich aus der Tabelle in dem der ACD Wert liegt und wählt die niedrigere Nummer dieses Bereiches. Die Ranknummer markiert die Gradzahl und durch das Addieren der anfänglichen Temperatur wird eine Genauigkeit von 1°C erreicht. | ||
| + | |||
| + | Umrechnungstabelle und Funktion sind schon in der HomeLab Bibliothek enthalten, sie müssen somit nicht extra für diese Aufgabe erstellt werden. In der Bibliothek heißt die Umrechnungsfunktion // | ||
| + | |||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // Beispielprogramm des Thermistors des Sensormoduls. | ||
| + | // Die Temperatur wird auf dem LCD angezeigt. | ||
| + | // | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // | ||
| + | // Hauptprogramm | ||
| + | // | ||
| + | int main(void) | ||
| + | { | ||
| + | unsigned short value; | ||
| + | signed short temperature; | ||
| + | char text[16]; | ||
| + | |||
| + | // Einrichten des LCD | ||
| + | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
| + | |||
| + | // Löschen des LCD | ||
| + | lcd_alpha_clear(); | ||
| + | |||
| + | // Name des Programms | ||
| + | lcd_alpha_write_string(" | ||
| + | |||
| + | // Einrichten des ADC | ||
| + | adc_init(ADC_REF_AVCC, | ||
| + | |||
| + | // Endlosschleife | ||
| + | while (true) | ||
| + | { | ||
| + | // Auslesen der 4-fach gerundeten Spannungswerte aus dem Thermistor | ||
| + | value = adc_get_average_value(2, | ||
| + | |||
| + | // Konvertieren der ADC Werte in Grad Celsius | ||
| + | temperature = thermistor_calculate_celsius(value); | ||
| + | |||
| + | // Konvertieren der Temperatur in Text. | ||
| + | // To display the degree sign, the octal variable is 337. | ||
| + | sprintf(text, | ||
| + | |||
| + | // Anzeige des Textes am Anfang der zweiten Zeile des LCDs. | ||
| + | lcd_alpha_goto_xy(0, | ||
| + | lcd_alpha_write_string(text); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Extra ===== | ||
| + | |||
| + | * {{: | ||