From 0a7b730e232af7964bba803844612ade42158553 Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Mon, 16 Nov 2015 23:32:20 +1100 Subject: [PATCH] Support DS18S20 and fix negative temp handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DS18S20 has only 1 fractional bit whereas DS18B20 has 4, and their temperature register alignment differs. Check the family code to choose the correct multiplier for both devices. Closes #610 Negative temperatures (less than 0°C) are returned as a sign-extended two's complement number. Subtract 0x10000 to recover the proper negative value. Signed-off-by: Nick Andrew --- lua_examples/onewire-ds18b20.lua | 30 +++++++++++++++++++++++++----- lua_modules/ds18b20/ds18b20.lua | 21 +++++++++++++-------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/lua_examples/onewire-ds18b20.lua b/lua_examples/onewire-ds18b20.lua index ed728bbc..a1a03b23 100644 --- a/lua_examples/onewire-ds18b20.lua +++ b/lua_examples/onewire-ds18b20.lua @@ -1,5 +1,5 @@ --' --- 18b20 one wire example for NODEMCU +-- ds18b20 one wire example for NODEMCU (Integer firmware only) -- NODEMCU TEAM -- LICENCE: http://opensource.org/licenses/MIT -- Vowstar @@ -40,10 +40,30 @@ else crc = ow.crc8(string.sub(data,1,8)) print("CRC="..crc) if (crc == data:byte(9)) then - t = (data:byte(1) + data:byte(2) * 256) * 625 - t1 = t / 10000 - t2 = t % 10000 - print("Temperature= "..t1.."."..t2.." Centigrade") + t = (data:byte(1) + data:byte(2) * 256) + + -- handle negative temperatures + if (t > 0x7fff) then + t = t - 0x10000 + end + + if (addr:byte(1) == 0x28) then + t = t * 625 -- DS18B20, 4 fractional bits + else + t = t * 5000 -- DS18S20, 1 fractional bit + end + + local sign = "" + if (t < 0) then + sign = "-" + t = -1 * t + end + + -- Separate integral and decimal portions, for integer firmware only + local t1 = string.format("%d", t / 10000) + local t2 = string.format("%04u", t % 10000) + local temp = sign .. t1 .. "." .. t2 + print("Temperature= " .. temp .. " Celsius") end tmr.wdclr() until false diff --git a/lua_modules/ds18b20/ds18b20.lua b/lua_modules/ds18b20/ds18b20.lua index 138c10da..20ebd1d7 100644 --- a/lua_modules/ds18b20/ds18b20.lua +++ b/lua_modules/ds18b20/ds18b20.lua @@ -101,18 +101,23 @@ function readNumber(addr, unit) if (t > 32767) then t = t - 65536 end - if(unit == nil or unit == C) then - t = t * 625 - elseif(unit == F) then - t = t * 1125 + 320000 - elseif(unit == K) then - t = t * 625 + 2731500 + + if (addr:byte(1) == 0x28) then + t = t * 625 -- DS18B20, 4 fractional bits + else + t = t * 5000 -- DS18S20, 1 fractional bit + end + + if(unit == nil or unit == 'C') then + -- do nothing + elseif(unit == 'F') then + t = t * 1.8 + 320000 + elseif(unit == 'K') then + t = t + 2731500 else return nil end t = t / 10000 - -- print("Temperature="..t1.."."..t2.." Centigrade") - -- result = t1.."."..t2 return t end tmr.wdclr()