Problems with Microcontroller Projects? You may face many Problems, but do not worry we are ready to solve your Problems. All you need to do is just leave your Comments. We will assure you that you will find a solution to your project along with future tips. On Request we will Mail you the Codes for Registered Members of this site only, at free service...Follow Me.

Reading Temperature Values from DS1820 using 1-Wire Protocol

In this experiment, we are going to build a digital temperature meter using DS1820 connected to our PIC16F628A development board. The temperature value will be displayed on the LCD display. I have modified the sample program that comes with the compiler according to our PIC board requirements. Also I have elaborated comments in the program so that every step will be more clear to the readers.

Experimental Setup:
The experimental setup is very straight-forward. Place DS1820 device on the three-pin female header that we recently added to our board. And also connect the data pin of DS1820 to RB.0 pin of PIC16F628A using a jumper wire.

 
 Circuit Diagram
 
Software:
Here is the program written in microC that reads temperature values from DS1820 device using OneWire Library.
/* Project name:
     One Wire Communication Test between PIC16F628A and DS1820
 * Copyright:
     (c) Rajendra Bhatt, 2009.
 * Description:
     This code demonstrates how to use One Wire Communication Protocol
     between PIC16F628A and a 1-wire peripheral device. The peripheral
     device used here is DS1820, digital temperature sensor.
     MCU:             PIC16F628A
     Oscillator:      XT, 4.0 MHz
*/
// LCD connections definitions
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_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 TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_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;
// End LCD connections definitions

// String array to store temperature value to display
char *temp = "000.00";

// Temperature Resolution : No. of bits in temp value = 9
const unsigned short TEMP_RES = 9;

// Variable to store temperature register value
unsigned temp_value;

void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RES - 8;

  // Variable to store Integer value of temperature
  char temp_whole;

  // Variable to store Fraction value of temperature
  unsigned int temp_fraction;
  unsigned short isNegative = 0x00;  

  // check if temperature is negative
  if (temp2write & 0x8000) {
     temp[0] = '-';
     // Negative temp values are stored in 2's complement form
     temp2write = ~temp2write + 1;
     isNegative = 1;   // Temp is -ive 
     }

  // Get temp_whole by dividing by 2 (DS1820 9-bit resolution with 
  // 0.5 Centigrade step )
  temp_whole = temp2write >> RES_SHIFT ;


  // convert temp_whole to characters
 if (!isNegative) { 
     if (temp_whole/100)
   // 48 is the decimal character code value for displaying 0 on LCD
     temp[0] = temp_whole/100  + 48;
     else
     temp[0] = '0';
  } 

  temp[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  temp[2] =  temp_whole%10     + 48;             // Extract ones digit

  // extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // convert temp_fraction to characters
  temp[4] =  temp_fraction/1000    + 48;         // Extract tens digit
  temp[5] = (temp_fraction/100)%10 + 48;         // Extract ones digit

  // print temperature on LCD
  Lcd_Out(2, 5, temp);
}

void main() {
  CMCON  |= 7;                       // Disable Comparators
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Temperature:   ");
  // Print degree character, 'C' for Centigrades
  Lcd_Chr(2,11,223);  
 // different LCD displays have different char code for degree
 // if you see greek alpha letter try typing 178 instead of 223

  Lcd_Chr(2,12,'C');

  //--- main loop
  do {
    //--- perform temperature reading
    Ow_Reset(&PORTB, 0);      // Onewire reset signal
    Ow_Write(&PORTB, 0, 0xCC);   // Issue command SKIP_ROM
    Ow_Write(&PORTB, 0, 0x44);   // Issue command CONVERT_T
    Delay_ms(600);
    // If this delay is less than 500ms, you will see the first reading on LCD 
    //85C which is (if you remember from my article on DS1820) 
    //a power-on-reset value.  
     
    Ow_Reset(&PORTB, 0);
    Ow_Write(&PORTB, 0, 0xCC);    // Issue command SKIP_ROM
    Ow_Write(&PORTB, 0, 0xBE);    // Issue command READ_SCRATCHPAD

    // Read Byte 0 from Scratchpad
    temp_value =  Ow_Read(&PORTB, 0);
    // Then read Byte 1 from Scratchpad and shift 8 bit left and add the Byte 0
    temp_value = (Ow_Read(&PORTB, 0) << 8) + temp_value;

    //--- Format and display result on Lcd
    Display_Temperature(temp_value);

    } while (1);
}

Experimental Output:
The temperature reading will be displayed on the LCD screen and will be updated every 600ms. Look at some snapshots below showing output.

 
 

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...

Recent Comments

Popular Projects

Give Support

Give Support
Encourage Me through Comments

Microcontroller Projects

Total Pageviews