1-Wire, DS18B20... How do I search the bus?

I have 5 DS18B20's hooked up to my Arduino. I am trying to scan the bus once, store all the addresses, then move on in the code. I cant even seem to get the basic scan to give me the 5 addresses. It works fine with up to 3 devices, any more and it endless loops. It never finishes. Any ideas?

void loop(void) 
{
  byte i;
  byte present = 0;
  byte done = 0;
  byte data[12];
  byte addr[8];

  while ( !done )
  {
    if ( ds.search(addr) != 1) 
    {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      done = 1;
      return;
    }
    else
    {
      Serial.print("Unique ID=");
      for( i = 1; i < 7; i++) 
      {
        Serial.print(addr[i], HEX);
        Serial.print(":");
      }
      Serial.println();    
    }
    delay(100);
  }
}

From the console out:

Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:
Unique ID=DE:E3:F6:1:0:0:
Unique ID=9E:C1:F6:1:0:0:

There is a bug in the OneWire library that creates the problem you are experiencing. The best way around this is to find the addresses of all the sensors one by one, and directly use these addresses to interface with your sensors.

I was afraid fo that.

I played around with the library to see I could find the bug, but I don't have enough 1-Wire devices to actually reproduce this problem. So I'll need your help. Could you see if the following change fixes it? Just open the library's OneWire.cpp file, and comment out line 268.

What's the bug? Where's it detailed? I ran into a problem where I was unable to resolve more than three devices on the bus, but I thought that was due to a poor wiring job on my part (I have DS18B20s running all over my house with some hefty wiring runs). I was getting CRC errors when scanning the bus. Is that what's happening here? I see that the sample code above isn't performing a checksum...

To my knowledge nobody has ever posted what the bug is exactly. I've made a best guess by "simulating" a bunch of 1-Wire devices in C# and ported the OneWire library search code across and debugged it there. In my simulation commenting out that line makes the search algorithm work (otherwise it loops between two devices in the same way shown in the first post of this thread).

I don't believe this bug has anything to do with CRC errors. That must be a different issue. Maybe you need try a different pull-up resistor? Try a 2k or 1.5k resistor (don't go lower than this).

I got around the problem by using two 1-Wire buses. :slight_smile:

I have experienced the same problem with search not terminating when there are more than four devices on the wire. Last night I put together a test system, demonstrated it has the same problem, studied the signaling with a scope, and tracked the problem to what appears to be a misplaced statement, line 268.

The logic is complex enough that I want to go through it again with a clear head. I would like to know more about Waffle's simulation. What search tree configurations did you simulate? I ask because I suspect some missing flag initialization which removing line 268 does not address.

Kudos to Waffle, and to my friend Wayne, for their assistance tracking down this problem.

FWIW, I currently have 4 1-wire devices hooked up to my Arduino,
2 1820's and 2 18B20's and have not had a single problem although
the distance between the Arduino and my sensors is about 6-inches (15-cm).
[Yeah, I know, not very useful 'cept for testing the sensors]

Longer runs will probably require a stronger pullup resistor (lower
resistance) on the data line (I'm using the standard 4K7-ohm resistor)
and probably low-capacitive cabling like CAT-5 or 5e. Longer runs
may possibly preclude the use of parasitic power and require Vcc to
be brought down the cable as well.

Dallas Semi (now part of Maxim IC) has a number of documents with
regards to longer 1-wire network cabling if that's what you're dealing
with.

Rusty -- Can you hook up a couple more devices and see if search still works? I found that the OneWire search code would fail when adding the 5th or 4th device, depending on which devices were already on the bus. I assume this is because the particular id bit patterns lead the search algorithm toward or away from the faulty logic. Perhaps having two different device codes is protecting you from the faulty logic too. -- Ward

Ward,
I've dumped 4 1820's and 2 18B20's onto my Arduino. I'm having no
problems with the search algorithm although search() is only called
after a system reset/powerup. Parasitic power is NOT used and the
data line has a 4k7 ohm resistor pulling it up to +5v.

I have now commented out line 268 as suggested by Waffle, deleted the OneWire.o file to cause a recompile, and tested the revised code with seven devices. It works.

For those who might want to duplicate this fix, here is a print out of the area in question with the commented line in place.

263 } else { // we are blazing new tree, take the 0
264 a = 0;
265 searchJunction = i;
266 done = 0;
267 }
268 // lastJunction = i;
269 }
270 if ( a) address[ ibyte] |= ibit;
271 else address[ ibyte] &= ~ibit;

I had the same problem as soon as I added a 6th device to my prototype DS18B20 network (parasite powered). Only 2 devices were affected; as soon as I removed either of them, the search function worked properly. The symptom of the problem was a search that endlessly cycled between device 28 C6 and 28 5E

My devices (all values in hex):

28 78 09 06 02 00 00 92
28 1C 23 02 02 00 00 C6
28 C6 0D 06 02 00 00 99 <-- remove either device 28 C6
28 5E FB 05 02 00 00 3B <-- or device 28 5E for search to work
28 01 47 02 02 00 00 D9
28 D9 FF 05 02 00 00 4B

Once I commented out line 268 and recompiled the OneWire library, all devices work fine.

Rx

YAY! Thank you.

This is great, I was stuck with the same problem: I could connect the AAG weather station (3 sensors) but when i tried to add one more ds18s20 the search program got in a loop.
Thank you for the detailed solution.

I've been banging my head over this problem for two days now. I finally wised up and decided to check the forums. :o

My problem manifested itself only when I recompiled the OneWire.cpp source code. I finally figured out that if I linked to the supplied object file, everything worked fine. I guess the problem must have gotten fixed at some point, and the OneWire.o file updated in the library, but not the source.

How can we get the source code updated in the library so others won't experience this? I sure would like to have those two days back!

Has there been a long term fix for this issue at this time?

I have a bus of 10 DS18S20s and the arduino still gets confused and goes into a loop in the same way mentioned my the original poster.

When I put 4 on the same bus it seems to work okay, when I put 6 on the same bus it works for a bit then goes into a loop, when I put 10 on a bus the whole thing just goes into the loop.

I changed the OneWire.CPP file as advised above and made sure the object file was removed and recompiled.

I cant split the bus up into 2 by 5 sensor buses because at least one of the sensor loops has already been installed during construction and its got more than 10 sensors on it already in difficult to re-wire locations.

crunch, I've re-coded the search function from the ground-up. Hopefully this fixes the bug once and for all. You can download this new version of the library here: http://waffle.netlogistics.com.au/arduino/OneWire8.zip

Let me know how it goes. If it works I'll update the playground article.

Waffle,

This works better, but not perfectly. Now I can have 6 sensors on the bus if I swap a new one in it will be detected.

No more addresses.
Unique ID=2C:EF:4:1:8:0:

Unique ID=52:F9:39:1:8:0:

Unique ID=41:7F:39:1:8:0:

Unique ID=5D:F9:39:1:8:0:

Unique ID=CB:B:5:1:8:0:

Unique ID=FB:E8:38:1:8:0:

No more addresses.

If I insert a 7th sensor

No more addresses.
Unique ID=2C:EF:4:1:8:0:

Unique ID=52:F9:39:1:8:0:

Unique ID=41:7F:39:1:8:0:

Unique ID=5D:F9:39:1:8:0:

Unique ID=CB:B:5:1:8:0:

Unique ID=1B:0:0:0:0:2:   <--- Point I put the new sensor onto the bus

Unique ID=1B:0:0:0:0:2:

Unique ID=1B:0:0:0:0:2:

Unique ID=1B:0:0:0:0:2:

The above will just continue in an infinite loop.

Is there any more information I can provide for you to help?

Can you give me the seven addresses (all eight bytes of each) of the devices when placed together that cause the loop problem? Then I'll be able to test the search algorithm on that combination of addresses to work out where the problem is.