Correction on the One Wire Example for DS18S20

General discussion on mikroElektronika website & forums.
Post Reply
Author
Message
noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Correction on the One Wire Example for DS18S20

#1 Post by noelrios7 » 21 Apr 2012 04:59

Here is the correction for the One Wire Example using a DS18S20. The master reads two bytes where the MSByte is a Sign and the LSByte is the temperature reading. The LSBit of the LSByte is the decimal which is 0 or 0.5. The code works but after a conversion, the result is 27.5 degrees celcius. I even used the formula written in the DS18S20 datasheet but the result is still 27.5. Does any one has a suggestion?


//const unsigned short TEMP_RESOLUTION = 9;

char text[] = "00.0";
unsigned short temp;
unsigned short sign;
unsigned short decimal;

void Display_Temperature(unsigned short temp1) {
// const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
// unsigned int temp_fraction;
/*
// check if temperature is negative
i//f (temp2write & 0x8000) {
// text[0] = '-';
// temp2write = ~temp2write + 1;
// }
*/
// extract temp_whole
// temp_whole = temp2write >> RES_SHIFT ;
temp_whole=temp1;
// convert temp_whole to characters
// if (temp_whole/100)
// text[0] = temp_whole/100 + 48;

text[0] = (temp_whole/10)%10 + 48; // extract tens digit
text[1] = temp_whole%10 + 48; // extract ones digit

text[2]='.';
if (decimal & 0x01)
text[3] ='5';
else text[3]='0';

/*
// 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
text[4] = temp_fraction/1000 + 48; // extract thousands digit
text[5] = (temp_fraction/100)%10 + 48; // extract hundreds digit
text[6] = (temp_fraction/10)%10 + 48; // extract tens digit
text[7] = temp_fraction%10 + 48; // extract ones digit
*/
// print temperature on LCD
Lcd_Out(2, 5, text);
}//~

void main() {
unsigned short dummy;
float count_per;
float count_remain;
float temperature;
float reading;
ADCON1 = 7; // Configure AN pins as digital I/O
Lcd_Config(&PORTD,1,0,2,7,6,5,4);
Lcd_Init(&PORTD); // Lcd_Init_EP4, see Autocomplete
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1, 1, " Temperature: ");
// Print degree character, 'C' for Centigrades
Lcd_Chr(2,13,223);
Lcd_Chr(2,14,'C');

//--- main loop
do {
//--- perform temperature reading
do{}
while(Ow_Reset(&PORTE,2)); // Onewire reset signal
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0x44); // Issue command CONVERT_T
Delay_ms(750);


do{}
while(Ow_Reset(&PORTE,2));
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0xBE); // Issue command READ_SCRATCHPAD


temp = Ow_Read(&PORTE,2);
sign = Ow_Read(&PORTE,2);
dummy = Ow_Read(&PORTE,2);
dummy = Ow_Read(&PORTE,2);
dummy = Ow_Read(&PORTE,2);
dummy = Ow_Read(&PORTE,2);
dummy=Ow_Read(&PORTE,2);
count_remain=dummy;
dummy=Ow_Read(&PORTE,2);
count_per=dummy;
do{}
while(Ow_Reset(&PORTE,2));

// temp = (Ow_Read(&PORTE,2) << 8) + temp;

decimal=temp;
temp>>=1;
reading=temp;
temperature=reading-0.25+(count_per-count_remain) /count_per;

temp=temperature;

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


} while (1);
}

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Correction on the One Wire Example for DS18S20

#2 Post by janko.kaljevic » 23 Apr 2012 12:23

Hello,

When you used our example, were you able to get proper results?

Best regards.

noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Re: Correction on the One Wire Example for DS18S20

#3 Post by noelrios7 » 24 Apr 2012 00:39

MCU: PIC16F877
Crystal: 12Mhz

When I used the original example, the result is always 85 degrees celcius. But when I modified the code the temperature now is 27.5 degrees celcius. I hope to try a DS18B20 but one must write the configuration register of the DS18B20 for a nine bit resolution.

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Correction on the One Wire Example for DS18S20

#4 Post by janko.kaljevic » 24 Apr 2012 09:13

Hello,

Please test it with another sensor.
Example code is tested and it works fine for DS1820.
And i do not see any reason why it should not work for DS18x20.

Best regards.

noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Re: Correction on the One Wire Example for DS18S20

#5 Post by noelrios7 » 25 Apr 2012 12:22

Here is the code for a DS18B20. I tested it and it works
MCU: PIC16F877
Crystal: 12Mhz

const unsigned short TEMP_RESOLUTION = 12;

char *text = "000.0000";
unsigned temp;
double radix=2;

void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int decimal;

char temp;



// check if temperature is negative
if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}

// extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;

// convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;

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

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

decimal=0;
if(temp & 0x01)
{
decimal+=625;
}
if(temp & 0x02)
{
decimal+=1250;
}
if(temp & 0x04)
{
decimal+=2500;
}
if(temp & 0x08)
{
decimal+=5000;
}




// convert temp_fraction to characters
text[4] = decimal/1000 + 48; // extract thousands digit
text[5] = (decimal/100)%10 + 48; // extract hundreds digit
text[6] = (decimal/10)%10 + 48; // extract tens digit
text[7] = decimal%10 + 48; // extract ones digit

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

void main() {
ADCON1 = 7; // Configure AN pins as digital I/O
Lcd_Config(&PORTD, 1, 0, 2, 7, 6, 5, 4); // Lcd_Init_EP5, see Autocomplete
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1, 1, " Temperature: ");
// Print degree character, 'C' for Centigrades
Lcd_Chr(2,13,223);
Lcd_Chr(2,14,'C');


Ow_Reset(&PORTE,2); // Onewire reset signal
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0x4E); // Issue command Write

Ow_Write(&PORTE,2,0x00);
Ow_Write(&PORTE,2,0x00);
Ow_Write(&PORTE,2,0x7F);

//--- main loop
do {
//--- perform temperature reading
Ow_Reset(&PORTE,2); // Onewire reset signal
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0x44); // Issue command CONVERT_T
Delay_ms(750);

Ow_Reset(&PORTE,2);
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0xBE); // Issue command READ_SCRATCHPAD

temp = Ow_Read(&PORTE,2);
temp = (Ow_Read(&PORTE,2) << 8) + temp;

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

Delay_ms(500);
} while (1);
}

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Correction on the One Wire Example for DS18S20

#6 Post by janko.kaljevic » 26 Apr 2012 11:44

Hello,

Thanks for sharing.

Best regards.

noelrios7
Posts: 10
Joined: 19 Apr 2012 03:52

Re: Correction on the One Wire Example for DS18S20

#7 Post by noelrios7 » 17 Sep 2014 12:21

I do not know what happened but the smiley on the code is 8 so its shift left by eight

MaGiK
Posts: 897
Joined: 19 Apr 2013 10:00

Re: Correction on the One Wire Example for DS18S20

#8 Post by MaGiK » 17 Sep 2014 19:11

Hello noelrios7 :D

This smiley 8) appears when you type 8 then type )
All smilies can be put here either by clicking them from the box on the left of the text box, or by typing how they're represented :wink:
How to avoid this problem in the future? :shock:
The solution is very simple :D

After you finish typing your code here (Or pasting it after copying from somewhere), you should put your code in the code display mode.
How to do this? Well, you have to select the entire code, then click on the button that says "code", which is available just above the text box in which you're typing your post :D

Your code will look like this:

Code: Select all

const unsigned short TEMP_RESOLUTION = 12;

char *text = "000.0000";
unsigned temp;
double radix=2;

void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int decimal;

char temp;



// check if temperature is negative
if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}

// extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;

// convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;

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

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

decimal=0;
if(temp & 0x01)
{
decimal+=625;
}
if(temp & 0x02)
{
decimal+=1250;
}
if(temp & 0x04)
{
decimal+=2500;
}
if(temp & 0x08)
{
decimal+=5000;
}




// convert temp_fraction to characters
text[4] = decimal/1000 + 48; // extract thousands digit
text[5] = (decimal/100)%10 + 48; // extract hundreds digit
text[6] = (decimal/10)%10 + 48; // extract tens digit
text[7] = decimal%10 + 48; // extract ones digit

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

void main() {
ADCON1 = 7; // Configure AN pins as digital I/O
Lcd_Config(&PORTD, 1, 0, 2, 7, 6, 5, 4); // Lcd_Init_EP5, see Autocomplete
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1, 1, " Temperature: ");
// Print degree character, 'C' for Centigrades
Lcd_Chr(2,13,223);
Lcd_Chr(2,14,'C');


Ow_Reset(&PORTE,2); // Onewire reset signal
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0x4E); // Issue command Write

Ow_Write(&PORTE,2,0x00);
Ow_Write(&PORTE,2,0x00);
Ow_Write(&PORTE,2,0x7F);

//--- main loop
do {
//--- perform temperature reading
Ow_Reset(&PORTE,2); // Onewire reset signal
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0x44); // Issue command CONVERT_T
Delay_ms(750);

Ow_Reset(&PORTE,2);
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0xBE); // Issue command READ_SCRATCHPAD

temp = Ow_Read(&PORTE,2);
temp = (Ow_Read(&PORTE,2) << 8) + temp;

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

Delay_ms(500);
} while (1);
}
Try it when you post a code in the forum next time. It makes your code more readable :mrgreen:

Best Regards :D
My hobby is collecting MikroElektronika products.
Gotta catch them all!

SEHAIRI
Posts: 11
Joined: 08 Nov 2015 00:01

Re: Correction on the One Wire Example for DS18S20

#9 Post by SEHAIRI » 08 Nov 2015 00:21

Hi,
Thank you very much, I bought a DS18B20 and I thought I have DS1820. Each time I ran the code doesn't work unless I change the resolution to 12
It seems that the code in example doesn't work properly with DS18B20.
I have just a simple question about the last two lines of program that I can't understand , why we have to read the port twice with shift and what is the size of the one wire

Code: Select all

temp = Ow_Read(&PORTA, 5);
temp = (Ow_Read(&PORTA, 5) << 8) + temp; 
If the first line is the LSB and the second line is the MSB why we have used the shift by 8 and the sum
Your help is very appreciated

MaGiK
Posts: 897
Joined: 19 Apr 2013 10:00

Re: Correction on the One Wire Example for DS18S20

#10 Post by MaGiK » 09 Nov 2015 16:12

Hello magnetar :D
magnetar wrote:why we have to read the port twice with shift and what is the size of the one wire
We have to read it twice since we can only read a single byte each time, and since the resolution is higher than 8 bits (a byte), then we have to take into account the rest of the bits that were not involved in the first calculation.

The one-wire read command can only read a byte at a time.

I hope that this was helpful
Best Regards :D
My hobby is collecting MikroElektronika products.
Gotta catch them all!

SEHAIRI
Posts: 11
Joined: 08 Nov 2015 00:01

Re: Correction on the One Wire Example for DS18S20

#11 Post by SEHAIRI » 10 Nov 2015 09:52

Thank you very much Magik for your answer. You are Magic :D

MaGiK
Posts: 897
Joined: 19 Apr 2013 10:00

Re: Correction on the One Wire Example for DS18S20

#12 Post by MaGiK » 12 Nov 2015 13:58

You are most welcome magnetar. I'm glad that I was able to help :D
By the way, welcome to the forum! :mrgreen:

Best Regards :D
My hobby is collecting MikroElektronika products.
Gotta catch them all!

Post Reply

Return to “Website & Forums General Discussion”