Go Down

Topic: Problem with DS18B20 OneWire and long cables (Read 56912 times) previous topic - next topic

Tuxdiver

Apr 13, 2009, 10:54 pm Last Edit: Apr 13, 2009, 10:56 pm by Tuxdiver Reason: 1
I tried to build a temperature sensor with a few DS 18B20 distributed in the house. So I build the needed 4k7 resistor on a breadboard and connected the 3 required cables to a RJ45 patch panel, using pins 1=5V, 2=Data, 6=GND.
This works perfect when the sensors are "near" the arduino. A few meters is no problem, every sensor delivers perfect data, so sketch and cabling seems to be OK.

Then I tried to put one sensor more far away, using the cables in my house. But then nothing works anymore, there are no readings anymore.

The OneWire-Bus seems to crash, when cables are too long. There are some documents on the MAXIM-Website concerning a long-range network, but it is also statet, that it might be possible to change the timing a bit.

I already tried to tune the "read_bit" timings a little bit:  I again get values from the sensors, but these values are wrong (bad CRC).

Has anyone build a network with a longer range / weight and One-Wire-Bus?

edit: some pictures and a german description can be found here: http://camino.dirk-melchers.de/2009/04/12/arduino-temperatur-sensor/

Easty

Can't read German so not sure how you have the wiring configured... sorry.

I found some problems with a 10m single run with a temperature sensor, A to D converter and a counter at the end, I had to use a 2k2 which seemed to cure the issues.

It may help. Easty.

Tuxdiver

Sorry - I just translated the page to something like english :-)

I tried it with 2k instead of the 4k7 - but that did not help. The read values are not that random any more, but closer to "FF" then... :-(

But thanks for your help!

Easty

Is it definately cable length? Does a single sensor work when on the breadboard?

Tuxdiver

Yes, it works without any problems: when connected directly to the breadboard, when connected to the patch panel directly, but not when connected over about 20 or 30m of CAT-5 cable.

The problem can be triggered without a problem here: connect one sensor directly to the patch panel - data is ok. Connecting the second to the other patch panel port - data of all sensors corrupted.

here: http://www.maxim-ic.com/appnotes.cfm/an_pk/148 are some information about large networks and I will try to improve the "sending" part a bit...

Tuxdiver

Problem is fixed - a least, I get values for a few hours now...

Here's the patch to OneWire.cpp:

Code: [Select]

--- OneWire_orig.cpp    2008-05-20 02:10:54.000000000 +0200
+++ OneWire.cpp 2009-04-14 19:30:58.000000000 +0200
@@ -115,8 +115,8 @@
// more certain timing.
//
void OneWire::write_bit(uint8_t v) {
-    static uint8_t lowTime[] = { 55, 5 };
-    static uint8_t highTime[] = { 5, 55};
+    static uint8_t lowTime[] = { 60, 8 };
+    static uint8_t highTime[] = { 8, 60};
   
    v = (v&1);
    *modeReg |= bitmask;  // make pin an output, do first since we
@@ -137,7 +137,7 @@
   
    *modeReg |= bitmask;    // make pin an output, do first since we expect to be at 1
    *outputReg &= ~bitmask; // zero
-    delayMicroseconds(1);
+    delayMicroseconds(3);
    *modeReg &= ~bitmask;     // let pin float, pull up will raise
    delayMicroseconds(5);          // A "read slot" is when 1mcs > t > 2mcs
    r = ( *inputReg & bitmask) ? 1 : 0; // check the bit


As you can see, I had to adjust the timing a little bit. As far as I understand the specifications, I think the original timings in OnwWire.cpp are at the minimum allowed. I now put the values a little bit more to "safe" mode ;-)

And I also had to replace the 4k7 resistor with a 2k2.

I'm not sure how to contact Tom - maybe he is reading this post ;-)


Easty

Glad you got it sorted. Thanks for updating us!

Easty.

cf20852

I had the same problem using a Cat5 cable about 80 feet/24.25 meters long, powering a single DS18B20 with 5V and using a 4.7k resistor on the far end of the cable.  In the version of the OneWire library I started with, the read_bit() timing was set to pull the data line low for 1 microseconds then high for 5 microseconds before reading the bit sent back from the DS18B20.  I found that pulling the data line low for 2 microseconds then high for 7-15 microseconds made it work reliably.  Then I tried the Version 2 library, which pulls the data line low for 3 microseconds then high for 9 microseconds before reading the bit.  This seems to work fine as well.  I suspect the problem is that the time constant of the 4.7k resistor multiplied by the capacitance of the cable results in a slow rise time of the data line and consequently reading 1 bits as 0s.  But I don't have my o'scope here to test that hypothesis.

Tuxdiver

Yes, that were my thoughts, too. I also did not have a o'scope to "see" the signals...  :(

I installed some DS18B20 in the house some month ago using long Cat5 cables and the OneWire2-Library. That fixed the timing problem - so the above patch is not needed anymore, but I still had to use the 2k2 resistor.

cf20852

The 18B20 datasheet says that the sink current for logic low, IL, is 4 mA at VI/O = 0.4 V.  So when the power supply is 5.0 V, I think you should be able to get away with a pullup resistor as low as 1k2.  The lower the value of the pullup resistor, the faster the rise time of the open-drain output of the 18B20 should be.  Also, the characteristic impedance of CAT 5 cable is 100 Ohms, so you get a somewhat better impedance match for the high state with a 1k2 resistor than you do with a 4k7 resistor, esp. with the resistor at the far end.  Interestingly, the 18B20 datasheet shows that the output FET is a 100 Ohm MOSFET (see Figure 10), so it looks like it is matched to the cable impedance, at least for driving the output low.

For others reading this, I think the minimum pullup resistor for a single OneWire signal is about 1k2, but I haven't tested this to see if it will work.  If you have cables from the Arduino board to several sensors, wired in a hub-and-spoke configuration, with the Arduino at the hub and with pullup resistors to 5V at the far end of each spoke, the minimum equivalent parallel resistance should be 1k2.  You can also put it at the Arduino end, but that might not work as well.  You could also have a resistor at each end of the cable (assuming you send 5V to the far end), in which case the minimum equivalent parallel resistance is still 1k2.

The weak link in pulling down the data line seems to be the 18B20--it looks like the ATmega328 can sink about 14 mA at 0.4 V at 85 C (Figure 29-304 in the ATmega48A/48PA/88A/88PA/168A/168PA/328/328 datasheet) vs 4 mA for the 18B20.

Note that the lower the pullup resistor value, the more current the 18B20 has to sink when driving the line low, which will increase its power dissipation slightly, resulting in a little more self-heating.

But maybe I'm over-analyzing  :-? All that having been said, the important thing is that it works, and it's been a fun project!

JDuggan

I'm using an Arduino Fio as the master for a DS18B20, which provides 3.3V instead of 5V. I have successfully received accurate temp readings from the DS18B20 in parasitic power mode using a 4k7. When I try switching to direct power mode though, the Fio seems to crash/lockup. The RX/TX lines on the USB explorer board that I have connected to the Fio light up and the heartbeat led I have blinking on D13 goes dark. I'm using Arduino 021. The DS18B20's data sheet says Vdd can be 3V-5V, but I'm wondering if running at 3.3V could create issues with the timing. I would expect it to just give me bad data though, not lockup. Any help would be greatly appreciated. Thanks!

tkbyd

I've done more with 1-Wire using dedicated interfaces rather than connecting the device to my Arduino, but I suspect the same principles will apply....

a) You are better off NOT using parasitic mode. The modest extra "trouble" is well worth it.

b) Use cat-5 cable

c) The "magic resistor" (mentioned above) often helps. The right value? Use a little trial and error!

d) Be sure to put multiple 1-Wire chips in a daisy chain, not a "star"... i.e. ONE run of two wires, with 1-wire chips across it, like the rungs of a ladder.... do NOT have several wires leading out from where your Arduino is, with 1-Wire chips on each of the several "rays" of the "star".

I have tested strings of three or four 1-Wire temperature sensors on cat-5 cables of up to... umm, from memory... 40m? They WILL work! But as I said... this was with 1-Wire adapters.

More on 1-Wire wiring, and links to other stuff, at...

http://sheepdogsoftware.co.uk/sc2wm.htm

(Includes note on "magic resistor")

Go Up