This is an old revision of the document!
Necessary knowledge: [HW] Sensors Module, [HW] lcd, [ELC] Voltage Divider, [AVR] Analog-to-digital Converter, [LIB] Analog to Digital Converter, [LIB] Alphanumeric LCD, [LIB] Sensors
Ein Thermistor ist ein Typ von Widerstand, dessen Widerstand sich mit der Temperatur verändert. Es gibt zwei Typen von Thermistoren: Welche mit positiven Temperaturkoeffizieten und welche mit negativen Temperaturkoeffizieten. Der Widerstand von Thermistoren mit positiven Koeffizienten steigt wenn die Temperatur steigt und bei den Negativen steigt der Widerstand wenn die Temperatur fällt. Die dazugehörigen Abkürzungen sind PTC(positive temperature coefficient) und NTC (negative temperature coefficient).
Die Abhängigkeit des Thermistorwiderstands ist nicht linear von der Temperatur abhängig und dies verkompliziert die Benutzung. Für genaue Temperaturmessungen wird die Steinhart-Hart exponentielle Gleichung dritter Ordnung genutzt, da der Thermistorwiderstand in kleinen Temperaturbereichen linear ist. Die folgende vereinfachte Steinhart-Hartgleichung mit B-Parameter existiert für NTC Thermistoren:
where:
Parameter B ist ein Koeffizient, welcher normalerweise im Datenblatt des Thermistors enthalten ist. Aber er ist nur konstant in bestimmten Temperaturbereichen, z.B. in Bereichen von 25-50 °C oder 25-85 °C. Wenn der gemessene Temperaturbereich größer ist, sollte das Datenblatt des Thermistors zu Rate gezogen werden.
Normalerweise wird ein Spannungsteiler benutzt um den Widerstand eines Thermistors zu messen, wobei ein Widerstand mit dem Thermistor ausgetauscht wird und die Inputspannung konstant ist. Die Outputspannung des Spannungsteilers wird gemessen, welche sich je nach Widerstand des Thermistors ändert. Wenn Spannung anliegt, fließt Strom durch den Thermistor, welcher sich durch den Widerstand aufheizt und der Widerstand verändert sich. Den Fehler durch das Aufheizen kann man ausrechnen, jedoch ist es einfacher einen Thermistor zu nutzen, welcher einen hohen Widerstand hat und sich nicht so viel aufheizt.
Mit begrenzten Ressourcen und weniger Anspruch auf Genauigkeit, werden vorberechnte Tabellen für die Temperaturen genutzt. Normalerweise haben die Tabellen Temperaturbereiche und die entsprechenden Werte an Widerstand, Spannung und ADC enthalten. Alle exponentiellen Berechnungen sind schon gemacht und der Nutzer muss nur noch die entsprechende Reihe finden und die Werte auslesen.
Das Sensormodul des HomeLab ist mit einem NTC Thermistor mit 10 kΩ nominellen Widerstand ausgestattet. Bei Temperaturen von 25-50 °C ist der Parameter B des Widerstands 3900. Ein Pin des Thermistors ist an die 5+V Betriebsspannungs angeschlossen der Andere an Kanal 2 (Pin PF2) Ein typischer 10 kΩ Widerstand ist auch am gleichen Pin des Microcontrollers und an die Erde angeschlossen, zusammen mit dem Thermistor entsteht so ein Spannungsteiler. Da wir mit ein NTC Thermistor arbeiten, wo der Widerstand sinkt wenn die Temperatur steigt, wird die Outputspannung bei steigender Temperatur höher.
Wenn man den AVR nutzt, ist es praktisch eine Tabelle zu mit den Werten der Temperaturen und des ADC zu nutzen um die korrekte Temperatur zu finden. Es ist klug für jeden °C Temperatur des Messbereiches den entsprechenden Wert des ADC raus zu suchen, da eine Tabelle zu groß auf Grund der 10 Bit ADC Werte wird. Es wird empfohlen ein Tabellenkalkulationsprogramm (MS Excel, Openoffice Calc, etc.) zu nutzen um die Tabelle zu erstellen. Die Steinhart-Hart Formel welche für den NTC angepasst wurde, gibt den Widerstand bei entsprechender Temperatur aus. Abgeleitet aus dem Widerstand, ist es möglich die Outputspannung des Spannungsteilers zu berechnen und daraus den Wert des ADC. Berechnete Werte können wie folgt ins Programm eingefügt werden:
// // Table for converting temperature values to ADC values. // Every element of the array marks one Celsius degree. // Elements begin from -20 degree and end at 100 degree. // There are 121 elements in the array. // const signed short min_temp = -20; const signed short max_temp = 100; const unsigned short conversion_table[] = { 91,96,102,107,113,119,125,132,139,146,153, 160,168,176,184,192,201,210,219,228,238,247, 257,267,277,288,298,309,319,330,341,352,364, 375,386,398,409,421,432,444,455,467,478,489, 501,512,523,534,545,556,567,578,588,599,609, 619,629,639,649,658,667,677,685,694,703,711, 720,728,736,743,751,758,766,773,780,786,793, 799,805,811,817,823,829,834,839,844,849,854, 859,863,868,872,876,880,884,888,892,896,899, 903,906,909,912,915,918,921,924,927,929,932, 934,937,939,941,943,945,947,949,951,953,955 };
Following algorithm may be used to find the temperature which corresponds to the parameters of the ADC:
// // Converting the ADC values to Celsius degrees: // signed short thermistor_calculate_celsius(unsigned short adc_value) { signed short celsius; // Covering the table backwards: for (celsius = max_temp - min_temp; celsius >= 0; celsius--) { // If the value in the table is the same or higher than measured // value, then the temperature is at least as high as the temperature // corresponding to the element. if (adc_value >= conversion_table[celsius])) { // Since the table begins with 0 but values of the elements from -20, // the value must be shifted. return celsius + min_temp; } } // If the value was not found the minimal temperature is returned. return min_temp; }
Der Algorithmus sucht den Bereich aus der Tabelle in dem der ACD Wert liegt und, und nimmt die niedrigere Nummer dieses Bereiches. Die Ranknummer markiert die Gradzahl und beim addieren der primären Temperatur wird eine Genauigkeit von 1°C erreicht.
Diese Umrechnungstabelle und Funktion sind schon in der HomeLab Library, daher gibt es keine Grund diese für diese Aufgabe zu erstellen. In der Library heisst die Umrechnungsfunktion thermistor_calculate_celsius. Es muss bedacht werden, dass die Funktion nur richtig ist, wenn sie mit dem Thermistor des Sensormoduls von HomeLab genutzt wird. Wenn man andere Thermistoren nutzt muss eine entsprechende Umrechnungstabelle erstellt werden und eine komplexere Funktion verwendet werden, welche im Handbuch der Library beschrieben wird. Das Beispielprogramm dieser Übung ist ein Thermometer, welches Temperatur in °C Misst und sie auf dem Alphabetischen LCD ausgibt.
// // Example program of the thermistor of Sensors module. // The temperature is displayed on the LCD. // #include <stdio.h> #include <homelab/adc.h> #include <homelab/module/sensors.h> #include <homelab/module/lcd_alpha.h> // // Main program // int main(void) { unsigned short value; signed short temperature; char text[16]; // Setting the LCD lcd_alpha_init(LCD_ALPHA_DISP_ON); // Cleaning the LCD lcd_alpha_clear(); // Name of the program lcd_alpha_write_string("Termomeeter"); // Setting the ADC adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Endless loop while (true) { // Reading the 4 times rounded values of the voltage of the thermistor value = adc_get_average_value(2, 4); // Converting the values of ADC into celsius scale temperature = thermistor_calculate_celsius(value); // Converting the temperature in to text. // To display the degree sign, the octal variable is 337. sprintf(text, "%d\337C ", temperature); // Displaying the text in the beginning of the second row of the LCD. lcd_alpha_goto_xy(0, 1); lcd_alpha_write_string(text); } }