Wednesday, August 30, 2017

PIC18F4550 + LM335 temperature sensor example


Interfacing PIC18F4550 with LM335 analog temperature sensor
As mentioned above, the LM335 is a 3-pin analog device which can measure temperature (converts temperature to analog voltage). This sensor requires an ADC to convert the analog data into digital one. this topic shows how to use PIC18F4550 microcontroller ADC module to measure the ambient temperature using the LM335 sensor.
The LM335 sensor has the following features (from LM335 datasheet):
  • Directly Calibrated to the Kelvin Temperature Scale
  • 1°C Initial Accuracy Available
  • Operates from 400 μA to 5 mA
  • Less than 1-Ω Dynamic Impedance
  • Easily Calibrated
  • Wide Operating Temperature Range
  • 200°C Overrange
  • Low Cost
The LM135 has a breakdown voltage directly proportional to absolute temperature at 10 mV/°K. If the LM335 output voltage for example is 3.03 (3030 mV) that means the temperature is: 303 °Kelvin = 30 °Celsius.
Hardware Required:
  • PIC18F4550 microcontroller
  • LM335 Temperature sensor - datasheet
  • 1602 LCD Screen
  • 10K ohm potentiometer or variable resistor
  • 2.2K ohm resistor
  • +5V Power supply source
  • Breadboard
  • Jumper wires
Interfacing PIC18F4550 with LM335 temperature sensor circuit:
Interfacing PIC18F4550 microcontroller with LM335 temperature sensor
The LM335 sensor has 3 pins (from left to right):
Pin 1 for calibration, not used in this example
Pin 2: output
Pin 3: GND (ground).
The output pin of the LM335 sensor is connected to analog channel 0 (AN0). I chose the 2.2K ohm because as written in the datasheet for optimum accuracy the current flows through the LM335 should be 1mA. For example if the temperature = 27°C, the output will be 3.00V and assume the supply voltage is exactly 5.00V that means the current flows through the sensor is ( 5 - 3)/2.2 = 0.90mA which is good enough. Also the value 2.2K is a standard value and well used.
The 1602 LCD screen is connected to pins RD0~6. The 10K variable resistor is used to adjust the brightness of the screen.
In this example the PIC18F4550 runs with its internal oscillator @ 8MHz and MCLR pin function is disabled.
Interfacing PIC18F4550 with LM335 sensor CCS C Code:
The following C code was tested with CCS PIC C compiler version 5.051.
/* Interfacing PIC18F4550 with LM335 analog temperature sensor CCS C code.
   Read LM335 datasheet to understand the code!
   http://ccspicc.blogspot.com/
   electronnote@gmail.com
*/

//LCD module connections
#define LCD_RS_PIN      PIN_D0
#define LCD_RW_PIN      PIN_D1
#define LCD_ENABLE_PIN  PIN_D2
#define LCD_DATA4       PIN_D3
#define LCD_DATA5       PIN_D4
#define LCD_DATA6       PIN_D5
#define LCD_DATA7       PIN_D6
//End LCD module connections

#include <18F4550.h>
#fuses NOMCLR, INTRC_IO
#device ADC=10
#use delay(clock = 8MHz)
#include <lcd.c>

char message1[] = "Temp =  00.0 C";
char message2[] =      "=  00.0 K";
signed int16 Kelvin, Celsius;
void main(){
  setup_oscillator(OSC_8MHZ);                    // Set internal oscillator to 8MHz
  setup_adc(ADC_CLOCK_INTERNAL);                 // ADC Module uses its internal oscillator
  setup_adc_ports(AN0);                          // Configure AN0 pin as analog
  set_adc_channel(0);                            // Select channel 0 (AN0)
  lcd_init();                                    // Initialize LCD module
  lcd_putc('\f');                                // Clear LCD
  while(TRUE){
    delay_ms(1000);                              // Wait 1 second
    Kelvin = read_adc() * 0.489;                 // Read analog voltage and convert it to Kelvin (0.489 = 500/1023)
    Celsius = Kelvin - 273;                      // Convert Kelvin to degree Celsius
    if(Celsius < 0){
      Celsius = abs(Celsius);                    // Absolute value
      message1[7] = '-';                         // Put minus '-' sign
    }
    else
      message1[7]  = ' ';                        // Put space ' '
    if (Celsius > 99)
      message1[7]  = 1 + 48;                     // Put 1 (of hundred)
    message1[8]  = (Celsius / 10) % 10  + 48;
    message1[9]  =  Celsius % 10  + 48;
    message1[12] = 223;                          // Degree symbol
    message2[2]  = (Kelvin / 100) % 10 + 48;
    message2[3]  = (Kelvin / 10)  % 10 + 48;
    message2[4]  = Kelvin  % 10 + 48;
    lcd_gotoxy(1, 1);                            // Go to column 1 row 1
    printf(lcd_putc, message1);                  // Display message1
    lcd_gotoxy(6, 2);                            // Go to column 6 row 2
    printf(lcd_putc, message2);                  // Display message2
  }
}