nodemcu / nodemcu-firmware

Lua based interactive firmware for ESP8266, ESP8285 and ESP32
https://nodemcu.readthedocs.io
MIT License
7.67k stars 3.13k forks source link

ds18b20.lua : 12bits resolution for DS18S20 instead of 9 bits #1978

Closed villeneuve closed 7 years ago

villeneuve commented 7 years ago

Hello, I apologize for having put a PR in the master branch instead of the dev branch #1976. I also understand after reading the "contributing guidelines" that I should have started an issue rather than a PR. This is what I do now.

In this PR I was writing this I have some 1wire temperature sensors. Some DS18B20 and some DS18S20 This DS18B20 one wire module works fine with both sensor types, however the temperature reading for the DS18S20 is 9 bits only (12 bits for the DS18B20). 9 bits is default for DS18S20 however it's possible to have 12 bits as explained here: https://datasheets.maximintegrated.com/en/ds/DS18S20.pdf and here in this Maxim application note: comparison of both sensors https://www.maximintegrated.com/en/app-notes/index.mvp/id/4377 9 bits is annoying because you get only half degree precision (i.e. 22; 22.5; 23; 23.5; 24 etc..) you cannot get something like 22.3. So even if I don't need the 4 figures after the decimal point, 12 bits resolution is better.

--

Anyway as noted by FrankX0 I checked if it works with an integer build, and of course it does NOT This line c = (((data:byte(8)-data:byte(7))/data:byte(8)) - 0.25) * 10000 generate this error

error loading module 'ds18b20' from file 'ds18b20.lua':
    ds18b20.lua:110: malformed number near '0.25

of course! 0.25 is far from an integer

So I believe it was not a good idea, it will cause more problems (for people using integer build) than bringing improvement. Also nowadays DS18S20 are rare and DS18B20 are the standard.

Sorry for bringing a false issue

FrankX0 commented 7 years ago

Don't worry, you can still do a pull request for the dev branch. You can do the calculation based on integers in the following way:

(data:byte(8) - data:byte(7)) * 10000 / data:byte(8) - 2500
TerryE commented 7 years ago

9 bits is default for DS18S20 however it's possible to have 12 bits as explained here.

Sorry but his one (and the whole raison d'être for this PR) has me totally confused. Quoting the DS, P8:

The power-up default of these bits is R0 = 1 and R1 = 1 (12-bit resolution).

And this is my experience. I buy my DS18B20s in bulk from China, but bench calibrate them as I describe on another forum in this post. My rig can support (and works quite happily with) up to 15 sensors, but that's only because I don't really need to do more than that at a go. And as you can see from that post if calibrate and adjust the readings cased on this calibration data, then you can get consistent absolute readings to the lsb.

villeneuve commented 7 years ago

Sorry if I brought confusion My issue/PR was to mention difference between DS18B20 and DS18S20 only. the code ds18b20.lua in the master branch https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_modules/ds18b20/ds18b20.lua can handle both devices DS18B20 and DS18S20 The code recognize them here

   if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
      -- print("Device is a DS18S20 family device.")

DS18B20 is family code 0x28 DS18S20 is family code 0x10 then the code do this

if (addr:byte(1) == 0x28) then
          t = t * 625  -- DS18B20, 4 fractional bits
        else
          t = t * 5000 -- DS18S20, 1 fractional bit
        end

So this means 12 bits resolution for a DS18B20 and 9 bits resolution for a DS18S20 However as per DS18S20 datasheet https://datasheets.maximintegrated.com/en/ds/DS18S20.pdf it is still possible to get 12 bits resolution with the calculation mentioned above. I had a DS18S20 (and several DS18B20) this ds18b20.lua code when reading a DS18S20 will return a value with one figure after the decimal point and this value can only be 0 or 5 (exemple with a rising temp you'll get 18.0 then 18.5 then 19.0 etc..) With a DS18B20 you have 4 figures after the decimal point.

Anyway I don't think it's worth a PR because DS18B20 are the standard, I don't know if you can still find DS18S20, and (remaining to check by me) if the calculation works with integer (as proposed by FrankX0), and I've seen (but not fully read) that the code has changed in the dev branch.

TerryE commented 7 years ago

Read the data sheet again; the S part only gives 9 bits of resolution.

Maximize System Accuracy in Broad Range of Thermal Management Applications

  • Measures Temperatures from -55°C to +125°C (-67°F to +257°F)
  • ±0.5°C Accuracy from -10°C to +85°C
  • 9-Bit Resolution
  • ...

The clone DS18B20s being so cheap, I am not sure why anyone would buy the S part

villeneuve commented 7 years ago

DS18S20 datasheet page 6:

Resolutions greater than 9 bits can be calculated using the data from the temperature, COUNT REMAIN and COUNT PER °C registers in the scratchpad. Note that the COUNT PER °C register is hard-wired to 16 (10h). After reading the scratchpad, the TEMP_READ value is obtained by truncating the 0.5°C bit (bit 0) from the temperature data (see Figure 4). The extended resolution temperature can then be calculated using the following equation:...

Maxim application Note APP 4377 : Comparison DS18B20 and DS18S20

The DS18S20 was designed to be a drop-in replacement for the original DS1820. To work as a replacement, the ADC in the DS18S20 is factory configured to always perform 12-bit conversions. The 12-bit data is then rounded to a 9-bit value and stored in the temperature register. To allow for greater than 9-bit resolution, a value for the Count Remain register is calculated. The Count Per °C register is set by the factory to be 16. Using the Count Remain and the Count Per °C registers and the formula above, up to 12-bit resolution can be obtained with the DS18S20.