瀏覽代碼

Support DS18S20 and fix negative temp handling

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 <nick@nick-andrew.net>
Nick Andrew 8 年之前
父節點
當前提交
0a7b730e23
共有 2 個文件被更改,包括 38 次插入13 次删除
  1. 25 5
      lua_examples/onewire-ds18b20.lua
  2. 13 8
      lua_modules/ds18b20/ds18b20.lua

+ 25 - 5
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 <vowstar@nodemcu.com>
@@ -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

+ 13 - 8
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()