Solution to DS18B20 random 85°C measurements

I have found a possible bug in the OneWire library where some or all of the DS18B20 sensor would randomly give a reading of 85°C. I am using six sensors in parasitic power on a single pin. I am only allowing one sensor to do temperature conversion at a time.

After studying the datasheet and forums, I noticed that 85°C is the power up value. Also stated in the datasheet (which I did not notice for a long time) is that under parasite power, a reset pulse of more than ~1ms can cause a power on reset. So I had a look in the OneWire library, and noticed that interrupts are being enabled for the duration of the reset. I changed the ::reset function to disable interrupts for the 480us delay and gone are my 85°C measurements.

I must also add that my Arduino is working under quite a load (it is an Ethernet Arduino based swimming pool temperature controller with a heatpump, solar panels, 4 digit display, etc.)

I am not sure whether this can cause ill aftereffects, maybe the experts out there can comment.

uint8_t OneWire::reset(void)
	IO_REG_TYPE mask = bitmask;
	volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
	uint8_t r;
	uint8_t retries = 125;

	DIRECT_MODE_INPUT(reg, mask);
	// wait until the wire is high... just in case
	do {
		if (--retries == 0) return 0;
	} while ( !DIRECT_READ(reg, mask));

	DIRECT_WRITE_LOW(reg, mask);
	DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
	DIRECT_MODE_INPUT(reg, mask);	// allow it to float
	r = !DIRECT_READ(reg, mask);
	return r;

Well that is very interesting.

If leaving the interrupts disabled solves that problem for you, well OK. I suppose it depends if anything else which your arduino is doing, requires interrupts.

I suspect this is an excercise in bad programming being an attempt to fix bad programming originally cause by bad application, possibly resulting from a failure to read the data sheet. In short, you should be removing the problem rather than trying to programme your way around it and, whenever you think you have found a bug, the first question to ask is - "How come I have found this bug when millions before me didn't?"

The most usual way to see the 85 is momentarily when starting or manually resetting. This is usually just a matter of calling for a reading before the DS18B20 has had a chance to get one i.e. caused by the wrong order of commands which is fixed the next time round the loop and the worst that happens is that the reading you see is one cycle out of date, and not likely to cause a problem.

I believe the above is indicative of any problem when the programme is running - you are simply calling for a result before the sensor has had a chance to do its job. This is caused by

  1. bad programming, or
  2. bad concept
  3. bad choice of sensor

It surely isn't #3, as the description of your project suggests the DS18B20 is an obvious and ideal choice. There is nothing to suggest a "heavy load" either. You make no mention of the type of Arduino you are using, but the project is very ordinary and any mysterious heavy load is usually a matter of memory running out, of which there is no evidence.

The problem could be #1 but the code you post is completely alien to me, and I assume it is incomplete anyway

With luck, the problem is #2, which could encompass several things, some of which might have a bearing on item #1. For starters, I have never known anybody yet who has a valid reason for using parasitic power but, when it is used, I believe a minimum of 750ms must be allowed to make the conversion, irrespective of the resolution used. Further, parasite power inherently requires a stronger pullup and, if your cable run is long, you may indeed find that you need to reduce the resistor even without parasite power. I don't know if the 85s are indicative of that, but I suspect they might be ie. inadequate power just at the time you really need it.

The bottom line is that the 85 signals power-up reset, and your first question should be - "How come I'm getting all these power up resets when everybody else isn't?"