Bu formul protona nasıl uygulanır?ben çözemedim

Başlatan Murat Mert, 18 Mayıs 2009, 11:35:58

Murat Mert

Sn. arkadaşlar ntc ile ölçmede ben bu formulü anlayıp uygulayamadım. Anlayan varsa ricam bunu protona nasıl uygularız? Kolay gelsin.


Alıntı yapılan: "picker"Değerli arkadaşlar,
Öncelikle 2 soruya yanıt vereyim.

1. Neden LM35 değilde NTC?
Arkadaşlar, sıcaklığı n faklı yöntemle ölçebilirsiniz. Bunların bazıları son derece kolay, bazıları ise biraz daha meşakkatlidir. Bununla birlikte uygulamayı çalıştıracağınız ortam, koşullar sizi belli bir takım sensör tiplerini seçmeye itebilir. Bu sebeple her uygulama DS1820, LM35, DS1620, NTC veya PTC ile yapılamaz. Dolayısıyla bunun sorgulanması çok da doğru değil.

2. Neden kod vermiyorum?
Burada mevzu nasıl analog dijital dönüştürülür değil. Yukarıda yazdıklarım kod yazmak için yeterlidir. O bilgiye ulaşmak benim 2 günümü aldı yaklaşık. Ondan önce de ısı tablosu ile yapma gayretine girdim. Fakat floating point kullandığımdan dolayı bir süre sonra PIC hafızası değişken sayısını kaldırmamaya başladı. Bu sebeple ben de önce yukarıda yazdığım formülasyona ulaştım. Sonra da yaklaşık 8-10 satırlık bir kod ile her değer için hassas direnç değerini dizi değişken kullanmadan, if-then'lerle uğraşmadan, tek değişken ile çözdüm. Şimdi deniyor ki sen o kadar uğraştın, balığı tuttun, balığı bana ver... Hayır... Balığı vermeyeceğim. Ama bir arkadaşımın isteği üzerine nasıl balık tutulacağını anlatacağım... (Hesaplama örneği)

1K NTC için hesaplama örneği
NTC datasheet'inde 1K NTC için sıcaklık tablosuna bakıyoruz (Murata marka).

Şimdi üç farlı değer için (Örneğin -10, 0 ve 25 derece olsun) direnç değerlerini seçelim...
-10 Derece için 4829 Ohm
0 Derece için 2977 Ohm
25 Derece için 1000 Ohm (NTC'lerin değerleri 25 derecedeki dirençleri için verilir).

Şimdi bu derece değerlerini Kelvine çeviriyoruz.

-10 Derece : 263,15 kelvin
0 Derece : 273,15 Kelvin
25 Derece : 298,15 Kelvin

Bunlar bizim T1, T2 ve T3 değerlerimiz...
Şimdi 1/T1, 1/T2 ve 1/T3 değerlerini hesaplayalım.

Sırasıyla : 0,0038, 0,003661, 0,003354 değerlerini bulduk.

Şimdi, Ln(4829), Ln(2977) ve Ln(1000) (Bu direnç değerlerinin 10 tabanına göre logaritmalarını alıyoruz) değerlerini hesaplayalım.

Bunlar da sırasıyla
8,48
8
6,91 çıktı.

Şimdi bunların 3. kuvvetlerini (küplerini) alalım.
Sırasıyla :
610,32
511,74
329,62

değerlerini bulduk.

Dolayısıyla şu üç denklemi elde ediyoruz :
0,0038=A+8,48.B+610,32.C
0,003661=A+8.B+511,74.C
0,003354=A+6,91.B+329,62.C

Şimdi buraya kadar verdim hesabı.

Bu 3 denklemden A, B ve C'yi hesaplayıp katsayıları buluyoruz.

Devam ediyoruz.
Önce 1. denklemin tüm katsayılarını 2. denklemdeki C'nin katsayıları ile çarpıyoruz.
Sonra 2. denklemin tüm katsayılarını 1. denklemdeki C'nin katsayıları ile çarpıyoruz.
Şu çıkıyor :
1,944689127=511,7449437A+4340,822591B+312326,6113C
2,234365537=610,3169464A+4881,72468B+312326,6113C
Bu iki denklemi birbirinden çıkarıyoruz. Şunu elde ediyoruz :
-0,28967641=-98,57200268A-540,9020892B+0C

Aynı işlemi 2 ve 3. denklemler için yapıyoruz ve :
-0,794427349=-280,6990144A-1419,970714B+0C

Şimdi 2 bilinmeyenli 2 denklemimiz oldu.
Bu 2 denklemi çözdüğümüzde :
A=0,001549185
B=0,000253225

Buluyoruz.
Birinci denklemde bu değerleri yerine koyup C'yi çekiyoruz ve
C=1,68718E-07
değerini buluyoruz.

Yani bizim kelvin cinsinden sıcaklığımız
T=1/(0,001549185+0,000253225ln(R)+1,68718E-07(lnR)^3)
oluyor.

Santigrad cinsinden sıcaklığımız ise
C=[1/(0,001549185+0,000253225ln(R)+1,68718E-07(lnR)^3]-273,15 oluyor.

Şimdi bu denklemimizin doğruluğunu test edelim.

Datasheetden 40 derece için direnç nedir ona bakalım.

558 Ohm görünüyor.
Dolayısıyla
[1/(0,001549185+0,000253225ln(558)+1,68718E-07(ln(558))^3]-273,15
hesapladığımızda 40 bulmalıyız.
ln(558)=6,324358962
ln^3(R)=252,9586506

Dolayısıyla formülümüz :
[1/(0,001549185+0,001601488+4,26787E-05)]-273,15
Buradan da
1/0,003193352-273,15
=313,1505791-273,15
C=40,00057908 santigrad bulunur.
Görüldüğü gibi 10'da bir değil, yüzde bir değil, binde bir değil, 10binde 5 hata ile sonucu bulduk. (Yukarıda bazı yuvarlamaları yapmış olmasam tam sonuç bulacaktık).

Herkese sevgiler.

Not : Şu formülleri bulmak için ille de yabancı kitapları karıştırmak zorunda kalmamalı insanlar.

Ama bizde bilgi paylaşımı (Bilgi paylaşımı ile hazırcılığı burada ayırmak gerekiyor) korkulan birşey...

Umarım sizler katıldığınız diğer forumlarda bu bilgileri paylaşırsınız...
mert07

Murat Mert

S.A.
Ustalar ben soğutmacıyım bu sistemi atölyede arızalı gelen cihazların (klimaların) kompresör press sıcaklığını ve evap giriş ve çıkış arasındaki farkları pc den izlemek ve kayıt için düşünüyorum. Araç servislerinde ki gibi test için. DS ve LM sensorleri hat uzun oluğu için hoş olmadı ds çok hassas ama hızlı değil. Kolay gelsin
mert07

Maxim

bende aynı şeyle uğraşıyorum ,
problem matematik bilgisinin yeterli olmaması ,
yoksa arkadaş zaten herşeyi yazmış oraya ,
elle tutulur bir ilerleme kaydedersem yazıcam .

Murat Mert

Alıntı yapılan: "maxiboost"bende aynı şeyle uğraşıyorum ,
problem matematik bilgisinin yeterli olmaması ,
yoksa arkadaş zaten herşeyi yazmış oraya ,
elle tutulur bir ilerleme kaydedersem yazıcam .

Sn Maxiboost teşekkür ederim kafayı yemek üzereyim hesap makinası (okuldan kalma) elimde uğrşıyorum boşa koydum domadı doluya koydum almadı lm ve ds çok kolay olacak ama uyulamamda sök tak olacağı için sağlıklı değil. Kolay gelsin.
mert07

Maxim

arkadaşın verdiği aynı onun gibi yaparak formülleri uygulayarak başka bir ntc hesabı yapmaya çalışıyorum,
bence zaten formülleri anlarsam onu pice uygulamak kolaydır .

kaldığım yere kadar yazayım ,

**ben 10K lık bir ntc seçtim ,
-10 Derece için 44190 ohm
  0 Derece için 28420 ohm
25 Derece için  10000 ohm


** bu değerler zaten sabit ,
haliyle 1/T1, 1/T2 ve 1/T3  değerlerimiz aynı olacak .
-10 Derece : 263,15 kelvin
0 Derece : 273,15 Kelvin
25 Derece : 298,15 Kelvin

yani ,
1/T1= 0,0038
1/T2= 0,003661
1/T3= 0,003354

** şimdi direnç değerlerimizin 10 tabanına göre logaritmalarını alıyoruz .
bunun için windows calculatoru kullandım ,
Ln(44190) , Ln(28420) , Ln(10000)

44190 = 10.69
28420 = 10.25
10000 = 9.21


**sonra bunların küplerini alıyoruz ,
10.69 = 1221.6
10.25 = 1076.8
9.21 = 781.2

küpleride aldık ,



**şimdi bulmamız gereken 3 tane denklemimiz var ,
Bu 3 denklemden A, B ve C'yi hesaplayıp, katsayıları buluyoruz
  0,0038 =  A + 10,69.B + 1221,6.C
0,003661 = A + 10,25.B + 1076,8.C
0,003354 = A + 9,21.B + 781,2.C


devam edecek.

wsxwsx

Alıntı yapılan: "maxiboost"** şimdi direnç değerlerimizin 10 tabanına göre logaritmalarını alıyoruz .
bunun için windows calculatoru kullandım ,
Ln(44190) , Ln(28420) , Ln(10000)

Ln, 10 tabanına göre değil e tabanına göre logaritmadır.

Maxim

Alıntı yapılan: "wsxwsx"
Alıntı yapılan: "maxiboost"** şimdi direnç değerlerimizin 10 tabanına göre logaritmalarını alıyoruz .
bunun için windows calculatoru kullandım ,
Ln(44190) , Ln(28420) , Ln(10000)

Ln, 10 tabanına göre değil e tabanına göre logaritmadır.

hımm peki hesap doğrumu ?
Ln(44190) = 10.69 ?

Maxim

aslında Stein-Hart denklemi ile hesaplıyorlar bunu protoncular ,
ben hiç deneme yapmadım ama bize gerekli olan o ntc nin T25 ve B değerleri , yanlışım olabilir ,T25, 25 derecedeki direnç değeri, B ise datasehhetinde verilen beta değeriki , her thermistörün B değerini bilemiyoruz ,o yüzden birkaç hesap yaparak o değeri buluyoruz ki ,
sanırım o arkadaşın ilk baştaki formüllerde bulduğu o.

accuracy of approx 1 degree centigrade, and a resolution of approx 0.1 degrees

yanlız bu kod 18F serilerinde çalışır ,log komutunu kullandığı için ,
16 serisinde olmuyor .



kafa karıştırmaz umarım ,
bu Stein-Hart denklemi ile hazırlanmış proton+ formülü

'
' Thermistor linearisation using a Stein-Hart equasion
'
'
' The program below is based on a 10K Ohm resistor as part of the thermistor's circuit: -
'
' +5 Volts
' --------
' |
' \
' / 10k Ohm 1% (or better) Resistor 
' \
' /
' |
' o-------------O To PORTA.0 of the PICmicro
' |
' \
' /o
' \	 NTC Thermistor
' /
' |
' |
' -----
' ---
' -
'
Include "PROTON18_20.INC"
 
FLOAT_DISPLAY_TYPE = LARGE ' Use the larger but faster floating point display routine
 
Dim MEDIAN_SWAP as Word ' Temporary Median Filter variable for swapping
Dim MEDIAN_INDEX as Byte ' Holds the position in the Bubble sort
Dim MEDIAN_SWAP_OCCURED as Bit ' Indicates if the Bubble sort is complete 
Dim THERMISTOR_VALUE as Word ' Holds the raw thermistor ADC reading
Dim RESISTANCE as Float ' Holds the resistance of the thermistor for a given temperature
Dim TEMPERATURE as Float ' Holds the floating point temperature in degrees Centigrade
Dim TEMP as Float ' Temporary variable for the thermistor linearisation
Dim LN as Float ' Used to hold the LOG of the thermistor value 
'
' The MEDIAN_SAMPLE array declaration and its associated constants (below) should be placed at the end of the DIM list
' 
Symbol MEDIAN_SAMPLES_TO_TAKE = 21 ' The amount of samples to take
#if(MEDIAN_SAMPLES_TO_TAKE > 127)
#error"Constant MEDIAN_SAMPLES_TO_TAKE cannot be greater than 127"
#endif
Symbol MIDDLE_SAMPLE = (MEDIAN_SAMPLES_TO_TAKE / 2) + 1 ' The middle sample of the samples taken
Dim MEDIAN_SAMPLE[MEDIAN_SAMPLES_TO_TAKE] as Word ' Create an array to hold the range samples
 
 
Dim AD_RESULT as ADRESL.Word ' Alias the 16-bit ADRESL\H register as AD_RESULT
Symbol GO_DONE = ADCON0.2 ' ADC completion poll bit 
'
' Constant values used for the Stein-Hart thermistor linearisation routine
' 
Symbol QUANTA = 5000.0 / 1024.0 ' Quatasising constant for ADC reading to Voltage calculation
Symbol T25 = 0.0033540 ' Thermistor's t25 value
Symbol B = 1.0 / 3489.0 ' Thermistor's B value
'
' The Stein-Hart linearising equation below is only suitable for describing a restricted range around 
' the rated temperature or resistance with sufficient accuracy.
'
' 1
' Tt = ------------------------
' 1/B * Ln(Rt/R25) + 1/T25
'
' The B values for common NTC thermistors range from 2000K through to 5000K.
' For this application, the popular, and more complicated, Stein-Hart equation is more accurate.
'
' The thermistor used did not provide the B value within its datasheet, but did give the T25 value. 
' i.e. resistance at 25 degrees Centigrade.
' To calculate the B value use the equation below.
'
' Tt * T25 R25
' B = ---------- * Ln ------
' Tt - T25 R100
'
' or: -
'
' (25 + 273.13) * (100 + 273.15) R25
' B = -------------------------------- * Ln ------
' 75 R100
'
' giving: -
'
' R25
' B = 1483.4 * Ln ------
' R100
'
' Thus, knowing the resistance at 25 degrees Centigrade and also at 100 degrees Centigrade 
' we can use the above calculation to find the value of B for a given thermistor.
 
'---------------------------------------------------------------------------------------
' THE MAIN DEMO PROGRAM LOOP STARTS HERE
 
Delayms 200 ' Wait for things to stabilise
Cls ' Clear the LCD
Print 254,72,%00000110,%00001001,%00001001,%00000110,0,0,0,0 ' Build the LCD degrees symbol in character 1
 
While 1 = 1 ' Create an infinite loop
Gosub READ_TEMP_SENSOR ' Read and linearise the thermistor
Print at 1,1,Dec1 TEMPERATURE,1,"C " ' Display the result on the LCD
Delayms 100 ' Wait a while
Wend ' Close the loop
 
'----------------------------------------------------------------------------------------------------
' Subroutines Start Here
'-----------------------------------------------------------------------------------------------------
' Create a MEDIAN filter to make an educated guess as to what is the true reading from the temperature readings taken.
' The routine below is a BUBBLE SORT, that arranges all the samples in ascending order within the array MEDIAN_SAMPLES.
' The middle sample is then extracted.
' This should eliminate spurious readings from the edges.
' Input : Array MEDIAN_SAMPLE holds "MEDIAN_SAMPLES_TO_TAKE" temperature readings taken
' Output : THERMISTOR_VALUE = the median (middle value) of the samples taken
'
MEDIAN_FILTER:
Repeat
MEDIAN_SWAP_OCCURED = 0 ' Clear flag that indicates swap. 
MEDIAN_INDEX = 0
Repeat ' For each cell of the array...
If MEDIAN_SAMPLE[MEDIAN_INDEX] > MEDIAN_SAMPLE[MEDIAN_INDEX + 1] Then ' Move larger values up. 
MEDIAN_SWAP = MEDIAN_SAMPLE[MEDIAN_INDEX] ' ..by swapping them. 
MEDIAN_SAMPLE[MEDIAN_INDEX] = MEDIAN_SAMPLE[MEDIAN_INDEX + 1]
MEDIAN_SAMPLE[MEDIAN_INDEX + 1] = MEDIAN_SWAP
MEDIAN_SWAP_OCCURED = 1 ' Set bit if swap occurred. 
Endif
Inc MEDIAN_INDEX
Until MEDIAN_INDEX = MEDIAN_SAMPLES_TO_TAKE ' Check out next cell of the array. 
Until MEDIAN_SWAP_OCCURED = 0 ' Keep sorting until no more swaps.
THERMISTOR_VALUE = MEDIAN_SAMPLE[MIDDLE_SAMPLE] ' Extract the middle sample's value
Return 
 
'-----------------------------------------------------------------------------------------------------
' Read the thermistor temperature sensor on AN0 (PORTA.0) and linearise the result
' Input : None
' Output : TEMPERATURE = Temperature in degrees Centigrade
' Notes : The thermistor is sampled by the ADC with 10-bit resolution several times
' : based on the constant "MEDIAN_SAMPLES_TO_TAKE".
' : A Median filter is then called to filter out any noise
' : Then the raw (filtered) thermistor value is run through a Stein-Hart calculation
' : which linearises the value into degrees Centigrade.
' : Accuracy depends on the thermistor and its accompanying 10K Ohm resistor.
'
READ_TEMP_SENSOR:
ADCON1 = %10000000 ' Make PORTA and PORTE all analogue and Right justify the ADC result
ADCON0 = %10000001 ' Set ADC: FRC/32 OSC, AN0, GO_DONE = 0, ADC Powered up 
For MEDIAN_INDEX = 0 to MEDIAN_SAMPLES_TO_TAKE - 1 ' Form a loop for the amount of temperature readings to take 
Delayus 5 ' Wait for the ADC's internal capacitors to charge
GO_DONE = 1 ' \ Take an ADC reading
Repeat : Until GO_DONE = 0 ' / Wait for the ADC conversion to finish
MEDIAN_SAMPLE[MEDIAN_INDEX] = AD_RESULT ' Add the reading to the median array
Next ' Close the loop
Gosub MEDIAN_FILTER ' Perform a median filter on the temperatures read
'
' Perform a Stein-Hart calculation to linearise the thermistor into degrees Centigrade
' 
TEMPERATURE = THERMISTOR_VALUE * QUANTA ' \
TEMP = 5000 - TEMPERATURE ' Find the resistance across the thermistor
RESISTANCE = (TEMPERATURE * 10000) / TEMP ' / 
LN = Log (RESISTANCE / 10000) ' \ 
TEMPERATURE = B * LN + T25 ' / Linearise the result using the stein-hart algorithm
TEMPERATURE = (1 / TEMPERATURE) - 273.15 ' Convert from Kelvin to Centigrade 
ADCON1 = 7 ' Make PORTA and PORTE all digital
Return ' Then return from the subroutine




bu da aynı kodun ,swordfish derleyicisine uygulanmış hali ,
// LCD proton development board
    #option LCD_DATA = PORTD.4
    #option LCD_RS = PORTE.0
    #option LCD_EN = PORTE.1

    Include "LCD.bas" 
    Include "math.bas"
    Include "ADC.bas"
    Include "convert.bas"

{
 Thermistor linearization using a Stein-Hart equation
 based on a program written for the Proton compiler By
 Les Johnston

 The Program below is based On a 10K Ohm resistor As part of the thermistor's circuit: -

  +5 Volts
 --------
    |
    \
    /  10k Ohm 1% (Or better) Resistor
    \
    /
    |
    o-------------O To PORTA.0 of the PICmicro
    |
    \
   o/
    \  Thermistor
    /
    |
    |
  -----
   ---
    -

 The Stein-Hart linearising equation below is only suitable For describing a restricted range around 
 the rated TEMPERATURE Or RESISTANCE with sufficient accuracy.

 1
 Tt = ------------------------
 1/B * LN(Rt/R25) + 1/T25

 The B values For common NTC thermistors range from 2000K through To 5000K.
 For this application, the popular, And more complicated, Stein-Hart equation is more accurate.

 The thermistor used did Not provide the B value within its datasheet, but did give the T25 value. 
 i.e. RESISTANCE At 25 degrees Centigrade.
 To calculate the B value use the equation below.

 Tt * T25 R25
 B = ---------- * LN ------
 Tt - T25 R100

 Or: -

 (25 + 273.13) * (100 + 273.15) R25
 B = -------------------------------- * LN ------
 75 R100

 giving: -

 R25
 B = 1483.4 * LN ------
 R100

 Thus, knowing the RESISTANCE At 25 degrees Centigrade And also At 100 degrees Centigrade 
 we can use the above calculation To find the value of B For a given thermistor.

---------------------------------------------------------------------------------------
}

    // sort a word array...
    Sub BubbleSort(ByRef pArray() As Word)
       Dim SwapOccured As Boolean
       Dim index As Byte
       Dim SwapTemp As Word
       Repeat
          SwapOccured = false
          index = 0
          Repeat
             If pArray(index) > pArray(index + 1) Then
                SwapTemp = pArray(index)
                pArray(index) = pArray(index + 1)
                pArray(index + 1) = SwapTemp
                SwapOccured = true
             EndIf
             Inc(index)
           Until index = Bound(pArray)
       Until Not SwapOccured
    End Sub

    // Get the median of an array
    Function GetMedian(ByRef pSamples() As Word) As Word
       Dim index As Byte
       BubbleSort(pSamples)
       result = pSamples(Bound(pSamples) / 2)
    End Function

    // Perform the Stein Hart linearization taking into account the thermistors characteristics
    Function SteinHart(pValue As Float) As Float
        Const T25Val = 0.0033540                    // Thermistor's t25 value
        Const ThermistorBVal = 1.0 / 3489.0         // Thermistor's B value
        Dim  LogValue As Float

        LogValue = log(pValue / 10000)              // Calculate the log
        Result = ThermistorBVal * LogValue + T25Val  // linearize using the stein-hart algorithm
    End Function

//-----------------------------------------------------------------

    Const SymDegree(8) As Byte = ($06,$09,$09,$06,0,0,0,0) // Data for deg symbol in cgram char 0


    Dim SampleArray(20) As Word
    Dim TempF As Float
    Dim Temperature As Float
    Dim index As Byte
    Dim Resistance As Float
    Dim ThermistorValue As Word
    Const Quanta = 5000.0 / 1024.0                 // Quantizing constant for ADC reading to Voltage calculation

    ADCON1 = $07                                   // PORTE as digital (LCD)
    TRISA.0 = 1                                    // configure AN0 as an input
    ADCON1.7 = 1                                   // set analogue input on PORTA.0

    DelayMS(200)

    LCD.WriteItem(SymDegree)                       // Write the custom char data to the LCD

    While 1 = 1

        For index = 0 To Bound(SampleArray)
            SampleArray(index) = ADC.Read(0)       // Take 20 samples and store them in the array 
        Next
        ThermistorValue = GetMedian(SampleArray)   // Then get the median of the array

        Temperature = ThermistorValue * Quanta     // Work out the voltage
        TempF = 5000 - Temperature                 // Find the resistance across the thermistor

        Resistance = (Temperature * 10000) / TempF
        Temperature = SteinHart(Resistance)        // linearize with the Stein Hart calculation

        Temperature = (1 / Temperature) - 273.15   // Convert from Kelvin To Centigrade

        LCD.Cls

        LCD.WriteAt(1,1, FloatToStr(Temperature),0,"C ")

        DelayMS(500)                               // Delay 500ms

    Wend

    End


wsxwsx

Alıntı yapılan: "maxiboost"
hımm peki hesap doğrumu ?
Ln(44190) = 10.69 ?
evet öyle çıkıyor
Log(44190) = 4.64532

Murat Mert

Herkeze birşeyler katmaya çalıştığı için teşkkürler.
mert07