Receiving weird results with 4 DS18B20 digital temp sensors??? (85 C, -127 C...)

Hello

I'm working on a project, and I need 4 DS18B20 digital sensors and some solar cells to read temperature changes and amount of sunlight. I don't believe hardware is a problem. And the solar cells are working fine, I had this problem before and after I added the cells. I'm using this code:

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

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

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

// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer, insideThermometer2, outsideThermometer2;

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();
  
  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  // assign address manually.  the addresses below will beed to be changed
  // to valid device addresses on your bus.  device address can be retrieved
  // by using either oneWire.search(deviceAddress) or individually via
  // sensors.getAddress(deviceAddress, index)
  //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
  //outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };

  // search for devices on the bus and assign based on an index.  ideally,
  // you would do this to initially discover addresses on the bus and then 
  // use those addresses and manually assign them (see above) once you know 
  // the devices on your bus (and assuming they don't change).
  // 
  // method 1: by index
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 
  if (!sensors.getAddress(insideThermometer2, 2)) Serial.println("Unable to find address for Device 2"); 
  if (!sensors.getAddress(outsideThermometer2, 3)) Serial.println("Unable to find address for Device 3");
  
  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices, 
  // or you have already retrieved all of them.  It might be a good idea to 
  // check the CRC to make sure you didn't get garbage.  The order is 
  // deterministic. You will always get the same devices in the same order
  //
  // Must be called before search()
  //oneWire.reset_search();
  // assigns the first address found to insideThermometer
  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // assigns the seconds address found to outsideThermometer
  //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

  Serial.print("Device 2 Address: ");
  printAddress(insideThermometer2);
  Serial.println();

  Serial.print("Device 3 Address: ");
  printAddress(outsideThermometer2);
  Serial.println();
 
  // set the resolution to 9 bit
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(insideThermometer2, TEMPERATURE_PRECISION);
  sensors.setResolution(outsideThermometer2, TEMPERATURE_PRECISION);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC); 
  Serial.println();

  Serial.print("Device 1 Resolution: ");
  Serial.print(sensors.getResolution(outsideThermometer), DEC); 
  Serial.println();

  Serial.print("Device 2 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer2), DEC); 
  Serial.println();

  Serial.print("Device 3 Resolution: ");
  Serial.print(sensors.getResolution(outsideThermometer2), DEC); 
  Serial.println();
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  delay(1000);
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
  delay(1000);

  // print the device information
  printData(insideThermometer);
  printData(outsideThermometer);
  printData(insideThermometer2);
  printData(outsideThermometer2);
}

When I upload it to the arduino uno and open the serial monitor. It reads data for each sensor normally giving the temperature in C for every 0.5C (for example 24.00 C, 24.50 C, 25.00 C, 25.50 C etc) However after a while, it randomly says the temp are at 85 C for a split second!! (sometimes -127). After that, the temp comes back to normal, but it gives it out for every 0.001 C!? (example: 24.02 C, 24.67 C, 25.14 C etc). And every once in a while it goes to 85 C for a second,then back to normal. Also each sensor usually does this, sometimes all at once. The picture I attached is an example. In the third row the temperature for the 2 middle sensors jumps at 85.Ignore the 1.72, that's the amount of light in my room.

This never happened with just 2 temp sensors. Thanks!!

Sounds to me there might actually be a hardware problem. The 85 degree response is usually indicative of the first reading after power up. How are you powering the sensors? Too much current draw on that power source may cause brown-outs. Might explain why the problems don't show until you add more devices.

How are the DS18B20s wired up? If you've wired them in parasite mode there might not be enough current to do a conversion reliably.

Pete

Like the other guy said, 85C is the register value after a power reset. I'll add that -127 is what you would read from the bus if the device didn't respond. All together sounds like devices whacking out from not quite enough power to accomplish the temperature conversion operation.

Okay so it's happening with only 2 sensors, it must be because of the setup since it was happening on the breadboard.

Pete: it's not in parasite mode because when I open the serial monitor, it says parasitemode: off,

I'm not quite sure if it's because of lack of power, since it's happening with just 2. When before, 2 worked fine on the breadboard. However, after it jumps to 85 C, they still work perfectly fine. Just they're more accurate to every 0.01 C instead of 0.5. I actually would't mind if data continues being collected with the more accurate measurements (even if they jump back up to 85 every once in a while) and maybe that's what they're supposed to do? But I also don't want anything to fry or go whilewhen Im collecting data, because data collection for my project is going to take months.

I've heard that sensors such as the DS18B20 can have inaccurate readings if you are drawing too much power (i.e., you also have a servo motor attached to your motor.) In addition, some of the Chinese remakes of Arduino don't put out a full 5V, but more like 4.7 or 4.5. Could either of these be your problem? You might want to check how much voltage your Arduino is putting out.

I think this could even happen with 2 sensors.

We need to know how you have it physically wired up. Do you have +5V, GND and DATA going to each sensor? What value pull-up resistor are you using on the DATA line?

I have a bunch of these sensors on one of my projects and I've seen the same thing (I'm not using parasitic power). So I just test for a valid temperature, if it fails I use a 50mS delay then re-read the sensor. Seems to work okay. I'm not sure if the delay does any good, but it doesn't hurt for what I'm doing.

ScottG:
Seems to work okay. I'm not sure if the delay does any good,

I think it does. I understand the DS18B20 is fine in loops of about one second but need time to settle down after sending data. I think -127 signifies the the sensor isn't connected but I guess inadequate power means much the same thi9ng.

After the 85 readings, you're getting more precision, which suggests that the device reset and reverted to 12 bit precision. Which could well be a power issue. Are you running long cables to these sensors?

Okay so I have the sensors all set up like this --> http://bildr.org/blog/wp-content/uploads/2011/06/DS18S20-hookup.png
They're all connected to the same digital pin (2) and they all have 4.7k pullup resistors on their data line

And yes the cables are long, good point. I have 1 sensor directly connected on the board, one waterproof sensor connected to a 6 foot long cable and the last 2 are on a approximately 12-foot cable that branches out at the end. Hope this helps, please ask if you want a clearer picture of the hardware setup, it's kind of complicated.

Thanks again!

There's only supposed to be one pullup resistor, not one per DS18B20. Also, for longer runs, you may want to make it a bit smaller.

The resistance or the cable length?

The resistance. The cable length adds it and so, if you're forced into long runs, a way to compensate is to reduce the size of the primary resistor.

Simax:
And yes the cables are long, good point. I have 1 sensor directly connected on the board, one waterproof sensor connected to a 6 foot long cable and the last 2 are on a approximately 12-foot cable that branches out at the end. Hope this helps, please ask if you want a clearer picture of the hardware setup, it's kind of complicated.

I have three DS18B20 on 6m cable. All the rest are 3m. I don't think cable length is your problem.

Only one pull up is required. I have seen no need to change from the regular 4k7 with these lengths.

It may still be a power problem. If you are using the USB cable for power, the first thing to do is get a 9v wall wart. No wait: If you are using USB cable from the front panel, the first thing to do is plug it in the back of the motherboard. It is often a better source of power

Thanks for your answers, I thought I had the problem solved after playing around with the resistor and finding that 3 worked perfectly. But now none of the temp sensors work at all. And I have no idea since it was completely out of the blue. Here's the new thread Ds18b20 temp sensors suddenly stop working? Solarcells losing V in daylight? - Project Guidance - Arduino Forum

thanks for lending your hand once again.

Want to add to this,

Got the code to work in 1.06 Arduino (Replacing WConstants.h headers in the DallasTemperature.cpp and OneWire.cpp helped) and had the same issue where I would only get -127.00 readout on serial.

My adding a short delay(10) to the loop, it solved the problem immediately, getting accurate temp readouts now. Thanks for the tip!

-127 is the error code indicating the sensors are not connected. I guess maybe this means you took only 1/100th of a second to plug the sensor in.