Proper MOSFET to power DS18B20 in parasite mode

After reading this thread and the datasheet I can see that a problem I have noticed is likely related to a voltage drop. I have 5 sensors in parasite with a 4.7k resistor. They work but drop a -127 randomly.

I am having a hard time really understanding how to use which MOSFET. Anyone able to lay it out in really layman terms/components?

Edit: Split from http://arduino.cc/forum/index.php/topic,64091.msg466607.html and merged with this topic. Coding Badly.

Molehs: After reading this thread and the datasheet I can see that a problem I have noticed is likely related to a voltage drop. I have 5 sensors in parasite with a 4.7k resistor. They work but drop a -127 randomly.

I am having a hard time really understanding how to use which MOSFET. Anyone able to lay it out in really layman terms/components?

Any assistance?

My electronics knowledge is sketchy at best, which likely accounts for the fact that I could never get even a single one of those sensors to work in parasitic power mode. Once I accepted that I was going to need three wires, everything worked perfectly.

The schematic shows a thermometer NOT using parasitic power. If it were using parasitic power the VCC and Ground pins would be connected together.

Are you waiting the required 750 milliseconds (for 12-bit values) between starting a temperature conversion and reading the scratchpad?

Here is the code I use to begin simultaneous temperature readings on all thermometers and then reading the values from two specific thermometers:

#include <OneWire.h>

//  Fault flags
extern const unsigned int ITemp_fault;
extern const unsigned int ETemp_fault;
extern unsigned int Faults;

// DS18S20 Temperature chip I/O
const int ONEWIRE_PIN = 9;
OneWire DS18S20(ONEWIRE_PIN);

// Can't make them const because the OneWire library doesn't take const. :(
byte InteriorThermometer[8] = {
  0x28, 0x95, 0xB9, 0x1D, 0x03, 0x00, 0x00, 0xB9};
byte ExteriorThermometer[8] = {
  0x28, 0xA9, 0x9E, 0x1D, 0x03, 0x00, 0x00, 0x80};

unsigned long lastTempConversionTime = 0;

void Thermometers_setup(void)
{
}

void Thermometers_loop(void)
{
}

void Thermometers_log(Print &dest)
{
  unsigned long currentTime = millis();

  // If it's been more than three seconds since the last conversion
  if (currentTime - lastTempConversionTime > 3000)
  {
    // Start a fresh conversion
    startThermometers();  // Begin a conversion on all thermometers
    lastTempConversionTime = currentTime;
    delay(750);
  }

  // Now read the temperatures
  float i_temperatureC = readThermometer(InteriorThermometer, ITemp_fault);
  float e_temperatureC = readThermometer(ExteriorThermometer, ETemp_fault);

  dest.print(", ");    
  dest.print(i_temperatureC, 3);
  dest.print(", ");    
  dest.print(e_temperatureC, 3);
}

void startThermometers()
{
  DS18S20.reset();
  DS18S20.write(0xCC);      // Address all thermometers
  DS18S20.write(0x44);         // start conversion, no parasite power on at the end
}

float readThermometer(byte addr[8], unsigned int faultFlag)
{
  byte data[9];
  float temperature_C;

  DS18S20.reset();
  DS18S20.select(addr);    
  DS18S20.write(0xBE);         // Read Scratchpad

  for (int i = 0; i < 9; i++) 
    data[i] = DS18S20.read();

  if (data[5] != 0xFF || data[7] != 0x10)
  {
    Faults |= faultFlag;
    return 999.999;
  }

  if ( OneWire::crc8( data, 8) == data[8])
  { // CRC is valid
    int temperature = (data[1] << 8) + data[0];  // Two byte binary temperature in °C/16
    // Serial.println(temperature, HEX);
    temperature_C = temperature / 16.0;
  }
  else
  {
    Faults |= faultFlag;
    return 999.999;
  }
  Faults &= ~faultFlag;
  return temperature_C;
}

I'm running 5 temp sensors in parasite mode and I am waiting the 750ms for the reads. They all read correctly it's just that randomly they pop up with that -127C. I do need to improve my code to eliminate the 750ms hang time but more importantly is to get clean reads currently which appears to be fixed with the proper MOSFET and layout. That is where I could use assitance.

They all read correctly it's just that randomly they pop up with that -127C.

Check the connections, I've some experience with bad connections and DS18B20 (not in parasite mode) and saw the -127 (too) often. That said could be another cause too.

What is the bit resolution you need, as only for 12 bit there is a need for the 750ms delay.

That said, have you checked - http://www.milesburton.com/Dallas_Temperature_Control_Library - version 3.7.0. There are examples to read the sensors asynchronously so you can do usefull things instead of waiting.

robtillaart: Check the connections, I've some experience with bad connections and DS18B20 (not in parasite mode) and saw the -127 (too) often. That said could be another cause too.

What is the bit resolution you need, as only for 12 bit there is a need for the 750ms delay.

That said, have you checked - http://www.milesburton.com/Dallas_Temperature_Control_Library - version 3.7.0. There are examples to read the sensors asynchronously so you can do usefull things instead of waiting.

When I had all of the wiring open I could not cause it to -127 by jiggling the wires. It seems that I didn't hook it up with enough power which would be taken care of with a MOSFET as indicated by the datasheet. And I don't understand enough to know what it means from the datasheet.

In parasite power mode, the 1-Wire bus and CPP can provide sufficient current to the DS18B20 for most operations as long as the specified timing and voltage requirements are met (see the DC Electrical Characteristics and AC Electrical Characteristics). However, when the DS18B20 is performing temperature conversions or copying data from the scratchpad memory to EEPROM, the operating current can be as high as 1.5mA. This current can cause an unacceptable voltage drop across the weak 1-Wire pullup resistor and is more current than can be supplied by CPP. To assure that the DS18B20 has sufficient supply current, it is necessary to provide a strong pullup on the 1-Wire bus whenever temperature conversions are taking place or data is being copied from the scratchpad to EEPROM. This can be accomplished by using a MOSFET to pull the bus directly to the rail as shown in Figure 4. The 1-Wire bus must be switched to the strong pullup within 10µs (max) after a Convert T [44h] or Copy Scratchpad [48h] command is issued, and the bus must be held high by the pullup for the duration of the conversion (tCONV) or data transfer (tWR = 10ms). No other activity can take place on the 1-Wire bus while the pullup is enabled

To me that is greek.

Post your sketch. Please use "code tags" (# button above the edit window).

I have 5 DS18B20s wired in parasite mode which all work. The problem I have is randomly each will read -127C. It seems that I didn't hook it up with enough power which would be taken care of with a MOSFET as indicated by the datasheet. And I don't understand enough to know what it means:

In parasite power mode, the 1-Wire bus and CPP can provide sufficient current to the DS18B20 for most operations as long as the specified timing and voltage requirements are met (see the DC Electrical Characteristics and AC Electrical Characteristics). However, when the DS18B20 is performing temperature conversions or copying data from the scratchpad memory to EEPROM, the operating current can be as high as 1.5mA. This current can cause an unacceptable voltage drop across the weak 1-Wire pullup resistor and is more current than can be supplied by CPP. To assure that the DS18B20 has sufficient supply current, it is necessary to provide a strong pullup on the 1-Wire bus whenever temperature conversions are taking place or data is being copied from the scratchpad to EEPROM. This can be accomplished by using a MOSFET to pull the bus directly to the rail as shown in Figure 4. The 1-Wire bus must be switched to the strong pullup within 10µs (max) after a Convert T [44h] or Copy Scratchpad [48h] command is issued, and the bus must be held high by the pullup for the duration of the conversion (tCONV) or data transfer (tWR = 10ms). No other activity can take place on the 1-Wire bus while the pullup is enabled

To me that is Greek. Any assistance in determining the wiring and hardware would be appreciated.

As I'm not sure if you are responding to me or not and I realized that this is a hardware, not programming, issue I've created a new thread in the appropriate sub forum for my specific issue.

http://arduino.cc/forum/index.php/topic,66452.0.html

You probably don't need a MOSFET, the Arduino output pins can probably pull-up hard enough - assuming the software does the right thing about using active pull=up for parasite power.

Which parts are Greek to you? Probably best to break that up into individually grokkable slices.

Start with pullup/down resistors: Grumpy Mike's tutorial.

Also, I'm going to throw out a wild guess that you don't need more power.

ETA: Also, a link to where that text you quoted resides would be nice.

Sorry, datasheet here: http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf

I understand the idea of what the paragraph says but not the technicalities of it. In particular the last part:

The 1-Wire bus must be switched to the strong pullup within 10µs (max) after a Convert T [44h] or Copy Scratchpad [48h] command is issued, and the bus must be held high by the pullup for the duration of the conversion (tCONV) or data transfer (tWR = 10ms). No other activity can take place on the 1-Wire bus while the pullup is enabled

As well needing more power would make sense to me as it's pretty random for each one. As such I ruled out a wiring thing because the likelihood of all of them having wiring issues that only happen at random is pretty unlikely. But the idea of random occasions that it needs more power than is available sounds feasible to me. But then again this stuff just doesn't click for me sometimes...or perhaps more often than sometimes.

Out of curiosity, how long is your total cable run? Is this a prototype (ie, all DS18B20 on protoboard) or an actual installation? I've found that powering the bus via +5v rather than using parasitic mode is much more reliable and responsive. In my case, I've got about 60 different 1-wire devices scattered around my home on several independent busses (my longest has 23 devices on a single bus). I found long parasitic runs to be glitchy at best, and maddeningly slow to query. You may also want to take a look at the HA7S SIP module from EDS (http://www.embeddeddatasystems.com/HA7S--ASCII-TTL-1-Wire-Host-Adapter-SIP_p_23.html) if you're serious about monitoring with 1-Wire and Arduino. Dead simple to integrate with arduino via TTL serial and handles all timing/bit-banging for you.

As I'm not sure if you are responding to me

I was.

I realized that this is a hardware, not programming, issue

The pin you are using for 1-Wire communications is capable of becoming a "strong pullup" through the OneWire library. In other words, your problem could easily be hardware or software.

It’s all greek to me

Normally the chip gets its power through the 4k7 resistor.

What that is saying is that under certain conditions (temp conversion and eprom writing) the chip needs more power than can be supplied through the resistor so you have to provide it some other way. The method they suggest is to basically short out the resistor with a FET, thus providing a hard power supply to the bus.

This means that no bus activity can occur while the FET is turned on.

Another thing to note about parasitic power is that it’s not recommended over 100C temps.


Rob

With only 5 sensors, each drawing, at most, 1.5mA, that's only 7.5mA, total ever possible. An Arduino pin can supply that, can't it? (Yeah, I know, the pullup itself will limit current, I should do the arithmetic.)

But if something is pulling the bus low, it won't matter.

@Molehs: Which libraries are you using, and what versions?

I2C communicates by pulling the bus low. The parts get power while it remains in the "high" state. If too much data gets sent... or something is behaving badly... the bus can spend too much time "low" and the parts lose power... result - they act up.

An Arduino pin can supply that, can't it?

Yep, I guess you just have to disable I2C and turn the pin into an output for the duration, I haven't looked but presumably the library does this.

The pin you are using for 1-Wire communications is capable of becoming a "strong pullup" through the OneWire library.

As Coding Badly said.


Rob

justjed: With only 5 sensors, each drawing, at most, 1.5mA, that's only 7.5mA, total ever possible

Nope. It's 1.5mA max at one time, as only one device (the selected node) can be actively queried.

From the datasheet:

when the DS18B20 is performing temperature conversions or copying data from the scratchpad memory to EEPROM, the operating current can be as high as 1.5mA.

The Maxim datasheets are actually very well written and explain 1-Wire operation in very clear terms. I hate to invoke the dreaded RTFM, but... Really. All of this is very clearly explained in the docs.