milesburton / Arduino-Temperature-Control-Library

Arduino Temperature Library
https://www.milesburton.com/w/index.php/Dallas_Temperature_Control_Library
968 stars 487 forks source link

Problem with Setting Resolution #120

Closed PLPOLAND closed 6 years ago

PLPOLAND commented 6 years ago

Hi, I tried to set resolution to 9 bit in my project, but it wasn't work. So I upload the "Tester" from examples and I've something like that:

Dallas Temperature IC Control Library Demo Locating devices...Found 1 devices. Parasite power is: OFF Found device 0 with address: 286164118DB652EE Setting resolution to 9 Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 24.50 Temp F: 76.10 Requesting temperatures...DONE Temperature for device: 0 Temp C: 24.56 Temp F: 76.21

So It's setting resolution to 9 but then is 12 back... Some ideas?

RobTillaart commented 6 years ago

Strange.. Which version of the library did you use? Which platform?

PLPOLAND commented 6 years ago

Library ver. 3.7.9 Arduino 1.8.2 Board - Arduino UNO Sensor - DS18B20

RobTillaart commented 6 years ago

Sounds like up to date. Can you reproduce with a second DS18 sensor (if you have one)?

PLPOLAND commented 6 years ago

Second one:

Dallas Temperature IC Control Library Demo Locating devices...Found 1 devices. Parasite power is: OFF Found device 0 with address: 286164118D8C4A7B Setting resolution to 9 Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 25.19 Temp F: 77.34 ...

And next 4 at the same time:

Dallas Temperature IC Control Library Demo Locating devices...Found 4 devices. Parasite power is: OFF Found device 0 with address: 2861641196499092 Setting resolution to 9 Resolution actually set to: 12 Found device 1 with address: 286164118DB6152B Setting resolution to 9 Resolution actually set to: 12 Found device 2 with address: 286164118DF115DE Setting resolution to 9 Resolution actually set to: 12 Found device 3 with address: 286164118DF5EB8E Setting resolution to 9 Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 25.19 Temp F: 77.34 Temperature for device: 1 Temp C: 25.56 Temp F: 78.01 Temperature for device: 2 Temp C: 24.69 Temp F: 76.44 Temperature for device: 3 Temp C: 25.44 Temp F: 77.79 ...

So it's all of them 😞

RobTillaart commented 6 years ago

Looked at the code of TESTER.PDE

(line 25) sensors.begin(); sets the value of the variable bitResolution probably to 12. (adding a Serial.println(bitResolution); can confirm this)

The setResolution call in tester.pde (line 58) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); maps to the library bool setResolution(const uint8_t*, uint8_t, bool skipGlobalBitResolutionCalculation = false);

and the implementation does (278) bitResolution = max(bitResolution, newResolution); which keeps bitResolution on 12....

And the value of bitResolution is returned by getResolution()...

can you please change the line (line 58) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); into (line 58) sensors.setResolution(TEMPERATURE_PRECISION);

and give it a test run Sorry I have no hardware nearby to do test myself

PLPOLAND commented 6 years ago

No problem 😉 So I add

Serial.print("bitResolution= "); Serial.println(bitResolution);

just before closing "}" of begin() method. And I changed line 58 to

sensors.setResolution(TEMPERATURE_PRECISION);

Serial Monitor output:

Dallas Temperature IC Control Library Demo bitResolution= 12 Locating devices...Found 1 devices. Parasite power is: OFF Found device 0 with address: 286164118DB652EE Setting resolution to 9 Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 23.81 Temp F: 74.86 ...

RobTillaart commented 6 years ago

Do you get the same problem with the single.pde example? It does also set and get the resolution....

PLPOLAND commented 6 years ago

Yeah...

Dallas Temperature IC Control Library Demo Locating devices...bitResolution= 12 Found 1 devices. Parasite power is: OFF Device 0 Address: 286164118DB652EE Device 0 Resolution: 12 Requesting temperatures...DONE Temp C: 23.94 Temp F: 75.09 Requesting temperatures...DONE Temp C: 23.94 Temp F: 75.09

RobTillaart commented 6 years ago

So it is not the sketch,

Can you change a line in the library? line 305 or so change 12 to 42

uint8_t DallasTemperature::getResolution(const uint8_t* deviceAddress) { // DS1820 and DS18S20 have no resolution configuration register if (deviceAddress[0] == DS18S20MODEL) return 42;

As getRes has two paths that give 12 as answer, lets see which is used. Please run tester.pde after the modification

PLPOLAND commented 6 years ago

I change it. I think, it uses correct one... 🤔

TemperDallas Temperature IC Control Library Demo bitResolution= 12 Locating devices...Found 1 devices. Parasite power is: OFF Found device 0 with address: 286164118DB652EE Setting resolution to 9 Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 24.00 Temp F: 75.20 ...

RobTillaart commented 6 years ago

So the getResolution() sees the right type of sensor, can read the scratchPad and returns 12.

So now lets see what it acually writes to the config register (line 275) in setResolution

        writeScratchPad(deviceAddress, scratchPad);
        Serial.println(scratchPad[CONFIGURATION], HEX);
        // without calculation we can always set it to max

can you test?

PLPOLAND commented 6 years ago

Dallas Temperature IC Control Library Demo bitResolution= 12 Locating devices...Found 1 devices. Parasite power is: OFF Found device 0 with address: 286164118DB652EE Setting resolution to 9 1F Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 24.06 Temp F: 75.31

1F is good, isn't it?

RobTillaart commented 6 years ago

1F is indeed the value that should be written. so it seems that the right value 9 is written, but it reads back 12 all the time ...

next test (last for today)

TESTER.PDE can you please change the line (line 58) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); into (line 58) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION, true);

PLPOLAND commented 6 years ago

Nothing changed

Dallas Temperature IC Control Library Demo bitResolution= 12 Locating devices...Found 1 devices. Parasite power is: OFF Found device 0 with address: 286164118DB652EE Setting resolution to 9 1F Resolution actually set to: 12 Requesting temperatures...DONE Temperature for device: 0 Temp C: 24.06 Temp F: 75.31

RobTillaart commented 6 years ago

You could try to set resolution without the library, e.g. http://www.homautomation.org/2015/11/17/ds18b20-how-to-change-resolution-9101112-bits/

They use the low level calls and if these do work ==> the library is faulty if these do not work either ==> the sensors are faulty.

Give it a try

PLPOLAND commented 6 years ago

So, I found example example in OneWire library wich read ROM&Data. I add code from the webside. There is Serial Monitor output:

ROM = 28 61 64 11 8D B6 52 EE Chip = DS18B20 Data = 1 8B 1 FF FF 7F FF FF FF 8B CRC=8B Write data Data = 1 8B 1 FF FF 7F FF FF FF 8B CRC=8B Temperature = 24.69 Celsius, 76.44 Fahrenheit

and code:

#include <OneWire.h>

OneWire  ds(14);

void setup(void) {
  Serial.begin(9600);
    byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  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);
  }

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

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44);  

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

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

  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();
//####################################################################
  Serial.println("Write data");
  ds.reset(); // rest 1-Wire
  ds.select(addr); // select DS18B20
  ds.write(0x4E); // write on scratchPad
  ds.write(0x00); // User byte 0 - Unused
  ds.write(0x00); // User byte 1 - Unused
  ds.write(0x1F); // set up en 9 bits (0x1F)
  ds.reset(); // reset 1-Wire
 //##################################################################
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  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
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    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;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

void loop(void) {

}
RobTillaart commented 6 years ago

The resolution bit is 7F == RES12 bit

You should add a few lines in it (using the Dallas lib) to set the resolution to 9 and see what data contains then.

RobTillaart commented 6 years ago

Had a better look at the code and the writing of RES 9 is done allready but the chips do not seem to get the data.

It might be that the ds18B20 are mislabeled DS18S20 or another of the family that do not support resolution setting. Can you check that the sensor does say DS18B20 on the side?

Where did you buy them? A trusted (often more expensive) company?

PLPOLAND commented 6 years ago

Yes, there is "DS18B20" on the side. I bought them on botland.com.pl. They cost ~5PLN = ~1,15 EUR. I think I'm gonna give up with changing resolution and I'll write the asyc code 😞 If only there is no more ideas then damaged sensor 😉

RobTillaart commented 6 years ago

Price seems very low to me, but no proof that it is a fake sensor. The fact that the library example and the non-library code give the same result strongly points towards the sensor. As the datacommunication goes well it is not a pull up resistor or something like that,

found a sensor and an Arduino, so a small test

Dallas Temperature IC Control Library Demo
Locating devices...Found 1 devices.
Parasite power is: OFF
Found device 0 with address: 280FDE79020000B2
Setting resolution to 10
Resolution actually set to: 10
Requesting temperatures...DONE
Temperature for device: 0
Temp C: 26.00 Temp F: 78.80

Arduino UNO tester.pde sketch (modified to use res 10) dallas lib version: 3.8.0. Arduino IDE: 1.8.5

so some small differences with your test, the lib does set the resolution correctly, so I would order some SD18B20 from another source if possible

RobTillaart commented 6 years ago

@milesburton Please close issue