Thursday, September 7, 2017

PIC12F1822 + 1602 LCD + LM335 Temperature Sensor


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 data.
This topic shows how to build a thermometer using PIC12F1822 microcontroller and LM335 analog temperature 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. For example if the LM335 output voltage is equal to 3.03 (3030 mV) that means the temperature is: 303 Kelvin = 30 °Celsius.
The PIC12F1822 is an 8-bit microcontroller which has 4 analog channels with 10-bit resolution. The good thing with this microcontroller is the fixed voltage reference. With the fixed voltage reference we get approximately an exact result. Normally negative and positive references of the ADC module are VSS and VDD, but VDD is not exactly equal to 5.00V and here we should use the fixed voltage reference as a positive reference of the ADC module.
The PIC12F1822 has 3 fixed voltage references: 1.024V, 2.048V and 4.096V. For example if we set the fixed voltage reference to 4.096V and the ADC module is configured so that the negative and the positive references are VSS and FVR (Fixed Voltage Reference) respectively, in this case the equivalent 10-bit digital value of 4.096 is 1023 and 3.00V is 3.00 * 1023/4.096 = 749 , and so on.
In this project I used 4.096 because the LM335 output is between 2.23V (temperature = -50°C) and 3.98V (temperature = +125°C).
The temperature values (Kelvin and degree Celsius) are displayed on 1602 LCD display. This LCD is interfaced with the microcontroller using 74HC595 (74HC164 .....) shift register as what was done in this post:
Interfacing PIC12F1822 microcontroller with LCD display
Hardware Required:
  • PIC12F1822 microcontroller
  • LM335 Temperature sensor - datasheet
  • 1602 LCD Screen
  • 74HC595 shift register
  • 10K ohm variable resistor
  • 2.2K ohm resistor
  • +5V Power supply source
  • Breadboard
  • Jumper wires
Interfacing PIC12F1822 with LM335 temperature sensor circuit:
Interfacing PIC12F1822 MCU with LM335 temperature sensor and 1602 LCD circuit
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 (RA0). 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 display pins are connected to 74HC595 shift register except the Enable pin (E) which is connected directly to PIC12F1822. With the help of the shift register 74HC595 the LCD uses only 3 data lines: clock, data and enable. Other types of serial-in parallel-out shift registers can be used such as 74HC164 and CD4094 (74HC4094).
In this example the PIC12F1822 MCU uses its internal oscillator and MCLR pin function is disabled.
Interfacing PIC12F1822 with LM335 temperature sensor C code:
This code was tested with CCS PIC C compiler version 5.051.
To compile the C code below, the serial LCD driver source file must be added to the project just by downloading the source file and putting it on the project folder. The download link of the serial LCD driver is in this post:
3-Wire LCD driver for CCS PIC C compiler
The complete C code is the one below.
/* Thermometer using PIC12F1822 microcontroller and LM335 sensor C code.
   The temperature results (kelvin and degree Celsius) are displayed on
   1602 LCD screen with the help of a shift register (74HC595, 74HC164 ....).
   Serial LCD driver for CCS C must be added to the project.
   http://ccspicc.blogspot.com/
   electronnote@gmail.com
*/

// Serial LCD module connections
#define LCD_DATA_PIN  PIN_A5
#define LCD_CLOCK_PIN PIN_A4
#define LCD_EN_PIN    PIN_A2
// End serial LCD module connections

#include <12F1822.h>
#device ADC = 10
#fuses NOMCLR INTRC_IO PLL_SW
#use delay(clock=32000000)
#use fast_io(A)
#include <3WireLCD.c>                            // 3-wire serial LCD driver source file

char celsius_temp[] = "Temp =  00.0ßC";
char kelvin_temp[]  =      "=  00.0 K";
signed int16 Kelvin, Celsius;
void main() {
  setup_oscillator(OSC_8MHZ | OSC_PLL_ON);       // Set internal oscillator to 8MHz with PLL enabled (32MHz)
  lcd_initialize();                              // Initialize LCD module
  lcd_cmd(LCD_CLEAR);                            // LCD Clear
  setup_vref(VREF_ADC_4v096);                    // Configure FVR to supply ADC positive reference with 4.096V
  setup_adc(ADC_CLOCK_INTERNAL);                 // ADC Module uses its internal oscillator
  setup_adc_ports(sAN0 | VSS_FVR);               // Configure AN0 pin as analog - Voltage reference: VSS - FVR(4.096V)
  set_adc_channel(0);                            // Select channel 0 (AN0)
 while(TRUE){
    delay_ms(1000);
    Kelvin = (read_adc() + 1) * 0.4;             // Read analog voltage and convert it to Kelvin (0.4 = 100*4.096/1024)
    Celsius = Kelvin - 273;                      // Convert Kelvin to degree Celsius
    if(Celsius < 0){
      Celsius = abs(Celsius);                    // Absolute value
      celsius_temp[7] = '-';                     // Put minus '-' sign
    }
    else
      celsius_temp[7]  = ' ';                    // Put space ' '
    if (Celsius > 99)
      celsius_temp[7]  = '1';                    // Put 1 (of hundred)
    celsius_temp[8]  = (Celsius / 10) % 10  + 48;
    celsius_temp[9]  =  Celsius % 10  + 48;
    kelvin_temp[2]   = (Kelvin / 100) % 10 + 48;
    kelvin_temp[3]   = (Kelvin / 10) % 10 + 48;
    kelvin_temp[4]   =  Kelvin % 10 + 48;
    lcd_goto(1, 1);                              // Go to column 1 row 1
    printf(lcd_out, celsius_temp);               // Display Celsius_temp
    lcd_goto(6, 2);                              // Go to column 6 row 2
    printf(lcd_out, kelvin_temp);                // Display kelvin_temp
  }
}
The Result:
A hardware circuit of PIC12F1822 MCU, LCD and LM335 temperature sensor

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
  }
}

Sunday, August 27, 2017

Interfacing PIC16F877A with LM335 analog temperature sensor


The LM335 temperature sensor is an analog device which requires an ADC module to convert the analog data which is the voltage output from the LM335 into digital data. The LM335 has the following features:
  • 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 is for example is 3.03 (3030 mV) that means the temperature is: 303 °Kelvin = 30 °Celsius.
This topic shows how to interface the LM335 temperature sensor with PIC16F877A microcontroller.
Hardware Required:
  • PIC16F877A microcontroller
  • LM335 Temperature sensor - datasheet
  • 16x2 LCD Screen
  • 8MHz crystal
  • 2 x 22pF ceramic capacitor
  • 10K ohm potentiometer or variable resistor
  • 2.2K ohm resistor
  • +5V Power supply source
  • Breadboard
  • Jumper wires
Interfacing PIC16F877A with LM335 temperature sensor circuit:
PIC16F877A with LM335 temperature sensor circuit

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 (16x2) 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 PIC16F877A runs with 8MHz crystal oscillator.
Interfacing PIC16F877A with LM335 sensor CCS C Code:
The following C code was tested with CCS PIC C compiler version 5.051.
/* Interfacing PIC16F877A 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 <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#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_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);
    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
  }
}
Interfacing PIC16F877A with LM335 sensor videos:
The following video shows a breadboard hardware circuit of the example.


and the second video shows simulation using Proteus software.



Tuesday, July 4, 2017

Interfacing PIC16F887 with LM335 temperature sensor



PIC16F887 + LM335 sensor brotoboard hardware circuit
This is an example showing how to connect LM335 temperature sensing device with PIC16F887 microcontroller.
The LM335 is an analog device which requires an ADC module to convert the analog data which is the voltage output from the LM335 into digital data. The LM335 has the following features:
  • 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 is for example is 3.03 (3030 mV) that means the temperature is: 303 °Kelvin = 30 °Celsius.
Hardware Required:
  • PIC16F887 Microcontroller
  • LM335 Temperature sensor
  • 16x2 LCD Screen
  • 10K ohm potentiometer or variable resistor
  • 2.2K ohm resistor
  • 0.1µF Ceramic capacitor (optional)
  • +5V Power supply source
  • Breadboard
  • Jumper wires
Interfacing PIC16F887 with LM335 sensor circuit:
This is our example circuit where the microcontroller uses its internal oscillator.
The LM335 has 3 pins:
Pin 1 for calibration, not used in this example
Pin 2: output
Pin 3: GND (ground)
PIC16F887 microcontroller + LM335 temperature sensor device circuit diagram
Interfacing PIC16F887 with LM335 C code:
The C code used in this example is as the one below where it has been compiled with CCS PIC C compiler version 5.051.
/* Interfacing PIC16F887 with LM335 analog temperature sensor CCS C code
   Read LM335 datasheet to understand the code!
   Internal oscillator used @ 8MHz
   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 <16F887.h>
#fuses NOMCLR NOBROWNOUT NOLVP 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 the internal oscillator to 8MHz
  setup_adc(ADC_CLOCK_INTERNAL);                 // ADC Module uses its internal oscillator
  setup_adc_ports(sAN0);                         // 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);
    Kelvin = read_adc() * 0.489;                 // Rea 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
  }
}
The following video shows Proteus simulation of LM335 and PIC16F887:


Proteus simulation file can be downloaded from this link:
PIC16F887 + LM335 - Proteus

Reference:
LM335 Datasheet