Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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 ?
 
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.
 
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.
 
If your getting back a reading of 85 then the chances are that it is working correctly. Can you post your code?

mike.
 
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
int8 read_bit(void)
{
   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 read_byte(void)
{
   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,"Device No.%u address ",numROMs);

            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
#device adc=8

#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
   write_byte(0xBE); // Read scratch pad command

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

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

   scratch[8] = read_byte();   // Received crc byte
   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.
 
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.
 
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.
 
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
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top