Connecting 8 x DS18B20 to MEGA2560

I am experimenting with connecting 8 x DS18B20 temperature sensors to an Arduino MEGA 2560 (before I include them in my main project). I'm using the water resistant DS18B20's, 5 on a 3 metre cable and 3 on a 1 metre cable.

I started by getting the individual address of each DS18B20 by connecting each one to the MEGA individually and using one of the available sketches for that purpose. Each DS18B20 returned its address and temperature correctly.

I then connected all the DS18B20's together by soldering all the red wires, black wires and yellow wires together, put them into a connecting block, then into a breadboard with a 4.7Kohm resistor between the +ve 5v and the yellow data pins, then into the MEGA.

I am using the (c) 2010 Mark McComb, hacktronics LLC sketch, modified, for reading these sensors. The sketch is returning the correct name I've given for each sensor, but all the temperatures are coming back as 0.00 C .

//  temperature sensors.
//  Copyright (c) 2010 Mark McComb, hacktronics LLC
//  License: http://www.opensource.org/licenses/mit-license.php (Go crazy)
//  Tutorial:
//  http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 10 on the Arduino
#define ONE_WIRE_BUS 10

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the unique addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress intakeThermometer = { 0x28, 0x9E, 0xC2, 0x97, 0x1F, 0x13, 0x01, 0x88 };
DeviceAddress exhaustThermometer = { 0x28, 0xAA, 0x68, 0xF7, 0x17, 0x13, 0x02, 0x60 };
DeviceAddress supplyThermometer = { 0x28, 0x38, 0x4F, 0x95, 0x1F, 0x13, 0x01, 0x46 };
DeviceAddress extractThermometer = { 0x28, 0xAA, 0x03, 0xF0, 0x17, 0x13, 0x02, 0x87 };
DeviceAddress evaporatorThermometer = { 0x28, 0x7D, 0x2A, 0x8D, 0x1F, 0x13, 0x01, 0x3F };
DeviceAddress supplybetweenHECondenserThermometer = { 0x28, 0xA1, 0x38, 0x45, 0x92, 0x12, 0x02, 0x08, };
DeviceAddress exhaustbetweenHEEvaporatorThermometer = { 0x28, 0x08, 0x3E, 0x45, 0x92, 0x12, 0x02, 0x5E, };
DeviceAddress atticspaceThermometer = { 0x28, 0xDB, 0x33, 0x45, 0x92, 0x12, 0x02, 0x2F, };

void setup(void) {
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(intakeThermometer, 10);
  sensors.setResolution(exhaustThermometer, 10);
  sensors.setResolution(supplyThermometer, 10);
  sensors.setResolution(extractThermometer, 10);
  sensors.setResolution(evaporatorThermometer, 10);
  sensors.setResolution(supplybetweenHECondenserThermometer, 10);
  sensors.setResolution(exhaustbetweenHEEvaporatorThermometer, 10);
  sensors.setResolution(atticspaceThermometer, 10);
}

void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    Serial.print(tempC);
    Serial.print(" C");
    // Serial.print(" F: ");
    // Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop(void) {
  delay(2000);
  // Serial.print("Getting temperatures...\n\r");
  sensors.requestTemperatures();

  Serial.print("Intake: ");
  printTemperature(intakeThermometer);
  Serial.print("\n\r");
  Serial.print("Exhaust: ");
  printTemperature(exhaustThermometer);
  Serial.print("\n\r");
  Serial.print("Supply: ");
  printTemperature(supplyThermometer);
  Serial.print("\n\r");
  Serial.print("Extract: ");
  printTemperature(extractThermometer);
  Serial.print("\n\r");
  Serial.print("Evaporator: ");
  printTemperature(evaporatorThermometer);
  Serial.print("\n\r");
  Serial.print("Supply X: ");
  printTemperature(supplybetweenHECondenserThermometer);
  Serial.print("\n\r");  
  Serial.print("Extract X: ");
  printTemperature(exhaustbetweenHEEvaporatorThermometer);
  Serial.print("\n\r");    
  Serial.print("Attic: ");
  printTemperature(atticspaceThermometer);
  Serial.print("\n\r\n\r");
}

They should all be returning around 17.0 C .

Could this be an issue with my using 5 x 3 metre and 3 x 1 metre lengths? Or reflections from my soldering? It's strange that the sketch is seeing all the sensor addresses, but not the temperatures.

Where is the soldering, photo doesn't show any.
May I suggest to try the library example sketch instead of some 15years old code.

@spike524895

I have written a DS18B20 library that supports 1 device per IO pin. As you are using a MEGA2560, you have plenty of IO pins, so it might be worth the look..

This library makes connecting easy as you do not need to have the addresses of the sensors. The IO pin determines if it is “intake” or “exhaust” or …. The example to look for is DS18B20_two_sensors.ino which could be extended to 8 devices.

Advantage of this setup is that if one sensor breaks, you can replace it without needing to chance the address in the code (no compilation needed). Furthermore one broken sensor does not “corrupt” the signal of the other ones as every sensor has its own IO pin. Might be more robust in that sense.

The library implements a compatible subset of the “DallasTemperature.h”, so the learning curve is (should be) small.

Give it a look.

Not necessarily, but I think it was bad idea all the same. Strange things can happen with the wiring but that should not be the case here. I'm assuming the wiring is kosher in that your sensors came with quality wiring, and 3m is not overly long. Also I have never heard of a water-resistant DS18B20 that is a fake. Nonetheless, mixing 3m cable with 1m in a star pattern could be a problem and it might pay to clip off the soldering and try working with fewer sensors, all of the same length. I say this particularly because I am only aware of two error signals, -127 for no connection, and 85 for insufficient conversion time. I think getting 0.00 is weird.

The most sensors I have used is six, all 3m cable.

Also, there is nothing lacking with the Hacktronics tutorial. I have used it since it came out, and I defy anybody to find a code that is manifestly more up-to-date. However I'm sure that code tells you to put the sensors on pin 3, not 10. Now I don't know if this is a mechanical requirement, or maybe something secret in one of the libraries, but it is the only pin I have ever used, and I suggest you do the same. It just might work.

Note that you can always take the coward's way out and dispense with the one wire bus - you surely have enough pins(!)

If the sensor readings are 0, then the CRC is also 0 and the program considers the readings to be correct :wink:

I suppose I should have said "I think getting 0.00 when the real temperature is 17, is weird."

This means that the program does not accept data in variables 0, their CRС 0
What's called "receive it, sign for it"

P.S. I have an idea why this happens, but @robtillaart knows for sure :wink:

You will get 0.00 C when the data pin stays LOW, so when there are no pulses at all.
(one dead sensor can corrupt the whole one wire bus, other causes are possible)

When the DallasTemperature library reads the sensor the “scratchpad (variable to hold the internal registers of the DS18B20)” will all be zero. This gives a temperature of 0 and a CRC of 0 which matches.

@spike524895

Can you two calls in your code after sensors.begin()?

  • uint8_t DallasTemperature::getDeviceCount(void)
  • bool DallasTemperature::verifyDeviceCount(void)

What value do they return?

Try a stronger pull-up: 3.3k or even 2.2k.

ETA: also, check if counterfeit: GitHub - cpetrich/counterfeit_DS18B20: How to tell original from fake DS18B20 temperature sensors. (Probably not the issue since they work ok one-by-one…)

I didn't write that the code is not valid. But if the library has been updated ten times back then, library example code would generally be my first choice.

Everything about these sensors has been discussed hundreds of times, there's nothing more to say. I don't think there's any point in challenging them.
Data from these sensors can even be obtained manually.

Thanks for the lively discussion everyone. The problem has been solved by changing the resistor to 2.4Kohms, the only one I've got immediately to hand. So special thanks to DaveEvans.

I'll have an experiment with the rest of the advice given. Thanks all.

Doesn't look like your "set resolution" worked, I see 17.69 (11/16) and 17.06 (1/16). Resolution 10 should be 1/4 degree or even multiples of 0.25 degrees (17.25, 17.5,17.75, etc.).

Use the robtillaart's suggestion or have a look at post #15 " Multi Sensor Example" DS18B20 Reliable Reading Methods – Practical Implementation to Avoid Errors and Invalid Values - #14 by InquisitiveMind