Vajalikud teadmised: [HW] Kasutajaliidese moodul, [ELC] Pingejagur, [AVR] Analoog-digitaalmuundur, [LIB] Analoog-digitaalmuundur, [LIB] Graafiline LCD, [LIB] Andurid
Termistor on takisti, mille takistus muutub temperatuuriga. Termistore on kahte liiki: positiivse ja negatiivse temperatuuri koefitsiendiga. Positiivse koefitsiendiga termistori takistus temperatuuri tõustes kasvab ja negatiivsel väheneb. Vastavad lühendatud ingliskeelsed nimed on neil PTC (positive temperature coefficient) ja NTC (negative temperature coefficient).
Termistori kasutamise teeb keeruliseks tema takistuse temperatuurisõltuvuse mittelineaarsus. Lineaarne on sõltuvus vaid väikestes vahemikes, mitmekümnekraadise ja suurema mõõtepiirkonna arvutamiseks sobib Steinhart-Harti kolmandat järku eksponentsiaalne võrrand. NTC termistoride jaoks on olemas järgmine B-parameetriga lihtsustatud võrrand:
kus:
B-parameeter on koefitsient, mis tavaliselt antakse termistori andmelehes. Samas on see ainult teatud temperatuurivahemikes piisavalt konstantne, näiteks 25–50 °C või 25–85 °C. Kui mõõdetav temperatuurivahemik on suurem, tuleb võimalusel kasutada andmelehel antud võrrandit.
Termistori takistust mõõdetakse kaudselt pingejaguriga, kus ühe takisti asemel on termistor ja mille sisendpinge on konstantne. Mõõdetakse pingejaguri väljundpinget, mis muutub koos termistori takistuse muutusega. Pinget rakendades läbib termistori aga elektrivool, mis termistori selle takistuse tõttu soojendab ja seega omakorda takistust muudab. Termistori soojenemisest tekkivat viga saab arvutuslikult kompenseerida, kuid lihtsam on kasutada suurema takistusega termistorit, mis soojeneb vähem.
Piiratud ressurssidega ja suurt täpsust mittenõudvates rakendustes kasutatakse eelnevalt välja arvutatud temperatuuri ja takistuse vahelise sõltuvuse tabelit. Tabelis on üldjuhul kirjas kindla vahemikuga temperatuurinäitude vastavus anduri takistuse, pinge või analoog-digitaalmuunduri väärtusega. Tabeli puhul on kogu eksponentsiaalne arvutus eelnevalt ära tehtud ja programmis tuleb vaid mõõdetud parameetrile vastav rida üles otsida ja temperatuur välja lugeda.
Kodulabori moodul on varustatud 10 kΩ nimitakistusega NTC tüüpi termistoriga. Temperatuuril 25-50 °C on termistori B-parameeter 3900. Termistori üks viik on ühendatud toitega ja teine mikrokontrolleri analoog-digitaalmuunduri sisendisse (Kodulabor II puhul kanal 2, Kodulabor III puhul kanal 14). Sama mikrokontrolleri viigu ja maaga on ühendatud ka takisti, mis koos termistoriga moodustab pingejaguri. Kuna tegu on NTC termistoriga, mille takistus väheneb temperatuuri kasvades, siis samaaegselt tõuseb ka pingejaguri väljundpinge.
Temperatuuri leidmiseks on AVR-il otstarbekas kasutada temperatuuri ja analoog-digitaalmuunduri väärtuste teisendustabelit. Mõistlik on leida soovitud temperatuurivahemikust igale kraadile vastav analoog-digitaalmuunduri väärtus, sest vastupidine tabel läheb 10-bitise ADC väärtuste hulga tõttu liiga suureks. Tabeli tegemiseks on soovitatav kasutada mõnd tabelarvutuse programmi (MS Excel, LibreOffice Calc vmt). Eespool toodud NTC termistoride jaoks kohandatud Steinhart-Harti valemiga saab leida temperatuurile vastava termistori takistuse. Takistusest saab arvutada pingejaguri väljundpinge ning sellest omakorda ADC väärtuse. Leitud väärtused saab järgneval viisil programmi sisse kirjutada:
// Temperatuuri ADC väärtuseks teisendamise tabel // Iga massiivi element tähistab ühte Celsiuse kraadi // Elemendid algavad -20 kraadist ja lõpevad 100 kraadiga // Kokku on massiivis 121 elementi 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 };
Et tabelist ADC väärtuse järgi temperatuur leida, võib kasutada järgmist algoritmi:
// ADC väärtuse teisendamine Celsiuse kraadideks signed short thermistor_calculate_celsius(unsigned short adc_value) { signed short celsius; // Tabeli tagurpidi läbikäimine for (celsius = max_temp - min_temp; celsius >= 0; celsius--) { // Kui tabeli väärtus on sama või suurem kui // mõõdetud tulemus, siis temperatuur on vähemalt // sama kõrge kui elemendile vastav temperatuur if (adc_value >= conversion_table[celsius]) { // Kuna tabel algab nullist, aga elementide // väärtus -20 kraadist, siis tuleb väärtust nihutada return celsius + min_temp; } } // Kui väärtust ei leitud, tagastatakse minimaalne temperatuur return min_temp; }
Algoritm otsib tabelist vahemikku, kuhu ADC väärtus jääb, ja saab teada selle vahemiku aluspiiri järjekorranumbri. Järjekorranumber tähistab kraade, sellele tuleb ainult algtemperatuur otsa liita ja nii saadaksegi 1 kraadi täpsusega temperatuur.
Toodud teisendustabel ja funktsioon on juba olemas Kodulabori teegis, nii et käesolevas harjutuses neid ise kirjutama ei pea. Teisendamise funktsioonil on teegis nimeks thermistor_calculate_celsius. Arvestama peab, et teisendus kehtib ainult Kodulabori moodulil asuva termistori kohta. Muu termistori kasutamiseks tuleb ise teisendustabel luua ja kasutada teegi juhendis kirjeldatud keerukamat funktsiooni. Harjutuse näidisprogrammiks on termomeeter, mis mõõdab temperatuuri Celsiuse kraadides ja kuvab seda LCD ekraanil.
// Kodulabori termistori näidisprogramm // LCD ekraanil kuvatakse temperatuur kraadides #include <stdio.h> #include <homelab/adc.h> #include <homelab/module/sensors.h> #include <homelab/module/lcd_gfx.h> #include <homelab/delay.h> // Robootika Kodulabor II //#define ADC_CHANNEL 2 // Robootika Kodulabor III #define ADC_CHANNEL 14 // Põhiprogramm int main(void) { unsigned short value; signed short temperature; char text[16]; // LCD ekraani algseadistamine lcd_gfx_init(); // LCD ekraani puhastamine ja taustavalguse seadmine lcd_gfx_clear(); lcd_gfx_backlight(true); // Programmi nime kuvamine lcd_gfx_goto_char_xy(1, 1); lcd_gfx_write_string("Termomeeter"); // ADC muunduri seadistamine adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Lõputu tsükkel while (1) { // Termistori pinge 4-kordselt ümardatud väärtuse lugemine value = adc_get_average_value(ADC_CHANNEL, 4); // ADC väärtuse kraadideks ümberarvutamine temperature = thermistor_calculate_celsius(value); // Temperatuuri tekstiks teisendamine // Kraadi märgi kuvamiseks on oktaalarv 56 sprintf(text, "%d\56C ", temperature); // Teksti kuvamine LCD kolmandal real lcd_gfx_goto_char_xy(5, 3); lcd_gfx_write_string(text); hw_delay_ms(1000); } return 0; }