Dallas temperature sensor DS18B20 displays only 185?

I am using an Arduino Sainsmart Nano, hooked up to a uLCD32-PTu for my GUI that simply displays the sensor data and has simple controls for a 2 channel relay. I have 2 Dallas DS18B20 sensors that have been addressed and are using the One Wire library to use only one input pin.

I am using this setup in a vehicle and my problem is that both of my temperature sensors are displaying as either 000 and 000 or 185 and 185 on my LCD, however it is very inconsistent. Sometimes everything works perfectly displaying both sensor's data, but if I simply turn it off and then come back to it an hour later, it almost always reads 185 and 185 again.

If I unplug my slave sensor from the first sensor wiring, sometimes it will read my other sensor on the One Wire line just fine. However if I plug the number 2 sensor back in, I get inconsistent results. I am having a hard time debugging this system and I found this forum ( Why 185F | PICAXE Forum ) where someone had the same problem I am having, but they never said if or how they fixed this issue.

Is this a loose wire connection kind of issue? It's being so inconsistent I'm not really sure what to do next. Has anyone else had this problem or know how to fix it?

Is that temperature Celsius or Fahrenheit?

loose wires can only be checked by you :wink:

Can you post your code?

or better:
Can you minimize the code that still shows the effect?
And post that code?

You might check the pull-up resistor value (usually 4k7 - 10k but you can go down to 1K) and the +5V/GND connections.

The electrical environment of a vehicle it's quite noisy so you have to avoid ground loops and try to use a very good filter for the +5V supply.

Connect those sensors side by side (no extra lines) and try to find out if it's working OK with (any) single sensor and if it's really messed up when both sensors are connected (you might have a defective sensor or the lines are too noisy to allow a standard communication between master and multiple slaves).

First of all, try to use a single ground connection and a good power supply filter..

I am replacing the sensor right now that could be my problem and I'm going to make sure all my wiring connections are a little bit neater and solid and see if that makes a difference. I am positive it's not a problem with my code because this exact same setup worked perfectly on another system I built for another vehicle using the same code. I was just curious if anyone else has had this problem with these sensors before. I may use a different resister if this new sensor does not solve my problem, thanks for the help guys! I'll let you know how it goes

Since you refuse to post your code, one can only guess, but 85 usually means you are simply not getting a reading. This is most commonly a once-only problem caused by you calling for a response before the sensor has had a chance to do its job,. In your case

185 and 185 on my LCD, however it is very inconsistent. Sometimes everything works perfectly displaying both sensor's data, but if I simply turn it off and then come back to it an hour later, it almost always reads 185 and 185 again.

it could be caused by slack wiring or inadequate power. If you see -127 at all, you can be more sure the problem lies there. While the sensors could be suss, there is nothing to suggest that, particularly both of them. You might try testing the rig away from the car.

update: I found one of my sensors wires to have been possibly shorting out due to improper insulation around the connections. I replaced the sensor entirely and my problems were cut in half, however, after a few minutes of running the program, the temperatures being displayed on my LCD just froze at something like 65 and 75 even though the actual temperature was still climbing. I proceeded to reset the device and it kept displaying 000 and then 185 again. After a few more resets it suddenly started working again.
My #1 sensor may be shorting out like the #2 sensor, so I may replace it as well, however I noticed that even though the temps were not being displayed on the lcd screen, the controller was still flipping relays accordingly to the actual temperatures. I avoided posting my complete code until now because I assumed this was some kind of a hardware issue.

Here's my complete code, is there any hang-up in how I'm sending the sensor data to the screen that I missed?

#define CHANNEL1 8 //LowSpeed RELAY
#define CHANNEL2 9 //HighSpeed RELAY
#include <genieArduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 //DALLAS serial sensors go into input 3
// 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);
DeviceAddress coolant = { 0x28, 0x1F, 0x70, 0x66, 0x04, 0x00, 0x00, 0x0B };//LEDDIGITS0 and LEDDIGITS7 RED/BLUE/BLACK
DeviceAddress cooly = { 0x28, 0xB3, 0x58, 0x66, 0x04, 0x00, 0x00, 0xEC };//LEDDIGITS9 RED/GREEN/BLACK

int sliderVal = 170;
int sliderVal2 = 190;

int slider0_val = 190;//Set point for high speed radiator fan
int slider1_val = 170;//Set point for low speed radiator fan 
int humidity, t, temp;

void setup()
{
  pinMode(CHANNEL1, OUTPUT); 
  pinMode(CHANNEL2, OUTPUT); 
  digitalWrite(CHANNEL1, LOW); 
  digitalWrite(CHANNEL2, LOW);
  
  sensors.begin();
  sensors.setResolution(coolant, 10);
  sensors.setResolution(cooly, 10);
  
  genieBegin (GENIE_SERIAL, 56000);  //Serial0 for 4D Display
  
  genieAttachEventHandler(myGenieEventHandler);

  //Reset the Display (change D4 to D2 if you have original 4D Arduino Adaptor)
  pinMode(4, OUTPUT);  // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
  digitalWrite(4, 1);  // Reset the Display via D4
  delay(100);
  digitalWrite(4, 0);  // unReset the Display via D4

  delay (3500); //let the display start up

    genieWriteObject(GENIE_OBJ_LED_DIGITS, 6, sliderVal2);//preset value
    genieWriteObject(GENIE_OBJ_SLIDER, 0, sliderVal2);//preset value
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 8, sliderVal);//preset value
    genieWriteObject(GENIE_OBJ_SLIDER, 1, sliderVal);//Preset value
  
}



void loop()
{
  static long waitPeriod = millis();

  genieDoEvents(); // Do this every loop, checks the input buffer for data from the display and runs myGenieEventHandler()

  //Read from sensor every 100ms and write to the display
  if (millis() >= waitPeriod)
  {
    temp = (t * 1.8) + 32; //Convert *C to *F.
    
    float inside = sensors.getTempF(coolant);
    float outside = sensors.getTempF(cooly);
    
    //float tempC = sensors.getTempC(insideThermometer);
    //insideThermometer = sensors.requestTemperatures(); // Send the command to get DALLAS temperatures
    float tempF;
    
    sensors.requestTemperatures();    
    Serial.println (inside);////////GOOOD CODE 
    Serial.println (outside);///////GOOD CODE AGAIN... YAY!
    
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 0, inside);//The first line of code in the section gets ignored for some reason...?? copy and paste
    genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0, inside);//HOME SCREEN TEMP GAUGE.........FORM 0 
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 0, inside);//HOME SCREEN TEMP..................FORM 0
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 1, outside);//LOW.............FORM 1
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 7, outside);//HIGH............FORM 5
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 9, outside); //HOME SCREEN SENSOR DISPLAY........FORM 0 
    genieWriteObject(GENIE_OBJ_ANGULAR_METER, 1, outside);//HOME SCREEN SENSOR OUTPUT GAUGE.......FORM 0 

    waitPeriod = millis() + 10; // rerun this code in another 100ms time.
 
 
 ///////////////////////////
  if (slider0_val > outside)
  {
    digitalWrite(CHANNEL1, HIGH);
  }
  else
  {
    digitalWrite(CHANNEL1, LOW);
  }
 /////////////////////////////////////////////////////
  
  if (slider1_val > outside)
  {
    digitalWrite(CHANNEL2, HIGH);
  }
  else
  {
    digitalWrite(CHANNEL2, LOW);
  }
 }
 
}

void myGenieEventHandler(void)
{
  genieFrame Event;
  genieDequeueEvent(&Event);

  //If the cmd received is from a Reported Event
  if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    if (Event.reportObject.object == GENIE_OBJ_SLIDER)            // If the Reported Message was from a Slider
    {
      if (Event.reportObject.index == 0)                          // If Slider0
      {
        slider0_val = genieGetEventData(&Event);                  // Receive the event data from the Slider0
      }
    }
  }

 //If the cmd received is from a Reported Event
  if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    if (Event.reportObject.object == GENIE_OBJ_SLIDER)            // If the Reported Message was from a Slider
    {
      if (Event.reportObject.index == 1)                          // If Slider1
      {
        slider1_val = genieGetEventData(&Event);                  // Receive the event data from the Slider1
      }
    }
  }
//////////////////////////////////////////////////////////////////////////////////////////////
  //If the cmd received is from a Reported Object, which occurs if a Read Object is requested in the main code, reply processed here.
  if (Event.reportObject.cmd == GENIE_REPORT_OBJ)
  {
    
    //Put code in here, like the above, if you want to process data when you have used a genieReadObject in your main loop
    //Currently there are none, so this section has no code.
    //Filter out the Object and the Index like above, and then same the data into a variable as required.
  }
}

Hopefully my comment lines aren't too confusing, it's still a work in progress somewhat, but I tried my best to keep it clear and simple.

You may find this is the problem

    waitPeriod = millis() + 10;

but it I'm not clear about what this does and even less clear about why you do it that way. It implies a 10ms delay but, at the resolution you want, you need about 200ms or the sensor hasn't time to do it's job, hence the 85s, and the only time you get sensible readings is when somethihng else gets in and mercifully clogs the system.
I guess the first thing to do is come up with a valid reason for needing readings so frequently. In the unlikely event that you find one, and my understanding is correct, it is time to change to a dumb sensor like a PT500 that can deliver the goods faster.
If you change the 10 to 1000, it might work. Failing that I suggest you rewrite the programme without all that genie stuff, and concentrate on just the Ds18B20s

200ms or the sensor hasn't time to do it's job, hence the 85s,

I like to see the sensors reading data as quickly as possible, however, speed is really not a big deal with my project. Once per second would be fine too, it doesn't even need to be multiple times per second. Should I change it to:

waitPeriod = millis() + 200;

Or should I make it 1000? Which do you think would be more reliable an consistent?
side note: it's displaying "185" not just "85." does that make a difference?

Try moving this:

sensors.requestTemperatures();

Above this:

float inside = sensors.getTempF(coolant);

in your sketch.

Update: I just tried changing:

waitPeriod = millis() + 200;

to 

waitPeriod = millis() + 1000;

and it only took about 2 minutes for it to bug out on me again where before it would last about 10 minutes or so. What's weird is it works perfectly for the first couple minutes of being turned on, but then it freezes the temps at wherever they are on my screen and then when I power off and back on to reset it, no matter how many times I do this, it continues to say 185 and 185. What's up with this? Is something on the board itself reacting to temperature?

Good catch @elac, I will try that now and post results....
UPDATE: Tried moving the code, all my screen showed this time was 000 and 000 no matter how many times I reset it. When I unplug the sensors, the screen shows 32 and 32, but if I plug them back in it's 000 and 000. ???

A simple delay will do, nothing time critical being held up by using delay.
Try this :

void loop()
{
  genieDoEvents(); // Do this every loop, checks the input buffer for data from the display and runs myGenieEventHandler()

  //Read from sensor every 1 second and write to the display
  delay(1000);
  temp = (t * 1.8) + 32; //Convert *C to *F.
  sensors.requestTemperatures(); 
  
  float inside = sensors.getTempF(coolant);
  float outside = sensors.getTempF(cooly);

  Serial.println (inside);////////GOOOD CODE 
  Serial.println (outside);///////GOOD CODE AGAIN... YAY!

  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0, inside);//The first line of code in the section gets ignored for some reason...?? copy and paste
  genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0, inside);//HOME SCREEN TEMP GAUGE.........FORM 0 
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0, inside);//HOME SCREEN TEMP..................FORM 0
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 1, outside);//LOW.............FORM 1
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 7, outside);//HIGH............FORM 5
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 9, outside); //HOME SCREEN SENSOR DISPLAY........FORM 0 
  genieWriteObject(GENIE_OBJ_ANGULAR_METER, 1, outside);//HOME SCREEN SENSOR OUTPUT GAUGE.......FORM 0 

 ///////////////////////////
  if (slider0_val > outside)
  {
    digitalWrite(CHANNEL1, HIGH);
  }
  else
  {
    digitalWrite(CHANNEL1, LOW);
  }
  /////////////////////////////////////////////////////

  if (slider1_val > outside)
  {
    digitalWrite(CHANNEL2, HIGH);
  }
  else
  {
    digitalWrite(CHANNEL2, LOW);
  }
}

@elac I tried using your suggested delay and though on start up it glitched, after a reset it worked perfectly for about 10 minutes of testing and driving the car around. I'm about to take the car for a drive to do something this evening so I will watch how it behaves and update my progress from there

Gustermaximus:
side note: it's displaying "185" not just "85." does that make a difference?

No. It just means the you are probably American - the last place on earth still using fahrenheit. 185F=85C. It's not a problem. The message is the same.

At 10-bit resolution, the conversion time is 187.5ms, so it should be stable with a 200ms loop, but a loop that short is still a dumb idea. You are going to get either no change, or a raft of distracting confusion, causing you to crash the car
** delay(1000);**

Is the common code for getting a delay. Your messing about with millis may work OK, but I don't see the point in doing it that way.

I would suggest you test the sensors out of the car on a bench, using a standard example like the one from Hacktronics. At least then you can prove there is nothing wrong with them - which is probably the case

Update: So last night I drove the car for about 2 hours with breaks in between turning the car and the controller off and on about 3 times and it was interesting to see how the controller reacted to being ran continuously even after it froze the last read temp on my screen or just went to 000 or 185.

It was a cycle of about 15 minutes of a frozen value, but if I just let it run, it would eventually just fix itself and start displaying live temperatures again like it was designed to do. The cycle continued like that through each time I drove the car while running the arduino, but it seemed to have ran without any issue the longest on my way home which was about a 45 minute trip.

Obviously because I was driving by myself and trying not to die or kill anyone else, I could not watch the arduino as intently as I would have liked to, however, I'm thinking it has something to do with how my program is looping that after a certain amount of time it gets confused?

What's good, is that my relays seem to be operating correctly according to the actual temperature of the sensors, regardless of what my LCD says. Should I be checking with 4D systems to make sure I'm sending data to the screen correctly for this loop? I'm starting to wonder if this isn't a sensor problem and maybe just a confusion in my loop

all of the above results were while using the delay 1000 command instead of millis.

How are you driving the relays? Straight from the Arduino pins? Or through transistors driven by the Arduino pins? Links to the relays?
The DS18B20 needs a steady clean power source.
Could you give some details about the whole setup? Picture and/or diagram/schematic would be great.
Could you post the sketch you used in the test last night?

I am using a 2 channel sainsmart relay. 5v, GND and input 1 and 2 are wired directly to the Nano. There is only 1 5v pin on the Nano, so my sensors, the lcd display and the relay 5v pin are all three connected to the single 5v pin on the board. Is that too much to run off the one pin? I would upload a pic with a diagram but for some reason it won't let me.

I am powering the board through a 5v regulator that's connected directly to a 12v wire from an unused cigarette lighter jack.

my relays are powering other larger relays inside the fusebox of my car that are shorted to ground, so I am completing the circuit with a 12v wire straight from the battery into my sainsmart relay which switches my car's relays on/off.

Gustermaximus:
so my sensors, the lcd display and the relay 5v pin are all three connected to the single 5v pin on the board. Is that too much to run off the one pin?

Yes, I would guess this hook up is a big part of your problem with lock up.
Put a 1000uF cap on the output of the 5V regulator and power everything but the DS18B20s from the 5v regulator.
Power the DS18B20s from the Nano board 5V and return their grounds to the board, the display and relay grounds return to the 5V regulator ground.

I have a 100uF cap and a 104 K5Z on my regulator at the moment. Is 100uF good enough, or do I need a 1000?

Basically I'm connecting everything except the DS18B20s to the vin pin on the Nano? and this won't interfere with the board at all?

Is using the same 12v-5v regulator output pin to power the board through the vin pin on my Nano as well as powering the screen and relays going to interfere with power to the rest of the board in any way?

afaik is 1k the minimum, in all wiring schemes are 4k7 shown