Analog Temperatur
Med denne temperatur sensor er det muligt for et kredsløb at mærke temperaturen. Dette sker på analogt output(S). Det analoge output giver en spænding, der er afhængig af temperaturen.
Modulet
Modulet er fra keyes-serien keyes-moduler, og har betegnelsen KY-013.
Teorien bag modulets måling af temperatur
Temperatur sensoren er baseret på, at en type variabel modstand kaldet en termistor(den sorte knop i enden af modulet), har en elektrisk modstand som er afhængig af temperaturen omkring den(meget mere end almindelige modstande). Ved at kende til nogle bestemte specifikationer fra termistorens datablad, kan man opstille en funktion, der udtrykker temperaturen som funktion af modstanden over den. Denne funktion tager udgangspunkt i Steinhart-Hart ligningen:
Hvor T er temperaturen i grader kelvin(K) og R er modstanden i antal ohm(Ω). A, B og C er de tre såkaldte Steinhart-Hart parametre som kan oplyses i databladet for den pågældende termistor.
Der findes desuden forskellige typer termistorer, bl.a. PTC(positiv temperatur koefficient) og NTC(negativ temperatur koefficient). Som navnet antyder er forskellen den, at en PTC termistor øger sin modstand når temperaturen øges, mens en NTC termistor sænker sin modstand når temperaturen øges. Grundet forskellen på de to typer, kan man bruge en simplere version af Steinhart-Hart ligningen når der er tale om en NTC termistor som det er tilfældet med dette temperatur-modul. Ligningen ser ud som følgende:
Hvor T er temperaturen i grader kelvin(K) og R er modstanden i antal ohm(Ω), mens R0 er modstanden ved temperaturen T0(10KΩ ved 25C(298,15K)).Ligningen er i bund og grund den samme som før, men her ses der bort fra A og C parametrene, hvor C i stedet sættes til 0 og B sættes til sin reciprokke værdi, mens A parameteren sættes som følgende:
Det ses, at vi altså nu kun behøver at kende termistorens B parameter for at kunne få et udtryk for temperaturen som funktion af modstanden. B parameteren for termistoren i dette modul er målt til 1315K (kelvin), hvilket giver følgende funktion:
Hvor "Res" er modstanden over termistoren. Afbildet i et koordinatsystem med temperaturen i Kelvin op ad y-aksen og modstanden over termistoren hen ad x-aksen:
Og tilsvarende i grader celsius:
Det ses altså at forholdet mellem temperatur og modstand ikke er lineært som det er tilfældet med mange andre temperatursensorer. Dog er det muligt blot at betrakte forholdet som lineært, for at gøre beregningerne nemmere, hvis man kun opererer inde for et lille begrænset temperaturområde (dette er beskrevet i afsnittet om anvendelsen af modulet).
For at kunne anvende modulet mere konkret til visning af temperatur, så kan det være en fordel at omskrive ligningen , så man får modstanden udtrykt ved hjælp af temperaturen som vist her
Dette vender blot om på x- og y-aksen, så det er ikke så interessant. Det bliver mere interessant, hvis man sætter udtrykket for modstanden ind i en spændingsdeler, så man kan få et udtryk for den spænding man måler. Med en modstand på 10k ohm og en forsyning på 5V, så bliver udtrykket som følger:
Hvis man skitserer denne graf fra -100 grader til 200 grader vil man se at den kommer asymptotisk fra 5V i det lave temperaturområde, og går asymptotisk mod 0V i det høje temperaturområde.
Man kan også se at der er et område omkring de 25 grader, hvor grafen er tæt på at være lineær.
Ved at begrænse måleområdet til at ligge fra 0 til 50 grader, så kan man lave en lineær funktion som følger:
Hvis man skitserer denne graf fra 0 til 50 grader, sammen med den lineære funktion, så vil man få følgende visning:
Dette giver fejl på op mod 1 grad, hvilket måske kan være for meget.
Hvis man vil ud over det, så kan man indsnævre temperaturområdet, så man kun måler fra 15 til 35 grader, hvilket kan give væsentlig større nøjagtighed.
Har man brug for temperaturområdet fra 0 til 50 grader, så kan man dele lineariseringen om i 2 intervaller, så man får et udtryk der gælder fra 0 til 25 grader:
og et andet udtryk der gælder fra 25 til 50 grader:
Skitserer man temperaturkurven sammen med de to stykker lineær funktion, så kan man se at man kommer væsentligt tættere på den aktuelle kurve (fejlen er under 0,3 grader):
Temperatur modulets kredsløb
Kredsløbet er meget simpelt. Det består af NTC-modstanden R2 og en 10k ohm modstand R1, der sidder op til +5V.
Når temperaturen stiger bliver modstanden mindre, og dermed falder spændingen som det er vist i kurverne under forklaringen til kredsløbet.
Anvendelse af temperatur modulet
Det følgende vil forklare, hvordan man bruger dette modul til bestemmelse af temperaturen. Afsnittet omhandler brugen af analog out funktionen til nærmere at kunne bestemme den specifikke temperatur med en PIC16F684 mikrocontroller med ADC_holst modulet til AD-konvertering.
Simpel Bestemmelse af temperatur
Med analog output funktionen vil man kunne bestemme temperaturen i antal grader (celsius f.eks.). Dette bygger på termistor teorien som den beskrives i afsnittet "Teorien bag modulets måling af temperatur". Kreds-eksemplet til højre viser anvendelse af analog out (S) til bestemmelse af temperaturen.
Programmet som styrer PIC'en benytter sig af 4 LED lysdioder til at indikere i hvilket interval temperaturen befinder sig. Dette sker ved at PIC'en sender et højt signal ud af en af udgangene C0, C1, C3 eller C4. Modstanden R3 på 100Ω fungere som fælles modstand for de 4 LED dioder. Indgangen C2 fungerer som analog indgang, hvor modulet ADC_holst konverterer det analoge signal til digital værdi i PIC'en (til AD-konvertering bruges ADC_holst til PIC16F684 eller PIC16F690, ellers bruges modulet ADC) Man kunne også lave et system der giver den nøjagtige måling som temperatur-modulet leverer med en LCD skærm eller lign.
Nedestående program til mikrocontrolleren PIC16F684 ville fungere som styringen til det omtalte kredsløb. Detaljeret gennemgang af koden er indlejret som kommentarer (markeret ved "--"):
-- Definering af mikrocontroller
include 16f684
-- Opsætning
pragma target clock 4_000_000
pragma target WDT DISABLED
pragma target OSC INTOSC_NOCLKOUT
pragma target PWRTE ENABLED
pragma target MCLR INTERNAL
pragma target CP DISABLED
pragma target CPD DISABLED
pragma target BROWNOUT ENABLED
pragma target IESO DISABLED
pragma target FCMEN DISABLED
-- Importer "delay"-modulet
include delay
-- Definerer VDD(5V) som referenceværdien
const byte ADC_NVREF = 0
-- Importer "ADC_Holst"-modulet
include ADC_Holst
-- Aktiver de digitale PIC-ind/udgange
enable_digital_io()
-- Gør de digitale ind/udgange til udgange
portc_direction = all_output
-- Variabler til programmet:
-- Kanal 6 svarer til pin_C2 på PIC'en 16f684
var byte kanal = 6
-- Definerer en variabel der tildeles en værdi senere
var word temp
-- Følgende 3 variabler skal definere intervalerne:
var word x1 = 480 -- Definerer en bestemt værdi fra 0 til 1023
var word x2 = 512 -- Definerer en bestemt værdi fra 0 til 1023
var word x3 = 544 -- Definerer en bestemt værdi fra 0 til 1023
-- Følgende program vil blive udført for evigt
forever loop
-- Returnerer en værdi fra 0 til 1023
temp = adc_read(kanal)
if (temp > x1) & (temp < x2) then
-- Hvis temperaturen er indenfor det valgte interval
-- defineret af x1 og x2, sker følgende
pin_C0 = HIGH -- Udgangen C0 sættes til HIGH
pin_C1 = LOW -- Udgangen C1 sættes til LOW
pin_C3 = LOW -- Udgangen C3 sættes til LOW
pin_C4 = LOW -- Udgangen C4 sættes til LOW
elsif (temp => x2) & (temp < x3) then
-- Hvis temperaturen er indenfor det valgte interval
-- defineret af x2 og x3, sker følgende
pin_C0 = LOW -- Udgangen C0 sættes til LOW
pin_C1 = HIGH -- Udgangen C1 sættes til HIGH
pin_C3 = LOW -- Udgangen C3 sættes til LOW
pin_C4 = LOW -- Udgangen C4 sættes til LOW
elsif temp <= x1 then
-- Hvis temperaturen er lavere end x1 sker følgende
pin_C0 = LOW -- Udgangen C0 sættes til LOW
pin_C1 = LOW -- Udgangen C1 sættes til LOW
pin_C3 = HIGH -- Udgangen C3 sættes til HIGH
pin_C4 = LOW -- Udgangen C4 sættes til LOW
elsif temp >= x3 then
-- Hvis temperaturen er højere end x3 sker følgende
pin_C0 = LOW -- Udgangen C0 sættes til LOW
pin_C1 = LOW -- Udgangen C1 sættes til LOW
pin_C3 = LOW -- Udgangen C3 sættes til LOW
pin_C4 = HIGH -- Udgangen C4 sættes til HIGH
end if -- Afslutter if-sætningerne
delay_100ms(1) -- Giver en forsinkelse på 100ms
end loop -- Afslutter forever-loopet
Mere avanceret temperaturmåling
For at kunne programmere koden til at vise temperaturen, så skal man foretage en mskrivning, så man kan tolke temperaturen ud fra AD-læsningen:
Ved at lagre et antal i et array og summere dem, så kan man skabe en kunstig opløsning på AD-konverteren, så man kan komme i nærheden af en decimal på temperaturen.
Da PIC'en regner i heltal, så skal man være opmærksom på opløsningen og at man ikke mister decimaler ved beregningen. Det kan gøres ved at udføre beregningerne i større variabler (DWORD) og afslutte med at dividere ned til den endelige opløsning.
For kunne lave nogle håndterbare beregninger, så omskrives formlen til at arbejde i heltal, og at resultatet giver 10 gange temperaturen, så man på simpel vis kan skille tallet ad i en heltalsdel og en decimaldel:
I formlen her indgår SumAntal, der med de angivne konstanter skal være 16.
Interfacefil til Temperatur-modulet
Der skal i interface-filen angives hvilken kanal der måles på, og hvor stort midlingsarrayet skal være (4, 8, 16 eller 32). Det angives i Temperatur_def.jal som følger:
const byte Temperatur_channel = 2
const byte Temperatur_Sum_Antal = 16
Anvendelse af Temperatur-modulet
Softwaren ligger i en ZIP-fil med modulet og et eksempel på anvendelse.
Koden er lavet til at vise temperaturen på et ALCD display, så i initialiseringen hentes disse to moduler ind:
include ALCD
ALCD_clear_screen() -- (to first line)
include Temperatur
Herefter køres der i et forever-loop, hvor der hentes værdierne, og foretages dels midling og dels en omregning til temperatur i grader celcius.
Når man har kaldt Temperatur, så ligger heltalsdelen af temperaturen i Temperatur_heltal som en signed byte, og den ene decimal efter kommaet ligger i Temperatur_decimal. Hele loopet ser ud som følger:
forever loop
Temperatur
ALCD_cursor_position(0,0) -- start of first line
ALCD_write_char("T")
ALCD_write_char("e")
ALCD_write_char("m")
ALCD_write_char("p")
ALCD_write_char(" ")
ALCD_SDec_3(temperatur_heltal)
ALCD_write_char(",")
ALCD_Dec_1(Temperatur_decimal)
ALCD_cursor_position(1,0) -- start of second line
ALCD_Dec_5(word(Temperatur_sum))
delay_1ms(20)
end loop
Udskriften af Temperatur_sum er blot til testformål, og har ingen funktionel værdi.
Koden i Temperatur modulet
Den interessante del af koden er selve proceduren Temperatur, der beregner temperaturen i grader celcius ud fra summen af AD-tallene:
Procedure Temperatur is
var sdword middel -- Internal variables
var word aktuel
-- Next position in the array
Temperatur_n = (Temperatur_n + 1) % Temperatur_Sum_Antal
-- Read the AD-value
aktuel = adc_read(Temperatur_channel)
-- Update the sum in the array and the summin variable
Temperatur_sum = Temperatur_sum - Temperatur_save[Temperatur_n] + aktuel
Temperatur_save[Temperatur_n] = aktuel
-- Calculate the average temperature, in a signed variable
-- the number is 10 times the result, in order to make one decimal
middel = Temperatur_sum * 1000
middel = Temperatur_constant - middel
middel = middel / Temperatur_divisor
-- Calculate the integer number in a signed byte, and the decimal reading
Temperatur_heltal = sbyte(middel / 10)
Temperatur_decimal = byte(middel % 10)
end procedure
Moduler på Holstebro HTX | |||||||
---|---|---|---|---|---|---|---|
Tastaturer | Displays | AD-konvertering | I/O-ekspander | Serielt | Interface | Færdige | Andre |
RC-tast - AD-tast - M_tast | ALCD - LCD | ADC_holst - ADC mcp3201 - mcp3208 |
input - output | Seriel_holst - Serial hardware Serial hw int cts - Serial software |
Stepmotor - RFID RGB - RF-link - Afstand |
Humidity - Analog temp - Dig temp Accelerometer |
Rotary Encoder |
Oversigt over Hardware Moduler på Holstebro HTX