Post your best Lua script examples here

User avatar
By JumpZero
#62770 Hello,

I have some 1wire temperature sensors. Some DS18B20 and some DS18S20
I've noticed that the DS18B20 one wire module for NODEMCU available here:
https://github.com/nodemcu/nodemcu-firm ... s18b20.lua
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/ ... S18S20.pdf
and here in this Maxim application note: comparison of both sensors
https://www.maximintegrated.com/en/app- ... vp/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.
I have slightly modified the ds18b20.lua script to have this fonctionnality here is the change:
line 108:
Code: Select allt = t * 5000 -- DS18S20, 1 fractional bit

replaced by 6 lines:
Code: Select all-- 12 bits resolution. If you need 9 bits only comment the
-- two following lines and un-comment the third
c = (((data:byte(8)-data:byte(7))/data:byte(8)) - 0.25) * 10000
t = (t * 5000) + c
-- t = t * 5000 -- DS18S20, 1 fractional bit


here is the full script. Hope it may help others... :-)

Code: Select all--------------------------------------------------------------------------------
-- DS18B20 one wire module for NODEMCU
-- NODEMCU TEAM
-- LICENCE: http://opensource.org/licenses/MIT
-- Vowstar <vowstar@nodemcu.com>
-- 2015/02/14 sza2 <sza2trash@gmail.com> Fix for negative values
--------------------------------------------------------------------------------

-- Set module name as parameter of require
local modname = ...
local M = {}
_G[modname] = M
--------------------------------------------------------------------------------
-- Local used variables
--------------------------------------------------------------------------------
-- DS18B20 dq pin
local pin = nil
-- DS18B20 default pin
local defaultPin = 9
--------------------------------------------------------------------------------
-- Local used modules
--------------------------------------------------------------------------------
-- Table module
local table = table
-- String module
local string = string
-- One wire module
local ow = ow
-- Timer module
local tmr = tmr
-- Limited to local environment
setfenv(1,M)
--------------------------------------------------------------------------------
-- Implementation
--------------------------------------------------------------------------------
C = 'C'
F = 'F'
K = 'K'
function setup(dq)
  pin = dq
  if(pin == nil) then
    pin = defaultPin
  end
  ow.setup(pin)
end

function addrs()
  setup(pin)
  tbl = {}
  ow.reset_search(pin)
  repeat
    addr = ow.search(pin)
    if(addr ~= nil) then
      table.insert(tbl, addr)
    end
    tmr.wdclr()
  until (addr == nil)
  ow.reset_search(pin)
  return tbl
end

function readNumber(addr, unit)
  result = nil
  setup(pin)
  flag = false
  if(addr == nil) then
    ow.reset_search(pin)
    count = 0
    repeat
      count = count + 1
      addr = ow.search(pin)
      tmr.wdclr()
    until((addr ~= nil) or (count > 100))
    ow.reset_search(pin)
  end
  if(addr == nil) then
    return result
  end
  crc = ow.crc8(string.sub(addr,1,7))
  if (crc == addr:byte(8)) then
    if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
      -- print("Device is a DS18S20 family device.")
      ow.reset(pin)
      ow.select(pin, addr)
      ow.write(pin, 0x44, 1)
      -- tmr.delay(1000000)
      present = ow.reset(pin)
      ow.select(pin, addr)
      ow.write(pin,0xBE,1)
      -- print("P="..present)
      data = nil
      data = string.char(ow.read(pin))
      for i = 1, 8 do
        data = data .. string.char(ow.read(pin))
      end
      -- print(data:byte(1,9))
      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)
        if (t > 32767) then
          t = t - 65536
        end

        if (addr:byte(1) == 0x28) then
          t = t * 625  -- DS18B20, 4 fractional bits
        else
          -- 12 bits resolution. If you need 9 bits only comment the
          -- two following lines and un-comment the third
          c = (((data:byte(8)-data:byte(7))/data:byte(8)) - 0.25) * 10000
          t = (t * 5000) + c
          -- 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
        return t
      end
      tmr.wdclr()
    else
    -- print("Device family is not recognized.")
    end
  else
  -- print("CRC is not valid!")
  end
  return result
end

function read(addr, unit)
  t = readNumber(addr, unit)
  if (t == nil) then
    return nil
  else
    return t
  end
end

-- Return module table
return M


--
Jmp0