DS1820 wire length--one-wire code [Solved]

I have noticed that when adding DS1820s on separate wires to a single Arduino port, at some point they stop working, at about 20-25' of total wire length. All DS1820s work fine individually or when paired with any other device. Sometimes with long (16') wire the failure happens with 2 or 3 units. With shorter wire it's 3 or 4.

The question is, can I compile the one-wire code multiple times with a different port definition so that I can connect the sensors to multiple ports, thus reducing total wire length on each port?

The wire runs are long-ish because they are sensing the concrete temperature in a radiant heat floor and coming back to a common control panel. The 1/2" tubes for the sensors are already placed in the concrete, so wire length is set. I have noticed that the failure happens with shorter total wire length when I'm using a 4-wire, 22 gauge jacked cable and substantially longer total lengths when I use 24 gauge wire pair unjacketed telephone wire. So it's not wire length--I am assuming that it's total cable capacitance that's causing the problem.

The question is, can I compile the one-wire code multiple times with a different port definition so that I can connect the sensors to multiple ports, thus reducing total wire length on each port?

Yes. In fact there was a post in the last few days where someone preferred to wire up their sensors this way.

I'm plowing through the Programming and Sensor threads, but haven't found the post you refer [yet].

However, I may have solved my problem. Most of the one-wire topologies are limited to 100 m, maybe 150 in some topologies. The secret seems to be, for star and ladder topologies in particular, that you add 4.7K resistors for each wire. Makes no sense to me, since all the wires in a star are shorted together at the port pin, but it works. I tested it and suddenly I'm reading 3 sensors instead of only one.k

I still want to know how to read sensors on separate port lines. The quirk of using the one-wire library code is that it reads the sensors in order of address. If you change or add a sensor, the order of your existing sensors may or may not be disrupted and you display no longer correct.

This is the thread I was thinking of: http://forum.arduino.cc/index.php?topic=213168.0

I presume you are using the DS18B20. If you aren't using one of the temperature alarm registers you can use it to store your own label. Both alarms are an 8 bit register that is backed up in EEPROM. You can write your own label into each of your ds18B20 and use that to identify them. If one dies, get a new one, give it the same label, install it and away you go. Also, see this thread: http://forum.arduino.cc/index.php?topic=216835.0 Starting at message #14 I mention the same method.

Pete

Dr_Quark: The secret seems to be, for start and ladder topologies in particular, that you add 4.7K resistors for each wire. Makes no sense to me, since all the wires in a star are shorted together at the port pin, but it works.

I found that with a longer bus you need to reduce the pull-up resistor. With a 50m bus I had to go to 3K3 I think. When you put more pull-ups in parallel, you effectively lower the pull-up resistor -- increasing the bus current. High bus current leads to greater self-heating in the sensors, so that's the down-side.

I also found that, although it's supposed to work fine, a 3.3V (or 3.5V) bus just wouldn't work for me past 10m or so. A 5V bus was okay.

The 1-wire network design write-ups I've read discourage star topologies. If you need a star, then you should run N different buses out from different pins on the Arduino. I've done this and it's fine.

I’d like to do N 1-wire buses attached to N pins. The code (in the code example below) runs fine on pin 4. I see that the bus “oneWire,” which is defined on pin 4, is passed to the Dallas code here:
DallasTemperature sensors(&oneWire);

It is not apparent to me how to define a second bus and pass that to Dallas. Maybe I’m not aware of all the commands available in the Dallas software, but it seems to me that the command
sensors.requestTemperatures()
only refers back to the oneWire bus that was defined earlier. In the example above, can I make a second Dallas bus by defining a second 1-wire bus as “oneWire2,” say on pin 5, and then doing:
DallasTemperature sensors2(&oneWire2); ???
If so, is the second bus read by doing:
sensors2.requestTemperatures()

// Load Libraries
#include <Wire.h>
// Load Libraries for DS1820 and OneWire
#include <OneWire.h>
#include <DallasTemperature.h>
 // Data wire is plugged into pin 4 on the Arduino
#define ONE_WIRE_BUS 4
 // Setup oneWire instance to communicate with devices
OneWire oneWire(ONE_WIRE_BUS);
 // Pass oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
// ---------------- SETUP ---------------------------
void setup() { 
// Start the OneWire library
  sensors.begin();
 ...
 }
// ---------------- LOOP ----------------------- 
void loop() {
  readtemp() ;
// serial transmission stuff here
... 
}   // end of Loop
//-------subroutine---------------------------
void readtemp(void) {
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
float mytemp1 ;
float mytemp2 ;
float mytemp3 ;
float mytemp4 ;

  sensors.requestTemperatures(); // Send the command to get temperatures
  mytemp1 = sensors.getTempCByIndex(0) ;
  mytemp2 = sensors.getTempCByIndex(1) ;
  mytemp3 = sensors.getTempCByIndex(2) ;
  mytemp4 = sensors.getTempCByIndex(3) ;
...

In the example above, can I make a second Dallas bus by defining a second 1-wire bus as "oneWire2," say on pin 5, and then doing: DallasTemperature sensors2(&oneWire2); ???

I believe that's how to do it, but you do have the source of the libraries if you want to poke around and check, or you can just try it...

I just tried it, as in, I decided it would be faster to write the code and load it into a Nano on a breadboard than to plow through the library. Works great.

I'm reading one DS1820 on each pin 4-5-6-7. The only downside I've noticed is that the read is slower. It dropped from about .8 sec per cycle to a little over 2-1/2 seconds. I assume the requestTemperatures() command has a delay to allow for a 12-bit conversion, which can take up to 750 ms. I now have 4 of those commands in the code instead of the original 1. Using 4 sensor channels increased the code size by only a few bytes.

The other downside is you need 4 pullup 4.7K resistors.

This thread got started because of an issue with wire length. Here's a link sent by another member about long 1-wire networks and some thoughts on different topologies. http://www.maximintegrated.com/app-notes/index.mvp/id/148 My network was a star with radius of 17 m and weight of about 50 m, so it wasn't very big. The lower value (2.2K) pullup solved the wire length problem, but for maintainability I think using separate pins for the four sensors is the better way to go.

The only downside I've noticed is that the read is slower. It dropped from about .8 sec per cycle to a little over 2-1/2 seconds. I assume the requestTemperatures() command has a delay to allow for a 12-bit conversion, which can take up to 750 ms.

setWaitForConversion can allow you to do the read asynchronously.