Temperature Sensor (DS18S20 + PIC16F877A)

Here's a temperature sensor (thermometer) circuit that you can easily build. It uses the popular PIC 16F877A microcontroller. The temperature sensor is DS18S20. The DS18S20 communicates through the one-wire protocol. The PIC16F877A communicates with the DS18S20 with the one-wire protocol and gets the information for the temperature and displays it on the LCD.

The temperature range of this circuit is -55'C to +125'C.

The methods of communicating with the DS18S20 and sending/receiving commands, and reading the temperature value,  are all explained in the DS18S20 datasheet (datasheets.maximintegrated.com/en/ds/DS18S20.pdf).





Here is the code for the PIC16F877A:
(You can download the source file from: https://rapidshare.com/files/1817975964/DS18S20PIC16F877A.c)
--------------------------------------------------------------------------------------------------------------
//Programmer: Syed Tahmid Mahbub
//Compiler: mikroC PRO for PIC v4.60
//Target PIC: PIC16F877A
--------------------------------------------------------------------------------------------------------------

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

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

unsigned char TempH;
unsigned char TempL;
unsigned char TLow;
unsigned char vDisp[9];
unsigned char DP;

void main() {
     PORTB = 0;
     TRISB = 0;
     LCD_Init();
     LCD_CMD(_LCD_CURSOR_OFF);
     LCD_CMD(_LCD_CLEAR);
     PORTD = 0;
     TRISD = 0x01;
     delay_ms(200); //Wait for sensor and LCD to stabilize
     //vDisp = "+124.5 'C"
     vDisp[4] = '.';
     vDisp[7] = 39; // '
     vDisp[8] = 'C';
     LCD_Out(1,1, "Temp:");
     while (1){
         OW_Reset(&PORTD, 0); // 'Reset command to initialize One-Wire
         OW_Write(&PORTD, 0, 0xCC); // 'Skip ROM Command
         OW_Write(&PORTD, 0, 0x44); // 'Convert_T command
         delay_ms(800); // 'Provide delay for conversion
         RD7_bit = ~RD7_bit;
         OW_Reset(&PORTD, 0); // 'Reset command to initialize One-Wire
         OW_Write(&PORTD, 0, 0xCC); // 'Skip ROM Command
         OW_Write(&PORTD, 0, 0xBE); // 'Read Scratchpad Command
         TempL = OW_Read(&PORTD,0); //Read Temperature low byte
         TempH = OW_Read(&PORTD,0); //Read Temperature high byte
         DP = TempL & 0x01; // 'Check if Temperature is integer or fractional
         if (TempH){ //If reading is negative
            vDisp[0] = '-';
            TempL = ((~TempL) + 1) >> 1;
         }
         else{
             vDisp[0] = '+';
             TempL = TempL >> 1; // 'Shift one position right (divide by 2) to get integer reading and get rid of decimal point
         }
         vDisp[1] = (TempL / 100) + 48; // 'Get hundreds and convert to ASCII
         vDisp[2] = ((TempL / 10) % 10) + 48; // 'Get tens and convert to ASCII
         vDisp[3] = (TempL % 10) + 48; // 'Get units and convert to ASCII
         if (DP){ // 'If reading is fractional, ie has 0.5 at end
            vDisp[5] = '5';
         }
         else{ // 'If reading is a whole number
            vDisp[5] = '0';
         }
         Lcd_Chr(1,8, vDisp[0]);
         Lcd_Chr(1,9, vDisp[1]);
         Lcd_Chr(1,10, vDisp[2]);
         Lcd_Chr(1,11, vDisp[3]);
         Lcd_Chr(1,12, vDisp[4]);
         Lcd_Chr(1,13, vDisp[5]);
         Lcd_Chr(1,14, vDisp[6]);
         Lcd_Chr(1,15, vDisp[7]);
         Lcd_Chr(1,16, vDisp[8]);
     }
}
--------------------------------------------------------------------------------------------------------------
Reference documents:

DS18S20 datasheet: datasheets.maximintegrated.com/en/ds/DS18S20.pdf
PIC16F877A datasheet: ww1.microchip.com/downloads/en/devicedoc/39582b.pdf
mikroC LCD library: http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/lcd_library.htm
mikroC One-Wire library: http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/onewire_library.htm

Comments

Popular posts from this blog

Using the TLP250 Isolated MOSFET Driver - Explanation and Example Circuits

N-Channel MOSFET High-Side Drive: When, Why and How?

Using the high-low side driver IR2110 - explanation and plenty of example circuits