CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Multiple DS18B20 in parasite Mode (finally working!!!)
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sebitnt



Joined: 05 Dec 2010
Posts: 5

View user's profile Send private message

Multiple DS18B20 in parasite Mode (finally working!!!)
PostPosted: Sun Dec 05, 2010 2:39 am     Reply with quote

Hi everybody,

Since a few days I'm trying to get some DS18B20 working in parasite mode on my 16F877. Meanwhile it is working so far. The only thing that won't work is when I put more than 8 sensors at my PIC. In that case I get an output like this:
Code:
Device No.1 address 530000028FEE7828
Device No.2 address AE0000028FEAB428
Device No.3 address F200000290036A28
Device No.4 address F80000028FC0BA28
Device No.5 address F80000028FC4DE28
Device No.6 address A70000028FF74128
Device No.7 address 4000000290061128
Device No.8 address 330000028FB74D28
Device No.40 address BB0000028FD49328

Sensor Number: 1 22.0625
Sensor Number: 2 22.1250
Sensor Number: 3 23.9375
Sensor Number: 4 22.8125
Sensor Number: 5 22.0000
Sensor Number: 6 22.3750
Sensor Number: 7 22.2500
Sensor Number: 8 21.9375
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Error in data
Sensor Number: 33 22.0625
Sensor Number: 34 22.1250
Sensor Number: 35 23.9375
Sensor Number: 36 22.8125
Sensor Number: 37 22.0000
Sensor Number: 38 22.3750
Sensor Number: 39 22.2500
Sensor Number: 40 21.9375
...


I used some code out of this forum and modified it but i don't exactly know which code i used.
Maybe it was out of this posts:
http://www.ccsinfo.com/forum/viewtopic.php?p=129854
http://www.ccsinfo.com/forum/viewtopic.php?t=19255

Again: With eight sensors attached everything works fine but if i put the 9. sensor on my microcontroller i get an output as described before.
It would be nice if someone could help me with this code.

And here is my code:

main.c
Code:
#include <16F877A.H>
#fuses XT,NOWDT,NOLVP,PUT,NOPROTECT,NOBROWNOUT,NOWRT
//#use delay(clock = 20000000)
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define DQ PIN_E2 // One Wire Bus pin assignment

#include "onewire.c"



void main(void)
{
   int8 i;
   float temperature;
   int8 scratch[9];       

    //lcd_init();

   output_float(DQ);       // Set as input. 4k7 pullup on bus.
   FindDevices();         
   
   while(1)
   {
      if (!ow_reset())     // If a device is present
      {
         write_byte(0xCC,0); // Skip Rom command
         write_byte(0x44,1); // Temperature convert command
         //output_float(DQ);
         delay_ms(750);    // Max. conv. time is 750mS for 12 bit
         //output_float(DQ);
         ow_reset();
 
         // Now get the device raw temperature data using Match ROM with the
         // addresses obtained with FindDevices().
         // If the received crc is same as calculated then data is valid.
         // Scale and round to nearest degree C.
         // Scaling is 0.0625 (1/16) deg.C/bit with default 12 bit resolution.
         // Round by adding half denominator for positive temperatures and
         // subtracting half denominator for negative temperatures.
         int8 numRom;             
         for (numRom=1;numRom<=numROMs;numRom++)
         {
            if (Send_MatchRom(numRom))
            {
               write_byte(0xBE,0); // Read scratch pad command
               dowcrc = 0;       
               
               // Get the data bytes
               
               for (i=0;i<=7;i++)
               {
                   scratch[i] = read_byte();
                   ow_crc(scratch[i]);     
               }
   
               scratch[8] = read_byte();   // Get crc byte
               ow_reset();
   
               // If calculated crc from incoming bytes equal to crc byte
               // then data is valid.
                                         
               if (scratch[8] == dowcrc)
               {
                  temperature = (float) make16(scratch[1],scratch[0]);
                 
                  if (temperature >= 0)
                     temperature = (temperature + 8)/16;
               
                  else
                     temperature = (temperature - 8)/16;
                     
               printf("Sensor Number: %u", numRom); 
               printf(" %7.4g\r\n", temperature);
               }
               
               else
                  printf("Error in data\r\n");
            }
         }
        printf("\r\n");
      }   
   }
}



onewire.c
Code:
// One Wire bus functions - from Dallas publication AN162
// "Interfacing DS18x20/DS1822 1-wire Temperature Sensor in a Microcontroller
// Environment". Delays calculated from values given for 8051.
// Changed variable name ROM[] to RomBytes[] because ROM is a reserved word
// in version 4 of the CCS compiler.

// Global variables
int8 RomBytes[8];     
int8 lastDiscrep = 0;
short doneFlag = 0;
int8 FoundROM[9][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);         // Added, 1uS min. Code relied on 8051 being slow.
   output_float(DQ);
   delay_us(12);        // Read within 15uS from start of time slot
   return(input(DQ));   
}                       
//******************************************************************************
void write_bit(int8 bitval)
{
   output_low(DQ);

   if(bitval == 1) {
      delay_us(1);      // 1uS min. 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;
}

//-------------------------------------
//new byte writing routine with parasite power option
void write_byte(int8 val, int8 power_on)
{
int i;

for(i=0; i<8; i++)
   {
    output_low(DQ);
    delay_us( 2 ); 
    output_bit(DQ, shift_right(&val,1,0)); 

    delay_us(60);
 
    if((i == 7) && (power_on == 1))
      {
       output_high(DQ);
      }
    else
      {
       output_float(DQ);
       delay_us( 2 ); 
      }
   }

}

//******************************************************************************
// 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,0);       // 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 = ((RomBytes[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 ROM[n] with mask k
         if (g == 1) RomBytes[n] |= k;
         else RomBytes[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(RomBytes[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] = RomBytes[m];
            }

            printf("Device No.%u address ",numROMs);

            printf("%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.
      }
   }
printf("\n");
}
//******************************************************************************
// Sends Match ROM command to bus then device address
int8 Send_MatchRom(int8 actNumRom)
{
   int8 i;
   if (ow_reset()) return FALSE;          // 0 if device present
   write_byte(0x55,0);                      // Match ROM

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

   return TRUE;
}


Last edited by sebitnt on Sun Dec 05, 2010 7:52 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Sun Dec 05, 2010 4:04 am     Reply with quote

A series of comments:
1) Declare your variables in the C locations.....
For example, 'int8 numRom'. C allows variables to be declared at the start of a function (in the original version), _or_ (in latter versions), at the start of a function block. (immediately after a '{'), It does not support 'inline' variable definitions. Now CCS added support for the latter 'start of block' declarations, and does not complain about inline declarations, but these do not basically work.....
2) Look at the code you are using. How large are the tables used to store the devices found?. There seems to be some slight variation here, but basically 9 devices are allowed maximum with the code as posted, and there is a problem that 'numROMs', is allowed to go larger than the table storing the ROM data.
Remember that in C, arrays are zero referenced. The table, has entries 0 to 8. Wonder why an entry '9' does not work.....
Do some careful limit thinking, & expand the tables....

Best Wishes
sebitnt



Joined: 05 Dec 2010
Posts: 5

View user's profile Send private message

PostPosted: Sun Dec 05, 2010 7:52 am     Reply with quote

Thank you for your fast reply! I changed the variables declaration in a way, that they are declared at the beginning of main{} (learning JAVA at the moment Wink ). I'd also change the table for the recognized ROMs to a size of 12. So it would be possible to detect at least 11 Sensors (maybe also 12) and it worked fine with my 10 Sensors!
Thanks again!
Code available on request.
Have a nice sunday!
kunteper



Joined: 21 Nov 2010
Posts: 1

View user's profile Send private message

PostPosted: Mon Dec 06, 2010 1:26 pm     Reply with quote

sebitnt wrote:
Thank you for your fast reply! I changed the variables declaration in a way, that they are declared at the beginning of main{} (learning JAVA at the moment Wink ). I'd also change the table for the recognized ROMs to a size of 12. So it would be possible to detect at least 11 Sensors (maybe also 12) and it worked fine with my 10 Sensors!
Thanks again!
Code available on request.
Have a nice sunday!


I would appreciate if you could post your working code. I am having trouble reading 18b20's.
sebitnt



Joined: 05 Dec 2010
Posts: 5

View user's profile Send private message

PostPosted: Mon Dec 06, 2010 1:46 pm     Reply with quote

Here is the code: http://rapidshare.com/files/435116217/ds18b20.rar

Take attention to negative Temperatures!!! Maybe that these will not be calculated as expected. The code is not perfect, but a beginning. Especially the temperature calculation is a thing which I don't understand (why plus or minus eight degree???). I will work on the code at the next weekend. It would be nice if you could post your modifications!
ljbeng



Joined: 10 Feb 2004
Posts: 205

View user's profile Send private message

PostPosted: Mon Dec 20, 2010 5:10 pm     Reply with quote

Can you post the latest code in the Code Library area? Thanks.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Tue Dec 21, 2010 7:49 am     Reply with quote

I had a project almost ten years ago with the dallas 1 wire temp sensor 1820 in parasitic mode. I Never got more than 5 sensors to work and didn't get much more than 50 ft of wire until things stopped working reliably. Maybe they have improved the power draw on the sensors when sensing with the latest Maxim/Dallas sensors.
chikolisto



Joined: 01 Mar 2011
Posts: 1

View user's profile Send private message

it was deleted from rapidshare:(
PostPosted: Tue Mar 01, 2011 10:20 am     Reply with quote

please reupload Smile


sebitnt wrote:
Here is the code: http://rapidshare.com/files/435116217/ds18b20.rar

Take attention to negative Temperatures!!! Maybe that these will not be calculated as expected. The code is not perfect, but a beginning. Especially the temperature calculation is a thing which I don't understand (why plus or minus eight degree???). I will work on the code at the next weekend. It would be nice if you could post your modifications!
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Tue Mar 01, 2011 1:14 pm     Reply with quote

Better yet:
Quote:
Can you post the latest code in the Code Library area?

_________________
Google and Forum Search are some of your best tools!!!!
sebitnt



Joined: 05 Dec 2010
Posts: 5

View user's profile Send private message

PostPosted: Wed Mar 02, 2011 11:54 am     Reply with quote

ljbeng wrote:
Can you post the latest code in the Code Library area? Thanks.

Uploaded as requested: http://www.ccsinfo.com/forum/viewtopic.php?p=144754
subi



Joined: 29 Aug 2010
Posts: 24

View user's profile Send private message

DS18s20 negative measure
PostPosted: Thu May 26, 2011 2:50 pm     Reply with quote

sebitnt wrote:
ljbeng wrote:
Can you post the latest code in the Code Library area? Thanks.

Uploaded as requested: http://www.ccsinfo.com/forum/viewtopic.php?p=144754

Hi Everybody,
I would like to ask that I use this program to DS18s20: http://www.ccsinfo.com/forum/viewtopic.php?t=44853. The program works fine in the positive period but don't work well in the negative. A display shows 4095,5 instead of -0,5. Please help me how to show the negative numbers.
Thank you (sorry for my English)
Subi
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 27, 2011 12:30 am     Reply with quote

Please post new questions in a new topic.

Code:
                  temperature = (float) make16(scratch[1],scratch[0]);
I haven't tried, but you could change the line above to:
Code:
                  temperature = (float) (signed int16) make16(scratch[1],scratch[0]);
subi



Joined: 29 Aug 2010
Posts: 24

View user's profile Send private message

DS18s20 negativ measure
PostPosted: Fri May 27, 2011 12:39 pm     Reply with quote

ckielstra wrote:
Please post new questions in a new topic.

Code:
                  temperature = (float) make16(scratch[1],scratch[0]);
I haven't tried, but you could change the line above to:
Code:
                  temperature = (float) (signed int16) make16(scratch[1],scratch[0]);


Thank you. This advice is good. The program runs well.
Best regards,
Subi
Got PIC



Joined: 21 Mar 2008
Posts: 10

View user's profile Send private message

This doesn't work for me..
PostPosted: Mon Jan 09, 2017 7:53 pm     Reply with quote

I'm using a 18F6527.

This code doesn't work at all for me... Not sure why.
Code:

#include <18F6527.H>

#fuses  NOLVP,HS,PROTECT,NOWDT,PUT,BROWNOUT//,BORV45
#use delay(clock = 20000000)

#use rs232(baud=9600,PARITY=N, BITS=8,xmit=PIN_G1,rcv=PIN_G2,stream=USB_PORT,errors)   //
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ENABLE=PIN_C2, stream=SERIAL_PORT, errors)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 09, 2017 11:48 pm     Reply with quote

1. Post a link to your schematic.
If you can't do that, then search Google images for this:
Quote:
ds18b20 in parasite mode schematic

Then pick out the schematic that is the closest to what you're doing,
and post a link to it here.

2. Tell us what pin you're using for the data line for the sensors.

3. Tell us what the value of your pull-up resistor is for the sensors.

4. Tell us how many sensors you're using.

5. Tell us your Vdd voltage for the board.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group