PDA

View Full Version : Thermistor based temperature reading short code required



asifiqbal
- 9th November 2014, 10:04
I am new to pbp and i have created this 10k thermistor based temrature monitor on my own and it is working very fine without any problem, but my code is very long and takes a lot of memory, is there any alternative way write this code in short form

'i have taken thermister readings manually from -20c to 57c and
'result is stored as 8 bit values
'circuit is simple 16f877A


' 0.25 watt10k resistor 10k thermistor
' to ground---/\/\/\-----to An2-----/\/\/\---------to +5v


CLEAR
DEFINE OSC 4
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 1
DEFINE LCD_LINES 2
DEFINE LCD_BITS 4
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50


Low porte.2
pause 500


DEFINE ADC_BITS 8
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
trise=0
TRISA = %11111111
TRISD = %00000000
ADCON1 = %00000010 'set port a ANALOG

t vAR word 'create to read thermistor 8 bit value
x var word ' to show result from 0 to 57 C


main: 'this loop is to read from 0 to 57c because pbp dont show
' result in minus values
adcin 2,t
if t=<63 then gosub minus
if t => 64 and t=<65 then
x=0
endif


if t => 66 and t=< 67 then
x = 1
ENDIF


if t => 68 and t=< 70 then
x = 2
ENDIF


if t => 71 and t=< 72 then
x = 3
ENDIF


if t => 73 and t=< 74 then
x = 4
ENDIF


if t => 75 and t=< 77 then
x = 5
ENDIF


if t => 78 and t=< 79 then
x = 6
ENDIF


if t => 80 and t=< 82 then
x = 7
ENDIF


if t => 83 and t=< 85 then
x = 8
ENDIF


if t => 86 and t=< 87 then
x = 9
ENDIF


if t => 88 and t=< 90 then
x = 10
ENDIF


if t => 91 and t=< 92 then
x = 11
ENDIF


if t => 93 and t=< 95 then
x = 12
ENDIF


if t => 96 and t=< 97 then
x = 13
ENDIF


if t => 98 and t=< 100 then
x = 14
ENDIF


if t => 101 and t=< 102 then
x = 15
ENDIF


if t => 103 and t=< 105 then
x = 16
ENDIF


if t => 106 and t=< 108 then
x = 17
ENDIF


if t => 109 and t=< 110 then
x = 18
ENDIF


if t => 111 and t=< 113 then
x = 19
ENDIF


if t => 114 and t=< 116 then
x = 20
ENDIF


if t => 117 and t=< 118 then
x = 21
ENDIF


if t => 119 and t=< 120 then
x = 22
ENDIF


if t => 121 and t=< 123 then
x = 23
ENDIF


if t => 124 and t=< 126 then
x = 24
ENDIF


if t => 127 and t=< 129 then
x = 25
ENDIF


if t => 130 and t=< 131 then
x = 26
ENDIF


if t => 132 and t=< 134 then
x = 27
ENDIF


if t => 135 and t=< 136 then
x = 28
ENDIF


if t => 137 and t=< 139 then
x = 29
ENDIF


if t => 140 and t=< 141 then
x = 30
ENDIF


if t => 142 and t=< 144 then
x = 31
ENDIF


if t => 145 and t=< 146 then
x = 32
ENDIF


if t => 147 and t=< 149 then
x = 33
ENDIF


if t => 150 and t=< 151 then
x = 34
ENDIF


if t => 152 and t=< 153 then
x = 35
ENDIF


if t => 154 and t=< 156 then
x = 36
ENDIF


if t => 157 and t=< 158 then
x = 37
ENDIF


if t => 159 and t=< 160 then
x = 38
ENDIF


if t => 161 and t=< 163 then
x = 39
ENDIF


if t => 164 and t=< 165 then
x = 40
ENDIF


if t => 166 and t=< 167 then
x = 41
ENDIF


if t => 168 and t=< 169 then
x = 42
ENDIF


if t => 170 and t=< 171 then
x = 43
ENDIF


if t => 172 and t=< 173 then
x = 44
ENDIF


if t => 174 and t=< 175 then
x = 45
ENDIF


if t => 176 and t=< 177 then
x = 46
ENDIF


if t => 178 and t=< 179 then
x = 47
ENDIF


if t => 180 and t=< 181 then
x = 48
ENDIF


if t => 182 and t=< 183 then
x = 49
ENDIF


if t => 184 and t=< 185 then
x = 50
ENDIF


if t => 186 and t=< 187 then
x = 51
ENDIF


if t = 188 then
x = 52
ENDIF


if t => 189 and t=< 190 then
x =53
ENDIF


if t => 191 and t=< 192 then
x = 54
ENDIF


if t = 193 then
x = 55
ENDIF


if t = 194 then
x = 56
ENDIF


if t = 195 then
x = 57
ENDIF
if t> 195 then
goto outofrange


endif


lcdout $fe,1
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE ",DEC2 X,"c"
pause 100
goto main


outofrange:
adcin 2,t
if t < 196 then
goto main
endif
lcdout $fe,1
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "out of range"
pause 100
goto outofrange




minus: 'this loop is created to show minus values
pause 100
adcin 2, t
if t=> 64 then goto main


if t=>60 and t =<63 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -01c"
endif


if t=>57 and t =<59 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -02c"
endif


if t=>55 and t =<56 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -03c"
endif


if t=>53 and t =<54 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -04c"
endif


if t=>51 and t =<52 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -05c"
endif
if t=50 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -06c"
endif
if t=>48 and t =<49 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -07c"
endif
if t=>46 and t =<47 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -08c"
endif
if t=>44 and t =<45 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -09c"
endif
if t=>42 and t =<43 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -10c"
endif
if t=>40 and t =<41 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -11c"
endif
if t=>38 and t =<39 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -12c"
endif
if t=37 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -13c"
endif
if t=36 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -14c"
endif
if t=>34 and t =<35 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -15c"
endif
if t=>32 and t =<33 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -16c"
endif
if t=31 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -17c"
endif
if t=30 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -18c"
endif
if t=>28 and t =<29 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -19c"
endif
if t=>26 and t =<27 then
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE -20c"
endif
if t <26 then
lcdout $fe,1
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "out of range"
endif
goto minus
end

Amoque
- 9th November 2014, 12:18
I applaud your effort! It is inspiring to see people first work it out and then come looking to learn how to do it better. Thank you for posting.

Ideally, one would design the circuit to have a particular voltage change per degree. Say... 10mV/degree for example. By doing this, calculating the temperature from the input voltage (ADC value) is a very simple calculation - something like TEMPERATURE = (ADC_VALUE - NEGATIVE_TEMPERATURE_OFFSET) / mV_PER_DEGREE. It may be that this approach will work with your thermistor, but you would need examine the datasheet and post that information - or at least post to say which thermistor you are using so that someone here can look at that data. Of course, then you would only need to put "T" in the formula and get TEMPERATURE out for any temperature value.

Another approach, presuming you have no datasheet perhaps, is to do something similar yourself. For example: If, when T is between 60 and 102, the temperature is always T/2 - 32 and when T is between 103 and 196, the temperature is T/3 - 10, then it is possible to use far fewer IF/ THEN statements and still get accurate results. You will only need to determine which range T falls in and then (like above) apply the formula to your value to retrieve the correct temperature.

The last method in common practice is that which you've chosen - a "lookup" method, where the sensor value is read, then substituted with the correct temperature. PicBasic has a function to do this: LOOKUP:

LOOKUP Index,[Constant{,Constant...}], Var 'From the manual

In your case, it might look like: LOOKUP T-26 [-20,-20,-19,-19...] TEMPERATURE. Lookups like this can be very useful for translating unrelated data to appropriate output, but are tedious and memory intensive to use, so typically are to be avoided or at least abbreviated if at all possible. You might, for example, use a combination of the previous method and this one - using different, shorter, lookups to determine temperature from a formula result that provides fewer data points. If there is no way to reduce the number of data points, then perhaps you can reduce the amount of program memory used by storing the T value in EEPROM and then reading the temperature back from an offset position As:

DATA @ 0, 26, 27, 28...
DATA @ 100, -20, -20, -19...

So that you READ one value to find T, then add an offset to READ the temperature.

In PicBasic... in electronics... there are always several means to get to the same goal. The opportunity to follow your own path is the benefit of not just buying a thermometer and being done.

Acetronics2
- 9th November 2014, 16:22
Hi,

as T is always positive, and outputted values are 1,2,3 ....

A close look to LOOKDOWN2 command might be more than useful ...

Just my two cents

Alain

asifiqbal
- 10th November 2014, 12:57
thermitor value is 10k,and i am loading datasheet also,the problem is that value of thermistor does not change with same proportion with every c degree

Acetronics2
- 10th November 2014, 13:28
Oh ...

and I forgot it will be quite the same thing for negative temps ( using LOOKDOWN2 ) ... just adding a LOOKUP command to translate from indexes to true temp !!!

Alain

Amoque
- 11th November 2014, 09:58
thermitor value is 10k, and i am loading datasheet also,the problem is that value of thermistor does not change with same proportion with every c degree

You are, precisely, correct; however, the curve of resistance values is very close to a logarithmic curve and this may be precise enough - provided you can easily implement a log function. I do not know of a method to do this, so it may be that one of the other two methods, or Alain's suggestion of using LOOKDOWN2, may be better for your purpose - or perhaps you someone in the forum will know of a way. Or, it may be that this method is not accurate enough for your purpose.

The point is that always there are these types of issues to solve and these choices to make. If you are trying to minimize resources used, then one answer may be better, if you are optimizing for accuracy another approach may meet your need... there is no "best" way and no "perfect" answer. Look at the three general methods I have suggested, weight their relative merit in your application - does the PIC you're using have EEPROM? How much? Are you using it for something else or is it available for this task? It is clear from your OP that you have put a great deal of work into making this work - it is with the greatest of respect for this effort that I offer you these choices rather than dictate how I would complete MY project.

All that said...

If I was to do this and I had determined that my EEPROM was available, and I needed the accuracy of precise, stored values, then I would write the corresponding TEMPERATURE value to the EEPROM location of each ADC reading. If the ADC reading for -20 Celsius is 26 and the reading for -19 is 27... DATA @ 26, -20, -19; I would continue in this manner (duplicating temperature readings where necessary to maintain the pattern). Then, I would read the DATA location of the ADC value, like so:

ADCIN 1, ADC
READ ADC, TEMP

I would then write a subroutine to display the information:

Gosub DISPLAY_LCD

and wrap the subroutine in a label and return:

DISPLAY_LCD:
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE: ", DEC TEMP, 223, " C" 'ASCII 223 is DEGREE SYMBOL
RETURN

and then put all this in a loop, so that it displayed continuously every second:

MAIN:
ADCIN 1, ADC
READ ADC, TEMP
Gosub DISPLAY_LCD
PAUSE 1000
GOTO MAIN

DISPLAY_LCD:
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE: ", DEC TEMP, 223, " C" 'ASCII 223 is DEGREE SYMBOL
RETURN

DATA @ 26, -20, -19...

END

I'd then go back and add some more code to handle out of range values...

MAIN:
ADCIN 1, ADC
READ ADC, TEMP
IF ADC < 26 then GOTO MAIN 'LEAVE DISPLAY ALONE IF ITS TOO COLD - JUST KEEP READING
IF ADC > 25 and ADC < 196 THEN Gosub DISPLAY_LCD 'FOR NORMAL VALUES
IF ADC > 195 GOSUB DISPLAY_HOT 'FOR OVER RANGE
PAUSE 1000
GOTO MAIN

DISPLAY_LCD:
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "TEMPRATURE: ", DEC TEMP, 223, " C" 'ASCII 223 is DEGREE SYMBOL
RETURN

DISPLAY_HOT:
lcdout $fe,$80, "SENSOR ",dec3 t
lcdout $FE,$C0, "HOLY COW IS IT HOT IN HERE OR WHAT?"
RETURN

DATA @ 26, -20, -19...

END

Last, I think I'd double check my negative values to make sure they display correctly, then determine how to fix them.

asifiqbal
- 12th November 2014, 08:18
thankyou,amaque, i m really greatful to u