views:

159

answers:

2
+4  Q: 

One Wire Problem

Hi all!

I need your qualified help! I'm programing in C++, using a PIC 18F87J50 and trying to connect DS18B20 at my H0 Port!

I think my underlying programing is correct so.... the problem I have (think I have), is when performing a ROM Command, I'm searching for the 64-bit ROM CODE.

The first byte should tell me what family the component belongs to (28h). The next 48 bits should give me a uniq serial for just that component. The last one is used for a CRC.

Am I thinking right when doing like this:

void Device_ID( uint8_t command ){
    uint8_t ROM_CODE[8]; // 1 byte CRC, 6 bytes SERIAL, 1 byte Family code
    uint8_t loop;
    static char container[8];

    OW_reset_pulse();
    OW_write_byte( command );

    for(loop = 0; loop < 8; loop++)  // 1 byte in per time = 64-bits
    {
        ROM_CODE[loop] = OW_read_byte(); 
    }

    HexToStrWithZeros(ROM_CODE[0], container);
    Display_Cls();
    Display_StringAt ("Family Code: ",5,6);
    Display_Buffer (container);
}

If I ask for the code in ROM_CODE[1-6] I should get the uniq number?? should'nt I??

Kind Regards!

+2  A: 

Well, the best way to access the serial number is probably to copy it into a separate buffer using strncpy.

#include <string.h>

...

char family;
char serial[7]; // Extra byte for null terminator
char checksum;

...

family = ROM_CODE[0];

strncpy(serial, &ROM_CODE[1], 6);
serial[6] = '\0';

checksum = ROM_CODE[7];

...

The &ROM_CODE[1] is there to fetch the address of the 2nd element in ROM_CODE. ROM_CODE+1 may also work, but my C is a touch rusty.

The null ('\0') is added at the end as C uses null-terminated strings. This will make sure it's compatible with C library routines and commonly used C idioms.

You could also access it directly from the array. But that'll be harder to work with and unlikely to be worth it unless you really need that 6 bytes of memory.

Depending on how sophisticated your app is, you may want to wrap this in a class. Pass the 8 character buffer to the constructor and then use methods such as getFamily() / getSerial() to retrieve the information you want.

For a very simple app though, that's a whole lot of extra code to simplify something that's already very manageable.

Adam Luchjenbroers
Thank you for replying!My Programmer's Notepad complaining about "suspicious pointer conversion" when doing this: strncpy(serial, Is that a problem?/Thanks
Christian
Oh... I just tried your suggestion and the resault was the same... implying that Im doing something wrong before this step.. :(
Christian
It might be worth learning to use GDB then. It'll allow you to watch whats happening more closely.
Adam Luchjenbroers
BTW, what is actually going wrong when you run this program?
Adam Luchjenbroers
GDB... what is that? The thing going wrong here, is that I will only recieve a 64-bit number that is all "one´s" I print to the screen FFFFFFF.... and so on.My device should give me an uniq number in the ROM_CODE[] that isnt full of one's
Christian
Hm... I think my problem now more or less lies in the functions before this function... so this question is answered for!
Christian
A: 

Here is some code that should allow you to read the device ID. I think your code was running to fast here is some code that I used to interface with the DS18B20.

/****************************************************************************
* temperature.h
****************************************************************************/

#ifndef TEMP_H
#define TEMP_H

extern double read_temp ( void );
extern   void start_temp( void );
extern   void Device_ID ( void );

#endif

/****************************************************************************
* temperature.c
****************************************************************************/

void     reset_ow(void);
void     write_ow(uint8_t  b);
uint8_t  read_ow (void);

#define OW_TEMP_SIG LATHbits.LATH0
#define OW_TEMP_TRIS TRISHbits.TRISH0
#define OW_TEMP_SIG_IN PORTHbits.RH0
#define DIR_OUT 0
#define DIR_IN 1


void Device_ID( void )
{
    uint8_t loop; 
   uint8_t family; 
   uint8_t checksum; 
   uint8_t ROM_CODE[8];      // 1 byte CRC, 6 bytes SERIAL, 1 byte Family code

   reset_ow();
   write_ow(0x33); // READ ROM COMMAND DS18B20

    for(loop = 0; loop < 8; loop++) // 1 byte in per time = 64-bits
    {
     ROM_CODE[loop] = read_ow();
    }

    family = ROM_CODE[0];
    checksum = ROM_CODE[7];

  // add extra code to handle code
}

void start_temp(void) 
{
   uint8_t i;

   OW_TEMP_SIG=1;
   OW_TEMP_TRIS=DIR_OUT;
   for ( i=0;i<100;i++)
   {
       Delay_us(100);
   }
   reset_ow();
   write_ow(0xcc); // skip rom
   write_ow(0x44); // start t conv
}

double read_temp(void) 
{
   double temp=0;
   S16 itemp;

   reset_ow();
   write_ow(0xcc); // skip rom
   write_ow(0xbe); // read scratch pad
   itemp=read_ow();
   itemp|=(S16)read_ow()<<8;

   temp = itemp*(0.0625);
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
   return temp; 
}


void reset_ow(void)
{
   OW_TEMP_TRIS=DIR_OUT;
   OW_TEMP_SIG=0;
   Delay_us(250);
   Delay_us(250);
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
   Delay_us(250);
   Delay_us(250);
}

void write_ow(uint8_t b)
{
   uint8_t i;

   OW_TEMP_SIG=1;
   OW_TEMP_TRIS=DIR_OUT;
   for ( i=0;i<8;i++)
   {
      OW_TEMP_SIG=0;
      if ( b & 0x01 )
      {
         Delay_us(10);
         OW_TEMP_SIG=1;
      }
      Delay_us(70);
      OW_TEMP_SIG=1;
      Delay_us(10);
      b >>= 1;
   }
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
}

uint8_t read_ow(void)
{
   uint8_t b=0;
   uint8_t m;
   uint8_t i;

   m=1;
   for ( i=0;i<8;i++)
   {
      OW_TEMP_SIG=1;
      OW_TEMP_TRIS=DIR_OUT;
      OW_TEMP_SIG=0;        
      Delay_us(8);
      OW_TEMP_TRIS=DIR_IN;
      OW_TEMP_SIG=1;
      Delay_us(15);

      if ( 1 == OW_TEMP_SIG_IN )
      {
         b |= m;
      }
      m <<=1;
      Delay_us(60);
   }
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
   return b;
}
Rex Logan