![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
sebitnt
Joined: 05 Dec 2010 Posts: 5
|
Multiple DS18B20 in parasite Mode (finally working!!!) |
Posted: Sun Dec 05, 2010 2:39 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sun Dec 05, 2010 4:04 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
sebitnt
Joined: 05 Dec 2010 Posts: 5
|
|
Posted: Sun Dec 05, 2010 7:52 am |
|
|
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 ). 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! |
|
![](templates/subSilver/images/spacer.gif) |
kunteper
Joined: 21 Nov 2010 Posts: 1
|
|
Posted: Mon Dec 06, 2010 1:26 pm |
|
|
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 ). 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. |
|
![](templates/subSilver/images/spacer.gif) |
sebitnt
Joined: 05 Dec 2010 Posts: 5
|
|
Posted: Mon Dec 06, 2010 1:46 pm |
|
|
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! |
|
![](templates/subSilver/images/spacer.gif) |
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Mon Dec 20, 2010 5:10 pm |
|
|
Can you post the latest code in the Code Library area? Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Dec 21, 2010 7:49 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
chikolisto
Joined: 01 Mar 2011 Posts: 1
|
it was deleted from rapidshare:( |
Posted: Tue Mar 01, 2011 10:20 am |
|
|
please reupload
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! |
|
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Tue Mar 01, 2011 1:14 pm |
|
|
Better yet:
Quote: | Can you post the latest code in the Code Library area? |
_________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
sebitnt
Joined: 05 Dec 2010 Posts: 5
|
|
![](templates/subSilver/images/spacer.gif) |
subi
Joined: 29 Aug 2010 Posts: 24
|
DS18s20 negative measure |
Posted: Thu May 26, 2011 2:50 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri May 27, 2011 12:30 am |
|
|
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]); |
|
|
![](templates/subSilver/images/spacer.gif) |
subi
Joined: 29 Aug 2010 Posts: 24
|
DS18s20 negativ measure |
Posted: Fri May 27, 2011 12:39 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Got PIC
Joined: 21 Mar 2008 Posts: 10
|
This doesn't work for me.. |
Posted: Mon Jan 09, 2017 7:53 pm |
|
|
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) |
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 09, 2017 11:48 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|