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) << + 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);
}
Correction on the One Wire Example for DS18S20
- janko.kaljevic
- Posts: 3565
- Joined: 16 Jun 2011 13:48
Re: Correction on the One Wire Example for DS18S20
Hello,
When you used our example, were you able to get proper results?
Best regards.
When you used our example, were you able to get proper results?
Best regards.
Re: Correction on the One Wire Example for DS18S20
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.
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.
- janko.kaljevic
- Posts: 3565
- Joined: 16 Jun 2011 13:48
Re: Correction on the One Wire Example for DS18S20
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.
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.
Re: Correction on the One Wire Example for DS18S20
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) << + temp;
//--- Format and display result on Lcd
Display_Temperature(temp);
Delay_ms(500);
} while (1);
}
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) << + temp;
//--- Format and display result on Lcd
Display_Temperature(temp);
Delay_ms(500);
} while (1);
}
- janko.kaljevic
- Posts: 3565
- Joined: 16 Jun 2011 13:48
Re: Correction on the One Wire Example for DS18S20
Hello,
Thanks for sharing.
Best regards.
Thanks for sharing.
Best regards.
Re: Correction on the One Wire Example for DS18S20
I do not know what happened but the smiley on the code is 8 so its shift left by eight
Re: Correction on the One Wire Example for DS18S20
Hello noelrios7
This smiley 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
How to avoid this problem in the future?
The solution is very simple
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
Your code will look like this:
Try it when you post a code in the forum next time. It makes your code more readable
Best Regards
This smiley 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
How to avoid this problem in the future?
The solution is very simple
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
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);
}
Best Regards
My hobby is collecting MikroElektronika products.
Gotta catch them all!
Gotta catch them all!
Re: Correction on the One Wire Example for DS18S20
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
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
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;
Your help is very appreciated
Re: Correction on the One Wire Example for DS18S20
Hello magnetar
The one-wire read command can only read a byte at a time.
I hope that this was helpful
Best Regards
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.magnetar wrote:why we have to read the port twice with shift and what is the size of the one wire
The one-wire read command can only read a byte at a time.
I hope that this was helpful
Best Regards
My hobby is collecting MikroElektronika products.
Gotta catch them all!
Gotta catch them all!
Re: Correction on the One Wire Example for DS18S20
Thank you very much Magik for your answer. You are Magic
Re: Correction on the One Wire Example for DS18S20
You are most welcome magnetar. I'm glad that I was able to help
By the way, welcome to the forum!
Best Regards
By the way, welcome to the forum!
Best Regards
My hobby is collecting MikroElektronika products.
Gotta catch them all!
Gotta catch them all!