Analog Temperatur

Fra HTX Arduino
Spring til navigation Spring til søgning
Billede af NTC temperatur sensor


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

Termistor symbol

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:

Stainharhart.jpg

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:

Stainharhartsimpeltal.jpg

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:

Stainharhartsimpel.jpg

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:

Stainharhartsimpeltalogparameterere.jpg
Tempresfunktion.jpg

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:

Stainharthartgrafkelvin.jpg

Og tilsvarende i grader celsius:

Tempresfunktion2.jpg
Stainharthartgrafcelsiuss.jpg

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

Stainhart-res-temp.PNG

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:

Stainhart-volt-temp.PNG

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.

Stainhart-volt-temp-graf1.PNG

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:

Stainhart-volt-temp-lin.PNG

Hvis man skitserer denne graf fra 0 til 50 grader, sammen med den lineære funktion, så vil man få følgende visning:

Stainhart-volt-temp-graf2.PNG

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:

Stainhart-volt-temp-lin1.PNG

og et andet udtryk der gælder fra 25 til 50 grader:

Stainhart-volt-temp-lin2.PNG

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):

Stainhart-volt-temp-graf3.PNG

Temperatur modulets kredsløb

Analogt temperatur målekredsløb med NTC

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

Temperatur sensor kredsløb eksempel med S

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:

Temp-ad1.PNG

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:

Temp-ad2.PNG

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

Keyes-moduler på Holstebro HTX
Simple Digitale Input Switch modul - Reedrør - Hall sensor - Optisk Skift - Photo Gate - Vibration sensor - Vibration switch - Tilt sensor - Kviksølv kontakt - Linje følger
Digitalt kodede Input IR Modtager - Humidity -Digital Temperatur
5 benede Input Rotary Encoder -XY Joystick
Digitale 4 benede Input Magic Cup Light - LED 3-farve - RGB - RF-link - Afstand
Justerbare analoge/digitale Input Reed Magnetsensor - Temperatur Niveau - Metal detektor - Flamme - Hall Kontakt - Almindelig Mikrofon - Følsom Mikrofon
Simple digitale Output LED 2-farve - Aktiv Buzzer - Blink LED - IR LED - Laser - Relæ modul - Passiv Buzzer
Analoge input Analog Temperatur - LDR - Finger Pulsmåler - Lineær Magnetfelt