DS18S20 interfacing with pic and avr microcontroller



In this article you will learn how to interface temperature sensor DS18S20 with PIC16F877A microcontroller and atmega88 avr microcontroller. Complete interfacing circuit diagram and code for both PIC microcntroller and AVR microcontroller. DS18S20 interfacing with pic code is written using Mikro C for pic. Code for AVR microcontroller is written using Mikro basic complier for avr. Let’s start with basic introduction of DS18S20 digital thermometer.



DS18S20 digital thermometer

DS18S20 is  9- bit digital thermometer which is used to measure celsius tempertaure. DS18S20 also have fuction of alaram with non-volatile user programmed points. It communicates with microcontrollers with only one wire. So it works with one wire communication protocol. It requires only one data line for communication. It can also be powered from data line. It remove the need of external power supply. Each DS18S20 have unique 32 bit address. Therefore it is  easy to interface multiple DS18S20’s with microcontroller.

DS18S20 applications

It have many applications. Some major applications are given below.



  • industrial temperature controller
  • buildings temperature controller
  • digital thermometers

DS18S20  features

It have following major features as compared to other digital thermometers:

  • one wire interfacing with microcontroller i.e. only one wire is required for data
  • alarm setting if temperature is outside permissible limits
  • Multiple devices can be interfaced with same microcotroller due to unique 64 bit address
  • Maximum accuracy
  • It can read temperature from -55°C to +125°C
  • No need of external components. It is ready to use by interfacing with microcontroller

DS18S20 pin configuration

It is available in 3 pin TO-92 package and 8 pin SO package as shown in figure below:

ds18s20 pin configuration

ds18s20 pin configuration

We are using 3 pin ds18s20 package in this tutorial.  Brief description of all the pins is given below:

  1. Number 1 : ground pin
  2. number 2: Data input and output pin. It is open drain one wire interfaced pin. It is also used for powered DS18S20.
  3. number 3:  5 volt power supply if not used in parasite power mode. if parasite power mode is used, it must be grounded

DS18s20 interfacing with PIC16F877A microcontroller

Circuit diagram for interfacing of DS18S20 is shown below. It is not used in parasite power mode. Therefore 5 volt power is connected externally.  DS18S20 is interfaced with pin zero of port D. PORT D pin zero is used for one wire communication with digital thermometer.  16 ×2 LCD is used to display temperature. LCD interfacing with pic microcontroller is used to display temperature.

DS18S20 interfacing with pic microcontroller

DS18S20 interfacing with pic microcontroller

DS18S20 interfacing with pic code

Code for this project is written using Mikro C pro for pic.

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_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]);
 }
}

DS18s20 temperature sensor interfacing with avr microcontroller

Interfacing circuit diagram is shown below. Lcd interfacing with avr microcontroller is done to display temperature on lcd.

DS18S20 interfacing with avr microcontroller

DS18S20 interfacing with avr microcontroller

Code for ds18s20 with avr microcontroller

Code for this project is written using Mikro C basic for avr.

dim LCD_RS as sbit at PORTB2_bit
dim LCD_EN as sbit at PORTB3_bit
dim LCD_D4 as sbit at PORTB4_bit
dim LCD_D5 as sbit at PORTB5_bit
dim LCD_D6 as sbit at PORTB6_bit
dim LCD_D7 as sbit at PORTB7_bit

dim LCD_RS_Direction as sbit at DDB2_bit
dim LCD_EN_Direction as sbit at DDB3_bit
dim LCD_D4_Direction as sbit at DDB4_bit
dim LCD_D5_Direction as sbit at DDB5_bit
dim LCD_D6_Direction as sbit at DDB6_bit
dim LCD_D7_Direction as sbit at DDB7_bit


sub procedure ConversionDelay()
    delay_ms(800)
end sub

sub procedure StabilizeDelay()
    delay_ms(200)
end sub

dim Temperature as word
dim TempH as byte
dim TempL as byte
dim TLow as byte
dim vDisp as string[9]
dim DecimalPoint as byte

main:
     DDRC = $FE 'RC0 input for One-Wire
     LCD_Init()
     LCD_Cmd(_LCD_CURSOR_OFF) 'LCD Cursor off
     LCD_Cmd(_LCD_CLEAR) 'Clear LCD
     StabilizeDelay() 'Wait for sensor and LCD to stabilize
     vDisp = "+124.5 'C"
     LCD_Out(1, 1, "Temp:")
     while true
         OW_Reset(PORTC, 0) 'Reset command to initialize One-Wire
         OW_Write(PORTC, 0, $CC) 'Skip ROM Command
         OW_Write(PORTC, 0, $44) 'Convert_T command
         ConversionDelay() 'Provide delay for conversion
         OW_Reset(PORTC, 0) 'Reset command to initialize One-Wire
         OW_Write(PORTC, 0, $CC) 'Skip ROM Command
         OW_Write(PORTC, 0, $BE) 'Read Scratchpad Command
         Temperature = OW_Read(PORTC, 0) 'Read Temperature low byte
         Temperature = Temperature + ((OW_Read(PORTC, 0)) << 8) 'Read Temperature high byte and convert low and high bytes to one 16-bit word
         TempH = Hi(Temperature) 'High 8 bits of Temperature
         TempL = Lo(Temperature) 'Low 8 bits of Temperature
         DecimalPoint = Temperature.B0 'Check if Temperature is integer or fractional
         if (Temperature and $8000) then 'If reading is negative
            vDisp[0] = "-"
            TempL = byte((not TempL + 1) >> 1)
         else 'If reading is positive
            vDisp[0] = "+"
            TempL = TempL >> 1 'Shift one position right (divide by 2) to get integer reading and get rid of decimal point
         end if
         vDisp[1] = TempL div 100 + 48 'Get hundreds and convert to ASCII
         vDisp[2] = (TempL div 10) mod 10 + 48 'Get tens and convert to ASCII
         vDisp[3] = TempL mod 10 + 48 'Get units and convert to ASCII
         if (DecimalPoint) then 'If reading is fractional, ie has 0.5 at end
            vDisp[5] = "5"
         else 'If reading is a whole number
            vDisp[5] = "0"
         end if
         LCD_Out(1, 8, vDisp) 'Show temperature
     wend
end.



4 Comments

  1. Syed Ghufran Hassan July 4, 2015
    • BILAL Malik July 4, 2015
  2. ANICETH February 3, 2016
  3. Ramesh April 18, 2016

Add Comment

Subscribe to our blog to get updates in your email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 1,395 other subscribers