All About Circuits Forum  

Go Back   All About Circuits Forum > Software, Microcomputing, and Communications Forums > Embedded Systems and Microcontrollers

Notices

Embedded Systems and Microcontrollers Discussion forum for projects and working with embedded systems and microcontrollers (FPGAs, PICs, AVRs). Get help with hardware issues and embedded programming.

Reply   Post New Thread
 
Thread Tools Display Modes
  #1  
Old 03-30-2010, 02:23 AM
corsair corsair is offline
Member
 
Join Date: Mar 2010
Posts: 51
Talking Programming a Temperature Sensor using a PIC18F4550

I'd like to program a Temperature Sensor using the PIC18F4550, but I'm not sure how to start. For the moment, I am using a 10k Ohm pot to try to calibrate it. The Temperature Sensor that I am using is the LM335Z:
http://www.national.com/ds/LM/LM135.pdf

As I move the potentiometer from one end to the other, in ADRESH/ADRESL
I get values that range from 0x000 to 0x3FF. I understand that this is the voltage.

My first approach was to go into the datasheet and program every value. For example, values < 0x156 = -40*C, values > 0x1C6 = 100*C (since these are the max values), then program brackets. 0x157 = -39*C, 0x156 = -37*C, etc.

If I approached it this way, I would be killing myself going through all those values, especially if I found out the part is a little off or I need to change sensors or something.

I read somewhere on this forum:
Quote:
This simple device output 10mV/C. Feed this signal to one input of the comparator. The other input can be derived from a resistor network to provide the voltage for comparison.
This looks like something that applies to me, but I don't fully understand it, let alone try to program this in assembly.
Reply With Quote
  #2  
Old 03-30-2010, 04:15 AM
retched's Avatar
retched retched is offline
Senior Member
 
Join Date: Dec 2009
Location: Baltimore, MD
Posts: 5,198
Blog Entries: 14
Default

You can use an analog input on your pic and it will read the output from the temperature sensor.


If the temp in your room is 25*C, the input on the analog pin will be 250mv.

Simply divide the input by 10 to display the temperature.
__________________
-rm-
Reply With Quote
The Following User Says Thank You to retched For This Useful Post:
corsair (03-31-2010)
  #3  
Old 03-30-2010, 12:01 PM
Markd77's Avatar
Markd77 Markd77 is offline
Senior Member
 
Join Date: Sep 2009
Location: Birmingham
Posts: 2,784
Blog Entries: 1
Default

Not quite, it is an absolute Kelvin (K) scale.
0V output = 0K = -273.15C
10mV per degree C (or K) - means output at 0C (273.15K) = 273.15*10= 2731.5mv =2.7315V

Output at 25 degrees C (273.15+25=298.15K) = 298.15*10 = 2981.5mV = 2.9815V


To get the answer in degrees C, subtract the ADC result you should get at 0C from the ADC result, then:

The ADC range = 0-1023 (3FFh) for 5V
Each volt = 100 degrees C
Temp(K)= ADCresult /1023*5*100
= ADCresult * 0.4888

Temp(C) = (ADCresult - (2.73/5*1023)) *0.4888
= (ADCresult - 559) * 0.4888
Reply With Quote
The Following User Says Thank You to Markd77 For This Useful Post:
corsair (03-31-2010)
  #4  
Old 03-30-2010, 12:05 PM
Markd77's Avatar
Markd77 Markd77 is offline
Senior Member
 
Join Date: Sep 2009
Location: Birmingham
Posts: 2,784
Blog Entries: 1
Default

use this to generate code to multiply by 0.4888
I'm not sure if the generated code will work for negative temperatures - you could use the temp(K) result and then subtract 273 afterwards.

http://www.piclist.com/techref/picli...onstdivmul.htm
Reply With Quote
The Following User Says Thank You to Markd77 For This Useful Post:
corsair (03-31-2010)
  #5  
Old 03-30-2010, 12:29 PM
corsair corsair is offline
Member
 
Join Date: Mar 2010
Posts: 51
Default

Thanks very much guys, I'll work on it later tonight and let you know how it works =)
Reply With Quote
  #6  
Old 03-30-2010, 12:35 PM
retched's Avatar
retched retched is offline
Senior Member
 
Join Date: Dec 2009
Location: Baltimore, MD
Posts: 5,198
Blog Entries: 14
Default

Quote:
Not quite, it is an absolute Kelvin (K) scale.
0V output = 0K = -273.15C
10mV per degree C (or K) - means output at 0C (273.15K) = 273.15*10= 2731.5mv =2.7315V

Output at 25 degrees C (273.15+25=298.15K) = 298.15*10 = 2981.5mV = 2.9815V
You are correct. I never did like that kelvin kid...
__________________
-rm-
Reply With Quote
The Following User Says Thank You to retched For This Useful Post:
corsair (03-31-2010)
  #7  
Old 03-30-2010, 02:40 PM
Markd77's Avatar
Markd77 Markd77 is offline
Senior Member
 
Join Date: Sep 2009
Location: Birmingham
Posts: 2,784
Blog Entries: 1
Default

A further point is that this is only as accurate as your 5V power supply to the PIC.
If your power supply is 4.9V then the result would be 6 degrees lower at room temperature.

Last edited by Markd77; 03-30-2010 at 02:42 PM. Reason: added at room temperature.
Reply With Quote
The Following User Says Thank You to Markd77 For This Useful Post:
corsair (03-31-2010)
  #8  
Old 03-30-2010, 06:33 PM
Tahmid's Avatar
Tahmid Tahmid is offline
Senior Member
 
Join Date: Jul 2008
Location: Cornell University, Ithaca, New York, USA (from Dhaka, Bangladesh)
Posts: 344
Blog Entries: 7
Default

Hi corsair,
I have a similar project made with 18F452 with LM35. This may come to help you.
Here's the code in mikroBASIC:
Code:
program thermometer452

dim LCD_RS as sbit at RB4_bit
    LCD_EN as sbit at RB5_bit
    LCD_D4 as sbit at RB0_bit
    LCD_D5 as sbit at RB1_bit
    LCD_D6 as sbit at RB2_bit
    LCD_D7 as sbit at RB3_bit

    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit

dim ADCResult as longword
dim value as word[3]
dim vstring as string[3]

sub procedure GlobInit
    TRISB = 0
    PORTB = 0
    TRISA = 1
    ADCON1 = $4E
    LCD_Init
    LCD_Cmd(_LCD_CLEAR)
    LCD_Cmd(_LCD_CURSOR_OFF)
    LCD_Out(1, 1, "Temp:")
    LCD_Out(1, 15, "'C")
end sub

main:
     GlobInit
     while true
           ADCResult = (ADC_Read(0) * 500) >> 10
           value[0] = ADCResult div 100
           value[1] = (ADCResult div 10) mod 10
           value[2] = ADCResult mod 10
           vstring[0] = value[0] + 48
           vstring[1] = value[1] + 48
           vstring[2] = value[2] + 48
           LCD_Out(1, 10, vstring)
           delay_ms(50)
     wend
end.
Select All
mikroC(v8.20):
Code:
unsigned long ADCResult;
unsigned int value[3];
char vstring[3];

void GlobInit(void){
    TRISB = 0;
    PORTB = 0;
    TRISA = 1;
    ADCON1 = 0x4E;
    LCD_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0);
    LCD_Cmd(LCD_CLEAR);
    LCD_Cmd(LCD_CURSOR_OFF);
    LCD_Out(1, 1, "Temp:");
    LCD_Out(1, 15, "'C");
}

void main(){
    GlobInit();
    while (1){
          ADCResult = (ADC_Read(0) * 500) >> 10;
          value[0] = ADCResult / 100;
          value[1] = (ADCResult / 10) % 10;
          value[2] = ADCResult % 10;
          vstring[0] = value[0] + 48;
          vstring[1] = value[1] + 48;
          vstring[2] = value[2] + 48;
          LCD_Out(1, 10, vstring);
          delay_ms(50);
    }
}
Select All
Hope this helps.
Tahmid.
Attached Images
File Type: jpg circuit.jpg (33.4 KB, 60 views)
__________________
পৃথিবীর সর্বোচ্চ দালানও প্রথম ইট বসানো থেকেই তৈরি হয়েছে।
The tallest building in the world starts from the first brick.
Reply With Quote
The Following User Says Thank You to Tahmid For This Useful Post:
corsair (03-31-2010)
  #9  
Old 03-30-2010, 11:20 PM
corsair corsair is offline
Member
 
Join Date: Mar 2010
Posts: 51
Default

I am using a 3.3 voltage regulator, and i measured it and it looks pretty consistent at 3.3.

Tahmid, I have a question about your ADC result. Why are you adding 48?

The value[0],value[1],value[2] are the digits that are to be displayed, correct?
Reply With Quote
  #10  
Old 03-30-2010, 11:35 PM
Markd77's Avatar
Markd77 Markd77 is offline
Senior Member
 
Join Date: Sep 2009
Location: Birmingham
Posts: 2,784
Blog Entries: 1
Default

At 3.3V a recalcualtion is required:

Temp(K)= ADCresult /1023*3.3*100
= ADCresult * 0.3226

Temp(C) = (ADCresult - (2.73/3.3*1023)) *0.3226
= (ADCresult - 846) * 0.3226

Maximum temperature measurable will be 57 degrees C (330K) because 330K gives 3.3V
Reply With Quote
The Following User Says Thank You to Markd77 For This Useful Post:
corsair (03-31-2010)
Reply   Post New Thread

Tags
, , ,


Related Site Pages
Section Title
Worksheet Flip-flop circuits
Worksheet Nonlinear opamp circuits
Worksheet Linear computational circuitry
Worksheet Negative feedback opamp circuits
Worksheet Class A BJT amplifiers
Worksheet Regulated power sources
Worksheet Time constant circuits
Textbook Look-up tables : Principles Of Digital Computing
Worksheet Temperature coefficient of resistance
Textbook Transistor ratings and packages : Bipolar Junction Transistors


Similar Threads
Thread Thread Starter Forum Replies Last Post
Basic temperature control project ronnierohan007 Homework Help 5 11-27-2009 10:41 PM

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 03:30 PM.


User-posted content, unless source quoted, is licensed under a Creative Commons Public Domain License.
Powered by vBulletin
Copyright ©2000 - 2014, vBulletin Solutions, Inc.