DS18B20 Dallas Temperature readings jumping high at random intervals

I’ve been experiencing this same issue with my DS18B20 on 0.4.5 using https://github.com/Hotaman/OneWireSpark. Pretty much took my routines straight from his examples.

Temperature reads 76 most of the time, I was getting the occasional 131, and have been seeing 31 recently. I had chalked it up to a weak connection on my breadboard :smile:

Update - After letting it run on 0.4.4 and only getting a few high jumps in a weeks time, I just updated to 0.4.6 and already gotten 2 jumps at 134F in the last 2 hours with room temp @80F. not even using floats
:frowning:

Report from pushingbox, you can see frequency of temp jumps. Jump temp is always 58F greater than current temp.

I have a few DS18B20s laying around, I’ll throw my core code onto a photon and see if I get the same results. I use the libs on @krvarma’s github.

Updated history …

I’ve had mine running for a bit today and no jumps but getting 31.89 or -0.06 which I believe is no data. It is fairly regular so going to have to dig…

Here are the CRCs from a good read and a bad read. Really need one of the smart guys like @bko or @peekay123 to help decipher this though. I also get random FFFFFFF which becomes 31.89 as well, more common than the high value for me.

CRC=8D
71.37
Publishing now.
5E 3 4B 46 7F FF 2 10 8D

CRC=F7
128.98
Temp is high: 128.98
17:51:36
5E 1 4B 46 7F FF 2 10 8D

… and there’s the +57 degree difference! :smile:
I get a very occasional 30F reading. I only check for a high temp, and don’t check for a low temp so it may only be when the bad read immediately precedes my 30 second publish.

Could it be that the photon is just too fast compared to the core for the same loop?

Hi @LukeUSMC and @MisterNetwork

The way the CRC works in these parts is that you calculate the CRC of lasered address and compare it to the last byte and they should match. You can see in your two examples that in the first one, 8D matches 8D but in the second one, F7 is calculated because the second byte has been changed from 0x03 to 0x01 and the calculated CRC does not match 8D.

The best thing to do is have your software discard any data where the calculated CRC does not match last byte of the address.

I am thinking you have an electrical problem.

  • Are you using parasitic power with two wires data/power and ground to temp sensor? If so, you should try with three wires, power, ground and data.
  • You should also try a different pull-up resistor value–they recommend 4.7k so the approximately 40k pull-up built-in by setting pinMode() is not really the best choice.
  • If you have long wires to sensor (more than say 0.5meter), you might need to take other steps to reduce interference.
2 Likes

@bko I’m using 3 wire power/ground/data @ 4.7K res. Same way I have it on my core.
Wouldn’t an electrical problem have been showing consistent errors in all the firmware builds?

Same for me. 3 Wires, 4.7k resistor. I’m just going to throw a CRC check in my code and move on. It’s random and doesn’t persist so I’ll try three times in a single sample and if that doesn’t get good data, I’ll throw a fixed number that people can catch and do something with.

I’ll share a more tolerant ds18b20 Lib tomorrow. Not for everyone but it’ll work for me and I’m sure others.

Maybe or maybe not. It sounds like your electrical set up is pretty good. Are you staying away from the WiFi end of the chip? The RF output can cause problems too. Power supply is OK? Have you tried putting the Dallas part on +5V?

There is nothing I know of in the system firmware that changed from 0.4.4 to 0.4.5 or 0.4.6 that could even remotely account for this, but I have been surprised before.

I still think the first level answer is to discard any results with a bad CRC. If you want to dig deeper, by all means go for it. Step one in that dig for me would be to put a scope or logic analyzer on the data line and try to captured a failure.

Yes. Probably not a bad idea for a bunch of reasons. :smiley:

I got out a DS18B20 this weekend to play around with on another microcontroller (shame on me) that doesn’t really have analog capabilities to speak of (shame on them), but it does have the CRC-checking code. The function for that is below. Instead of using one, I used ds for the OneWire object. The code is adapted from http://bildr.org/2011/07/ds18b20-arduino/.

float getTempC() {
  byte data[12];
  byte addr[8];
  
  if(!ds.search(addr)) {
    ds.reset_search();
    return -1000;
  }
  
  if(OneWire::crc8(addr, 7)!=addr[7]) {
#ifdef DEBUG_SERIAL
    Serial.println("CRC is not valid!");
#endif
    return -1000;
  }
  
  if(addr[0] != 0x10 && addr[0] != 0x28) {
#ifdef DEBUG_SERIAL
    Serial.println("Device is not recognized");
#endif
    return -1000;
  }
  
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);
  
  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);
  
  for(uint8_t i=0; i<9; i++) {
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];
  
  float tempRead = ((MSB<<8) | LSB);
  return tempRead/16;
}

Maybe that will save you some time. :slight_smile:

1 Like

Glad to see this discussion continuing… Thought I’d share my code as I do already have a CRC check and still get the same 31.89 reading occasionally. I’m also using 3 wires with a 4.7k resistor. This is what I mentioned above that I took almost directly from the Hotaman lib example.

 if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
    ds.reset_search();
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();

  ds.reset();
  ds.select(addr);      // Just do one at a time for testing
                        // change to skip if you already have a list of addresses
                        // then loop through them below for reading

  ds.write(0x44);        // start conversion, with parasite power on at the end

  delay(1500);     

  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE, 0);            // Read Scratchpad 0

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    if (type_s==1) {    // DS18S20
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
      celsius = (float)raw / 16.0;
    }
  } else {  // DS18B20 and DS1822
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
    celsius = (float)raw / 16.0;
  }
  fahrenheit = celsius * 1.8 + 32.0;

Hi @m9er

I see the CRC is computed and checked in the address search but not in the data transfer phase. For the data transfer, your code computes the CRC of the first 8 bytes and prints it but I don’t see where you have an “if” statement that ignores the results when the computed CRC does not match the 9th byte.

It could very well be a timing problem (the Dallas parts are not fast).

2 Likes

I published a new lib for the WebIDE that has a sensorObj.crcCheck() that lets you easily check for CRC errors and throw away the results if sensorObjcrcCheck() == false;. This fixes the random high and low values (the lows stick around longer than the high ones which you’ll see if you run the example app).

DS18B20 0.1.00
DSB18XX Lib on Particle Photon

Or you can get it from my GitHub. ds18b20 lib on GitHub

2 Likes

@BKO Doh! You’re absolutely right. Tried out @LukeUSMC’s and got it working. Any time I got a bad CRC it only took one or 2 attempts to get a good reading again. Thanks for sharing!

One thing I did notice though is that I seemed to only enter the if(!ds18b20.search()) statement every other time getTemp is called. Both changing it to if(ds18b20.search()), and adding an else statement with the same routine gave a reading every time.

2 Likes

If you only have one sensor, you do not need to search, there is a option to skip rom, which makes all sensors respond.

This can also be used with multiple sensors also, to start their conversion at the same time, and then read them one at a time.

1 Like

I have used the ds1820 and had the same problem in all configurations ( 1 to 10 sensors on buss, strong pullup, fixed pullup). Was using a PIC as the controller. Never did find out what the cause was even after looking at the wave forms with a scope and triggering on a high reading. I fixed the problem with a digital filter and left it at that. I am planning on using this part with the particle and am interested in why this happens. My opinion is that is originating in the ds1820 but dont know why.