Sunteți pe pagina 1din 10

Experiment No.

4 : Reading Temperature Values from DS1820 using 1-Wire


Protocol
Wednesday, September 30, 2009

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.
Posted by Raj at 7:09 PM

Labels: DS1820, PIC16F628A, PIC16F628A Development Board, PIC16F628A Experiments,


Temperature Meter

12 comments:
Fabio said...

June 20, 2010 8:19 AM


Hi mr Raj.
Do you have a single example with 7 segments displays?
Tanks.

ducu said...

June 23, 2010 1:24 PM

Hello Mr. Raj i have been testes both version of temperature sensor (DS1820 and
DS18B20) and i found a little bug, in both version cannot display symbol "-" when read a
negative temperature.
Do you have any idea how to solve this problem?
I try to solve the problem by myself, with no results.
By the way you did a great gob with this site.

Regards,
ducu

Raj said...

July 3, 2010 8:03 PM

My code should work to display negative temperature too. Negative temperature are in
2's complement form, see my code
// check if temperature is negative
if (temp2write & 0x8000) {
temp[0] = '-';
// Negative temp values are stored in 2's complement form
temp2write = ~temp2write + 1;
}

Raj said...

July 3, 2010 8:05 PM

Fabio,
Here is my experiment with Seven segment Displays.
http://pic16f628a.blogspot.com/2009/10/experiment-no-5-multiplexed-seven.html
Nimal2006 said...

September 10, 2010 12:53 PM

Dear Sir,
I used DS18S20. it did not works it shows 'Temperature:
000.00 C
no temperature detects. I use same code. whats wrong?
Nimal

Raj said...

September 10, 2010 2:35 PM

Try increasing the delay_ms(600) to delay_ms(800) and see if it works.

Ow_Write(&PORTB, 0, 0x44);
Delay_ms(800);
// If this delay is less than 500ms, you will see the first reading on

Also Read this


http://www.picbasic.co.uk/forum/showthread.php?t=13388

Nimal2006 said...

September 11, 2010 7:50 AM

Thanks, Now its working.

Nimal2006 said...

September 11, 2010 8:36 AM

If LCD is 10 meters away from DS18S20 what kind of cable I have to used?

Krishna said...

September 16, 2010 9:11 PM


i want this circuit diagram anybody help me

Raj said...

September 17, 2010 5:57 AM

Krishna,
I have posted the circuit diagram. Enjoy!

kuzmin said...

February 15, 2011 2:32 PM

do you have hex for this example

Raj said...

February 15, 2011 4:34 PM

Kuzmin,
Here it is
http://embedded-lab.com/uploads/HexFiles/PIC16F628A/PIC16F628A_DS1820.zip

Post a Comment
Newer Post Older Post Home

Subscribe to: Post Comments (Atom)


Microcontroller-based Embedded Systems Design

Learn Embedded System Designing with PICMicro

S-ar putea să vă placă și