PaulStoffregen / OneWire

Library for Dallas/Maxim 1-Wire Chips
http://www.pjrc.com/teensy/td_libs_OneWire.html
579 stars 382 forks source link

Parasite mode support #42

Closed rajibgupta closed 6 years ago

rajibgupta commented 6 years ago

Hi,

Does the library by default supports parasite power mode or do we have to enable it in the code ?

Sorry in advance if this is a silly question.

orgua commented 6 years ago

it does. when using write() or write_bytes() just use the last "power" parameter, it drives the line with power. depending on your controller you have much less than 20mA. atmega328 can drive around 25mA

rajibgupta commented 6 years ago

thanks. So for example I just use it as ds.write(0xBE, 1) and rest will be taken care of ?

When the power is by default set to "0" what exactly this part of the code in the library does ? if ( !power) { noInterrupts(); DIRECT_MODE_INPUT(baseReg, bitmask); DIRECT_WRITE_LOW(baseReg, bitmask); interrupts(); }

orgua commented 6 years ago

the first and fourth operation is not relevant, it makes the two in the middle atomic (like bond together). the second one sets the pin to input. so it switches from driving the pin to a high impedance. the next command is not relevant again. on some controllers it disables the internal pull up resistor.

rajibgupta commented 6 years ago

So for example I just use it as ds.write(0xBE, 1) and rest will be taken care of ?

This is correct, right ?

PaulStoffregen commented 6 years ago

Are you using a chip that's substantially different than the 3 examples that come with this library? If so, maybe we should know the chip's info and consider adding another example. If your chip is covered by the examples, please start with one of the known-good examples.

orgua commented 6 years ago

the command is right yes, but if you expect an answer by the slave device you must call depower(), otherwise they will work against the master.

rajibgupta commented 6 years ago

@PaulStoffregen I am using DS18B20 . I have been using this library and the example since about an year with non-parasite power mode. It works fine for me. Since my application involves remote sensing and sensors are little far from the controller, I am considering to use parasite power mode for improved performance.

orgua commented 6 years ago

there is no improved performance. you just safe one of the three wires and get some more problems / things to watch out for. and btw, Paul was asking for your sensors, not your controller.

rajibgupta commented 6 years ago

@orgua I am simply using DS18B20 probes with atmega328P. I didn't get what you meant by expecting an answer by the slave device. Could you please explain this part ?

orgua commented 6 years ago

please read through the onewire-article on wikipedia if you are interested. this is a complex protocol. i wouldn't just enable parasitic power and hope for the best. worst case: you destroy hardware

rajibgupta commented 6 years ago

what are the extra problems and things to watch out for ?

In some places I face a problem in which the reading comes either -0.05 or 85(the default value stored on the chip on boot-up) deg Celsius occasionally. I don't know why this is happening.

orgua commented 6 years ago

do you use the standard example? it seems you are disregarding some wait-periods. maybe the sensor isn't ready to answer to the commands of the master. impossible to know without a capture of a logic analyzer or at least your source code.

rajibgupta commented 6 years ago
//Function to get digital sensor reading
float getDigitalSensorReading(short port){
  OneWire ds(port);
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  ds.search(addr);   

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

  delay(1000);     // maybe 750ms is enough, maybe not

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

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();

  }

  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {

      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);

    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; 

  return celsius;
}

Yes I have used the standard example. Please see the above code.

PaulStoffregen commented 6 years ago

I'm going to close this issue and unsubscribe. You guys can keep chatting. But these github issue are meant for reporting bugs. General usage and project guidance questions belong on the Arduino forum, not github issues.

rajibgupta commented 6 years ago

@PaulStoffregen Sorry for extending this one too long. Before you unsubscribe please give me one simple answer. If I want to use parasite mode with DS18B20 chip,do I need to make any changes to the example code ?

rajibgupta commented 6 years ago

@orgua Please give me your mail id, I will connect you there. my mail - rajib.4gupta@gmail.com

Thanks

orgua commented 6 years ago

so this is just a stripped down standard example..... your changes seem not to be harmful. but does it work? it depends on your sensor count. could be enough. i don't know how much power the ds18b20 need and how big your capacitors are. but think of it this way: every time you issue a command with "power" enabled, you are charging the capacitors of your slaves. you will need an osci and some experience with electronics to figure it out. good luck

rajibgupta commented 6 years ago

Yes it works in 90% of the cases. That's why I don't think it's a code issue. I am using only one sensor on one port. The problem is not with the parasite power mode. I am providing external supply separately to the sensors.

orgua commented 6 years ago

it is impossible to help you with this. you don't seem to know what's going on in your setup. Without this info it is just a search in the dark. Just filter out / throw away invalid values.... And check your external pull up resistor (a 1k to 4.7K resistor is necessary). Here is a check protocol you can work through: https://github.com/orgua/OneWire/blob/master/readme.md - under section HELP