PIC16F877 DS18B20 Temperature Sensor Interface

by Marwen Maghrebi

In this article, we explore how to interface the DS18B20 Temperature Sensor with microcontrollers, enabling accurate temperature monitoring for various applications.

PIC16F877 DS18B20 Temperature Sensor Project Overview

Things used in this project

Software apps and online services:

1- MPLAB

2- Proteus 8

Exploring the DS18B20 Temperature Sensor: Interfacing with PIC16F877A for Precise Temperature Measurement

In this project, we will explore how to interface the DS18B20 temperature sensor with a PIC16F877A microcontroller. Temperature sensors like the DS18B20 are essential in a wide variety of applications, from simple environmental monitoring to sophisticated temperature control systems.

DS18B20 Temperature Sensor Overview

The DS18B20 digital thermometer provides temperature readings in Celsius with a selectable resolution from 9 to 12 bits and features an alarm with user-programmable high and low trigger points stored in nonvolatile memory. It communicates using a 1-Wire bus, which requires only one data line and ground for interfacing with a central microprocessor. The DS18B20 can also operate in “parasite power” mode, drawing power from the data line itself, which removes the need for an external power source.

3D Model of DS18B20 Temperature Sensor

Each DS18B20 sensor has a unique 64-bit serial code, enabling multiple sensors to operate on the same 1-Wire bus. This makes it straightforward for a single microprocessor to control multiple DS18B20 sensors distributed across a wide area. This capability is especially useful for applications such as HVAC systems, building temperature monitoring, equipment temperature tracking, and process control systems.

For more details on the DS18B20 sensor and its integration with microcontrollers, please refer to the linked article.

Temperature Monitoring with PIC Microcontroller and DS18B20 Sensor

This code sets up a temperature monitoring system using a PIC microcontroller and a DS18B20 temperature sensor. The microcontroller reads temperature data from the DS18B20 sensor, converts it to a readable format, and displays it on an LCD screen. The program is organized to initialize the sensor, configure the LCD for display, and continuously update the temperature every second.

Configuration and Pin Definitions

This part configures the PIC microcontroller’s system settings and defines key pins for the DS18B20 temperature sensor and the LCD control. These definitions simplify access to pins throughout the code and set up necessary system parameters.

#include <xc.h>          // Include PIC microcontroller library
#include <stdio.h>       // For sprintf function
#include <string.h>      // For string operations

#define _XTAL_FREQ 20000000 // Define crystal frequency for delay calculations

// Configuration bits
#pragma config FOSC = HS     // High-speed oscillator
#pragma config WDTE = OFF    // Watchdog Timer disabled
#pragma config PWRTE = OFF   // Power-up Timer disabled
#pragma config BOREN = OFF   // Brown-out Reset disabled
#pragma config LVP = ON      // Low-Voltage Programming enabled
#pragma config CPD = OFF     // Data EEPROM Code Protection disabled
#pragma config WRT = OFF     // Flash Program Memory Write Protection disabled
#pragma config CP = OFF      // Flash Program Memory Code Protection disabled

// DS18B20 Pin definition
#define DS18B20_PIN PORTBbits.RB1
#define DS18B20_TRIS TRISBbits.TRISB1

// LCD control pins
#define RS PORTCbits.RC0
#define RW PORTCbits.RC1
#define EN PORTCbits.RC2

Global Variables and Function Prototypes

This section includes global variables for storing raw and processed temperature data, as well as function prototypes for the LCD and DS18B20 functions. The function prototypes help with modular code structure, keeping the main program flow clear.

// Global variables for temperature
static signed int raw_temp;   // Stores raw temperature data from sensor
static float temperature;     // Stores calculated temperature
static char temp_str[16];     // Buffer for temperature string

// Function prototypes for LCD
void lcd_initialize(void);
void lcd_data(unsigned char data);
void lcd_string(const char *str, unsigned char len);
void lcd_command(unsigned char cmd);

// Function prototypes for DS18B20
unsigned char ds18b20_start(void);
void ds18b20_write_bit(unsigned char bit);
void ds18b20_write_byte(unsigned char byte);
unsigned char ds18b20_read_bit(void);
unsigned char ds18b20_read_byte(void);
unsigned char ds18b20_read(signed int *raw_temp);

Main Program Logic

The main loop initializes the LCD and DS18B20, reads the temperature data from the sensor, converts it to Celsius, and displays the result on the LCD. If the sensor read fails, an error message is displayed instead.

void main(void) {
    // Initialize LCD pins
    TRISCbits.TRISC0 = 0;
    TRISCbits.TRISC1 = 0;
    TRISCbits.TRISC2 = 0;
    
    TRISDbits.TRISD4 = 0;
    TRISDbits.TRISD5 = 0;
    TRISDbits.TRISD6 = 0;
    TRISDbits.TRISD7 = 0;
    
    // Initialize DS18B20 pin as input
    DS18B20_TRIS = 1;
    
    lcd_initialize();

    while(1) {
        if(ds18b20_read(&raw_temp)) {
            // Convert raw value to temperature in Celsius
            temperature = (float)raw_temp * 0.0625;
            
            // Format temperature as a string
            sprintf(temp_str, "Temp: %2.1f C", temperature);
            
            // Display temperature on LCD
            lcd_command(0x80);         // Set LCD cursor position
            lcd_string(temp_str, 16);  // Display temperature string
        } else {
            lcd_command(0x80);
            lcd_string("Sensor Error!", 12);  // Display error message
        }
        __delay_ms(1000);  // Update every second
    }
}

DS18B20 Sensor Functions

This part defines the functions needed to communicate with the DS18B20 sensor, including functions to start communication, write and read bits, and read temperature data. Each function manages specific steps in the one-wire protocol required by DS18B20.

// Start DS18B20 communication and check response
unsigned char ds18b20_start(void) {
    unsigned char response;
    
    DS18B20_TRIS = 0;      // Set as output
    DS18B20_PIN = 0;       // Send reset pulse
    __delay_us(500);       // Hold for 500us
    
    DS18B20_TRIS = 1;      // Set as input
    __delay_us(100);       // Wait for response
    
    response = DS18B20_PIN; // Read response
    __delay_us(400);        // Wait 400us
    
    return !response;       // Return TRUE if sensor detected
}

// Write a single bit to DS18B20
void ds18b20_write_bit(unsigned char bit) {
    DS18B20_TRIS = 0;      // Set as output
    DS18B20_PIN = 0;       // Pull low
    __delay_us(2);
    
    if(bit) DS18B20_PIN = 1;  // Send bit
    __delay_us(80);        // Hold for 80us
    
    DS18B20_TRIS = 1;      // Release line
    __delay_us(2);
}

// Write a byte to DS18B20
void ds18b20_write_byte(unsigned char byte) {
    for(unsigned char i = 0; i < 8; i++) {
        ds18b20_write_bit(byte & 0x01);
        byte >>= 1;
    }
}

// Read a single bit from DS18B20
unsigned char ds18b20_read_bit(void) {
    unsigned char bit;
    
    DS18B20_TRIS = 0;      // Set as output
    DS18B20_PIN = 0;       // Pull low
    __delay_us(2);
    
    DS18B20_TRIS = 1;      // Release line
    __delay_us(5);         // Wait 5us
    
    bit = DS18B20_PIN;     // Read bit
    __delay_us(100);       // Wait 100us
    
    return bit;
}

// Read a byte from DS18B20
unsigned char ds18b20_read_byte(void) {
    unsigned char byte = 0;
    for(unsigned char i = 0; i < 8; i++) {
        byte >>= 1;
        if(ds18b20_read_bit()) byte |= 0x80;
    }
    return byte;
}

// Read temperature from DS18B20
unsigned char ds18b20_read(signed int *raw_temp_value) {
    unsigned char temp_l, temp_h;
    
    if(!ds18b20_start()) return 0;
    
    ds18b20_write_byte(0xCC);  // Skip ROM command
    ds18b20_write_byte(0x44);  // Start conversion
    
    while(!ds18b20_read_byte());  // Wait for conversion
    
    if(!ds18b20_start()) return 0;
    
    ds18b20_write_byte(0xCC);  // Skip ROM command
    ds18b20_write_byte(0xBE);  // Read scratchpad
    
    temp_l = ds18b20_read_byte();  // LSB
    temp_h = ds18b20_read_byte();  // MSB
    
    *raw_temp_value = (temp_h << 8) | temp_l;
    
    return 1;
}

LCD Display Functions

This section contains the LCD functions to initialize the display, send commands, and display data. These functions handle LCD control for clear and formatted temperature display.

// Initialize LCD for 4-bit mode
void lcd_initialize(void) {
    lcd_command(0x02); // Return cursor to home position
    lcd_command(0x28); // Set 4-bit mode, 2-line display, 5x8 font
    lcd_command(0x06); // Set entry mode with auto-increment
    lcd_command(0x0C); // Display ON, cursor OFF
    lcd_command(0x01); // Clear display
    __delay_ms(2);     // Short delay for clear screen command
}

// Send data to LCD
void lcd_data(unsigned char data) {
    RS = 1; RW = 0;       // Set to data mode and write
    PORTD = (data & 0xF0); // Send upper nibble
    EN = 1;
    __delay_ms(2);
    EN = 0;
    
    PORTD = ((data << 4) & 0xF0); // Send lower nibble
    EN = 1;
    __delay_ms(2);
    EN = 0;
}

// Send string to LCD
void lcd_string(const char *str, unsigned char len) {
    for(unsigned char i = 0; i < len; i++) {
        lcd_data(str[i]);
    }
}

// Send command to LCD
void lcd_command(unsigned char cmd) {
    RS = 0; RW = 0;       // Set to command mode and write
    PORTD = (cmd & 0xF0); // Send upper nibble
    EN = 1;
    __delay_ms(2);
    EN = 0;
    
    PORTD = ((cmd << 4) & 0xF0); // Send lower nibble
    EN = 1;
    __delay_ms(2);
    EN = 0;
}

Proteus Configuration :

  • Open Proteus & Create New Project and click next
  • Click on Pick Device
  • Search for PIC16F877A & DS18B20 & RESISTANCE
  • Click on Terminal Mode then choose (DEFAULT & POWER &GROUND)
  • finally make the circuit below and start the simulation
PIC16F877 DS18B20 Circuit Design in Proteus 8

That’s all!

If you have any questions or suggestions don’t hesitate to leave a comment below

You Might Also Like

Leave a Comment


Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?
-
00:00
00:00
Update Required Flash plugin
-
00:00
00:00