DS18B20 Temp Sensor - Working Intermittently & Not Reliable - Took Scope Readings & Could Use Advice

Hey guys,
I am using a Particle Photon (microcontroller w/ cloud connectivity) to communicate with a DS18B20 temperature sensor via the 1-wire bus. Below is how I have it wired up:

From the research I have done, it seems to be preferred that you use 5 volts to power the sensor, then a pullup to 3.3 volts (assuming a 3.3 volt microcontroller). This allows for more reliable data transmission with longer cables. I am using stereo audio jacks for the connectors, and because of this I am using a 220 ohm resistor for protection against momentary shorts while inserting the plug. Here is what the sensor looks like:

I am pulling sensor data from the sensor approximately every 4 seconds, and I get a LOT of errors throughout the day. There are periods of times where it can go several minutes before getting an error free value. Similarly, it can also go several hours and not have any errors, so its very intermittent. The errors range from “no sensors found” to CRC errors.

I wanted to point out that I have had these intermittent errors even with the wires soldered directly to the board, so because of this I do not believe the problem to be the audio jack. I have also tried multiple sensor combinations with multiple boards and I experience the same thing, so I can only assume its my design.

In an effort to try and diagnose the problem, I busted out the Rigol DS2202a oscilloscope to try and take some readings. I am very new to using oscilloscopes so bare with me.

I first took a look at the data line right next to the microcontroller, and this is what I see:

So I am thinking this should be acceptable? I don’t see rounded off raising edges, but I do notice the falling edge can sometimes droop/spike about 80mV below 0 volts… which I don’t think would be a big deal? I also don’t see too much noise here.

I then took a look at the 5V power at the jack:

I noticed that every time the microcontroller would pull data from the sensor, that I would see this voltage drop/spike. It looked pretty significant since it drops down to 3.5 volts momentarily. I put a 0.1uF ceramic capacitor at this location (between 5v power and ground) and it now is flat:

This alone did not fix the problem, I still noticed it was intermittent. I am now trying to replace the 4.7K pullup resistor to a 2.2K pullup to see if that helps, but it feels like I am missing something?

What do you guys think might be the problem? Thanks and any help is greatly appreciated!

1 Like

@mohit any thoughts? Posting your firmware, if you’re able to share it, would also be helpful so that we can make sure everything looks right there as well.

This is the firmware we are using:

I have been working on this the past couple days and still cannot figure out what the problem is.

Has anyone had any problems using this library? I’m beginning to think its a firmware issue but I cannot determine. Any tips on this?

It looks like you have it wired for powering using an external power supply, but in onewiretemp.cpp on line 23 you pass DS18X20_POWER_PARASITE which suggests that it’s configured to work in parasite power mode. I’ve not used this library so cannot be sure whether that’s the problem but it might be worth you checking.

2 Likes

Thanks for taking a look, @timx! @Mahonroy let us know what you find!

Thanks @timx, that is the sample that came along with the library. We are using it with the “DS18X20_POWER_EXTERN” as shown below:

if ( _solutionReadStart == 0 || millis() - _solutionReadStart >= 1000 )
{
    float solutionTemp = _solutionReadStart > 0 ? readSolutionTempSensor() : INVALID_READING;

    DS18X20_start_meas( DS18X20_POWER_EXTERN, NULL );
    _solutionReadStart = millis();

    return solutionTemp;
}

return INVALID_READING;

Another thing I noticed after using the oscilloscope on the data line next to the photon, that the small amount of fuzz (noise) you can see in the scope images is actually about ± 200mV. Is that a problem or is that still considered insignificant? Could that cause any errors?

https://community.particle.io/uploads/particle/original/2X/8/8e999122561b143de8ab88ed6d36839b0d03b18c.jpg

Here is a better view of what the data line looks like right up next to the microcontroller (rising and falling edge):

Note this is 500 nanoseconds window.

Note this is 200 nanoseconds window.

Is this acceptable for the data line by the way? I’m still trying to troubleshoot this and am running out of ideas.

If the data line looks good, does that mean it has to be a power problem then?

I ordered a bunch of DS18B20 sensors today so I’ll run some tests next week when they arrive. Hopefully someone else will come up with an answer before then, but just in case.

@Mahonroy, I suspect that the “noise” you see along with the overshoot are artifacts of your oscilloscope, not the I2C bus.

I would try either this library, or my version of it:


The only difference between the two is I’ve changed the timings to not be at the absolute minimum. I’m using DS18B20’s on 15M cables very reliably with about 50 in the field attached to Electrons.

2 Likes

Thanks @peekay123, that makes sense.

@hwestbrook, thanks for those libraries, I will definitely try those out!

How do you have your circuit set up by the way? Are you using 5V with a 4.7K pullup to 3.3V? Or something similar? Is your cable disconnectable (e.g. does it have some sort of a connector on it?)

Hey @hwestbrook, just wanted to check back with you about the circuit? Thanks again.

Is it possible that R17 (220 ohm resistor) in my circuit could be causing problems? (my original post above shows R17 in the circuit schematic).

Hi,
Your schematic doesn’t show everything, but I’m assuming the ground for the 5v source and the ground of the photon are connected together?

I have not used a configuration where the Vdd is connected to 5V (through a 220ohm resistor) and the DQ is pulled up to 3.3V for data, but it should work. I typically connect the DQ 4.7K pull-up and Vdd to 3.3V (which works fine also).

I’ve had issues with the dallas libraries (tried various, but found the conversion to 32-bits not everything works). First I’ve found that temperature readings can give bad readings of all 1s (0xFFFF) so these should be filtered out. The second probably I’ve found is they don’t do negative temperatures well (don’t sign-extend properly for 32-bit processors which have 4 byte vs. 2 byte integers prior to converting to a float/double).

So I took the getTemp() method from the Dallas library and modified it so that it sign-extends properly and only returns if it has a valid reading. In the code below the function sticks the temperature in a global variable “double” named “temp”. I have not had much issue with the code below.


// temp in degrees C in double temp, also function returns true is a good value, false if a bad value

bool getTemp()
{
    byte data[12];
    byte addr[8];
    bool good = false;
    if (!ds.search(addr)) {
        ds.reset_search();
        return good;
    }

    if (OneWire::crc8( addr, 7) != addr[7]) {
        return good;
    }

    if (addr[0] != 0x10 && addr[0] != 0x28) {
        return good;
    }

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

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

    for (int i = 0; i < 9; i++) { // we need 9 bytes
        data[i] = ds.read();
    }
 
    ds.reset_search();
 
    byte MSB = data[1];
    byte LSB = data[0];


    int tempTemp = ((MSB << 8) | LSB); //using two's compliment
    if (tempTemp == 65535) {  // then its a bad reading
        return good;
    } else {
        good = true;
    }

    // following sign-extends for 32-bit processors (int is 4 bytes), else you won't get negative temps
	if (MSB&0x80) {
	    tempTemp = tempTemp | 0xFFFF0000;
	} else {
	    tempTemp = tempTemp & 0x0000FFFF;
	}
	long longTemp = tempTemp;		// should sign extend
	
    float tempRead = longTemp;		// convert to floating
    temp = tempRead/16;
 
    return good;
}

Using this code I do something like:
void loop()
{
  temp = 0.0;
  if (getTemp()) {
    delay(750);
    // do something with the temperature
}

See if this works better for you.

@Mahonroy,

Sorry for the delay, I’ve been travelling quite a bit. Below is my schematic. It’s overly complicated as I am using this on a product board, but whats important is:

  • Connect GND to GND
  • Connect 3v3 to 3v3
  • Connect 4k7 resistor between the data line and the 3v3 power
  • Connect Data to Data

This has worked really well for me. I would not try any resistor other than what is recommended by Dallas and others in this forum.

1 Like

Thanks a lot for posting the diagram. Is the majority of the circuits complexity so that when you insert the audio jack, the temporary shorts don’t mess anything up?

So we tried those other libraries you mentioned, and the problem still remains :confused:

Any other ideas on what it might possibly be? Thanks again for taking the time to look into it.

Hi @Mahonroy,

My ds18b20’s do not have audio jack ports – they are wired directly into the PCB in a three wire configuration, pwr+, gnd, data.

I’m not really sure why you are having issues. Like I said, mine work pretty reliably with the circuit above and the library I’ve shared.

One thing I do, that you may not be doing, is I have some retry logic in my code. If one of the temp sensors returns the same value as its last value OR if it returns a bad value it will retry up to two times.

The other difference from my setup to yours sounds like you poll them very frequently. I only poll mine about once per hour.

Hope this helps.

@hwestbrook , thanks again for the info.
Where do you get your sensors from by the way? I am wondering if I am sourcing bad sensors?