# DS1822 - broken ?

Status
Not open for further replies.

#### tresca

##### Member
I've scavenged this entire site for working 1-wire code. Found many different variants for ds1820 and ds1822 code.

However, when I try any of them, I do not get a value that should represent my current temperature.

The values change, from either 0C, 85C or 127C. I tried holding my finger to it, blowing on it, an open flame, and the temperature does not change.

I did have the 4.7k pullup resistor, and I even tried multiple pins on my uC.

I tried 2 different ds1822 and both are constant (thought both dont have the same output).

One of them displays 127
The other display 85

Is it safe to assume that somehow I damaged them, or I received them damage or faulty ?

#### Pommie

##### Well-Known Member
I am guessing that a reading of zero or 127 is a hardware fault as these represent all zeros and (probably) all ones. A reading of 85 is to be expected as this is the power on value that is returned before a convert command is executed. Are you sending a convert (0x44) command and waiting for the conversion to finish?

Mike.

#### tresca

##### Member
To be completely honest, right now, im not doing anything. I'm taking working code posted on this site, and trying to get it to work. I havent made any mods to the code other then wat was necessary to get it to compile, such as certain #defines and what not.

I tried to make my own, but it failed, so I wanted to try working code to see if it was a problem with the ds1822 which is what im leaning towards right now. I think I fried both of them somehow.

sigh.

#### Pommie

##### Well-Known Member
If your getting back a reading of 85 then the chances are that it is working correctly. Can you post your code?

mike.

#### tresca

##### Member
onewire.h
Code:
// One Wire bus functions - from Dallas publication AN162
// "Interfacing DS18x20/DS1822 1-wire Temperature Sensor in a uC Environment"
// Delays calculated from values given for 8051 in source code
#include <lcd_config.h>

#define DQ PIN_B1
// Global variables
int8 DATA[8];            // DATA bit
int8 lastDiscrep = 0;
short doneFlag = 0;
int8 FoundROM[7][8];    // Table of found ROM codes, 8 bytes for each
int8 numROMs;
int8 dowcrc;            // crc is accumulated in this variable

// crc lookup table
int8 const dscrc_table[] = {
0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
157,195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,
35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,
248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,
140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
87,9,235,181,54,104,138,212,149,203,41,119,244,170,72,22,
233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53
};

// Returns 0 for one wire device presence, 1 for none
int8 ow_reset(void)
{
int8 presence;

output_low(DQ);
delay_us(488);          // Min. 480uS
output_float(DQ);
delay_us(72);           // Takes 15 to 60uS for devices to respond
presence = input(DQ);
delay_us(424);          // Wait for end of timeslot
return(presence);
}
/******************************************************************************/
// Read bit on one wire bus
{
output_low(DQ);
delay_us(1);         // 1uS min. Original code relied on 8051 being slow
output_float(DQ);
delay_us(20);        // Wait at least 15mS from start of time slot
return(input(DQ));   // Delay to finish time slot (total 60 to 120uS)
}                       // must be done next.
/******************************************************************************/
void write_bit(int8 bitval)
{
output_low(DQ);

if(bitval == 1) {
delay_us(1);      // 1uS min. Original code relied on 8051 being slow
output_float(DQ);
}
delay_us(105);       // Wait for end of timeslot
output_float(DQ);
}
/******************************************************************************/
{
int8 i;
int8 val = 0;

for(i=0;i<8;i++)
{
if(read_bit()) val |= (0x01 << i);
delay_us(120);  // To finish time slot
}

return val;
}
/******************************************************************************/
void write_byte(int8 val)
{
int8 i;
int8 temp;

for (i=0;i<8;i++)
{
temp = val >> i;
temp &= 0x01;
write_bit(temp);
}

delay_us(105);
}
/******************************************************************************/
// One wire crc
int8 ow_crc(int8 x)
{
dowcrc = dscrc_table[dowcrc^x];
return dowcrc;
}
/******************************************************************************/
// Searches for the next device on the one wire bus. If there are no more
// devices on the bus then false is returned.
int8 Next(void)
{
int8 m = 1;             // ROM Bit index
int8 n = 0;             // ROM Byte index
int8 k = 1;             // Bit mask
int8 x = 0;
int8 discrepMarker = 0;
int8 g;                 // Output bit
int8 nxt;               // Return value
short flag;

nxt = FALSE;            // Reset next flag to false

dowcrc = 0;             // Reset the dowcrc

flag = ow_reset();

if (flag||doneFlag)     // If no parts return false
{
lastDiscrep = 0;     // Reset the search
return FALSE;
}

write_byte(0xF0);       // Send SearchROM command

do
{
x = 0;
if (read_bit() == 1) x = 2;
delay_us(120);
if (read_bit() == 1) x |= 1;   // And it's complement

if (x == 3)                   // There are no devices on the one wire bus
break;
else
{
if (x > 0)                 // All devices coupled have 0 or 1
g = x >> 1;             // Bit write value for search

// If this discrepancy is before the last discrepancy on a previous
// Next then pick the same as last time.
else
{
if (m < lastDiscrep)
g = ((DATA[n] & k) > 0);
// If equal to last pick 1
else
g = (m == lastDiscrep);  // If not then pick 0

// If 0 was picked then record position with mask k
if (g == 0) discrepMarker = m;
}

// Isolate bit in DATA[n] with mask k
if (g == 1) DATA[n] |= k;
else DATA[n] &= ~k;

write_bit(g);  // ROM search write

m++;           // Increment bit counter m
k = k << 1;    // and shift the bit mask k
// If the mask is 0 then go to new ROM
if (k == 0)
{  // Byte n and reset mask
ow_crc(DATA[n]);      // Accumulate the crc
n++;
k++;
}
}
} while (n < 8);  // Loop through until through all ROM bytes 0-7

if (m < (65||dowcrc))   // If search was unsuccessful then
lastDiscrep = 0;     // reset the last Discrepancy to zero

else  // Search was successful, so set lastDiscrep, lastOne, nxt
{
lastDiscrep = discrepMarker;
doneFlag = (lastDiscrep == 0);
nxt = TRUE; // Indicates search not yet complete, more parts remain
}

return nxt;
}
/******************************************************************************/
// Resets current state of a ROM search and calls Next to find the first device
// on the one wire bus.
int8 First(void)
{
lastDiscrep = 0;
doneFlag = FALSE;
return Next();    // Call Next and return it's return value;
}
/******************************************************************************/
void FindDevices(void)
{
int8 m;

if(!ow_reset())
{
if(First())    // Begins when at least one part found
{
numROMs = 0;

do
{
numROMs++;

for (m=0;m<8;m++)
{
FoundROM[numROMs][m] = DATA[m];   // Identifies ROM no. on device
}

printf(lcd_putc,"%X%X%X%X%X%X%X%X\n\r",
FoundROM[numROMs][7],FoundROM[numROMs][6],FoundROM[numROMs][5],
FoundROM[numROMs][4],FoundROM[numROMs][3],FoundROM[numROMs][2],
FoundROM[numROMs][1],FoundROM[numROMs][0]);

} while (Next() && (numROMs<10));   // Continues until no additional
// devices found.
}
}
lcd_putc('\n'); lcd_putc('\r');
}
/******************************************************************************/
// Sends Match ROM command to bus then device address
int8 Send_MatchRom(void)
{
int8 i;
if (ow_reset()) return FALSE;          // 0 if device present
write_byte(0x55);                      // Match ROM

for (i=0;i<8;i++)
{
write_byte(FoundRom[numROMs][i]);   // Send ROM code
}

return TRUE;
}
/******************************************************************************/
onewiretest.c
Code:
#include <18F442.h>
#device *=16

#FUSES NOWDT, HS, PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=3M)

#include <onewire.h>

void main()
{

int8 i,j;
signed int16 stemp16;  // Raw temperature data in 2's complement
int8 scratch[10];          // Lowest two bytes are for temperature

output_float(DQ);        // 4k7 pullup on bus

lcd_init();
// Skip ROM code, must have only one device on bus
{
ow_reset();
write_byte(0xCC); // Skip Rom command
write_byte(0x44); // Temperature convert command
output_float(DQ);
delay_ms(750);    // Max. time for conversion is 750mS
ow_reset();
write_byte(0xCC); // Skip Rom command

dowcrc = 0;       // Reset the crc to start a new calculation

for (i=0;i<=7;i++)
{
ow_crc(scratch[i]);          // Accumulate the crc
}

ow_reset();

// Scale to deg. C, scaling is 0.0625 (1/16) deg.C/bit with default 12 bit
// resolution. Could reduce res. and therefore shorten conversion time
// if necessary.
// Output the temperatures in whole degrees, apply rounding by adding
// half denom.
if (scratch[8] == dowcrc)
{
stemp16 = (signed int16) make16(scratch[1],scratch[0]);
stemp16 = (stemp16 + 8)/16;
printf(lcd_putc,"%4ld ",stemp16);
}
else printf(lcd_putc,"xxxx");    // There was an error in the data
}

}
That was my last code I tried. The output is 128 when I try each ds1822 by itself. When I try the code without the device connected, I get "xxxx" which as I should.

Thoughts ?

I ordered some new samples, dont know when they'll come in to be able to test them out.

#### Gayan Soyza

##### Active Member
Did you notice the Dallas has stated this in their protocol you posted-" Delays calculated from values given for 8051 in source code".

You can find the place where the problem is.Is it in your main routine or in your <onewire.h> protocol.Comment the DS stuff & write a value to the "scratch[1],scratch[0]" & see you get a correct written value on the LCD!

Dealing with CRC is also bit doubt for me.

#### 3v0

##### Coop Build Coordinator
Forum Supporter
If you have a Junebug or PICkit2 you can use it as a logic analyzer to look at the signals generated by the PIC. Compare them to the ones provided by dallas to see what delays you need to adjust.

#### tresca

##### Member
sigh. I dont know whats wrong. I've been simulating it on proteus and the delays seem to be ok, but I still cant get it to work.

I think ill wait until my new order of ds1822's come in so i know that they are working rather try and fool around with this when it could very well be damaged.

#### sharnpio

##### New Member
I am guessing that a reading of zero or 127 is a hardware fault as these represent all zeros and (probably) all ones. A reading of 85 is to be expected as this is the power on value that is returned before a convert command is executed. Are you sending a convert (0x44) command and waiting for the conversion to finish?

Mike.
hi pommie,
what is the actual concept behind the 1-wire protocol for interfacing ds1820 with at89c2051.
plz......help me

#### Pommie

##### Well-Known Member
hi pommie,
what is the actual concept behind the 1-wire protocol for interfacing ds1820 with at89c2051.
plz......help me

Mike.

#### sharnpio

##### New Member
thank u pommie.............its fantastic

Status
Not open for further replies.