Created
March 31, 2017 14:14
-
-
Save TerryE/5ea4f51492468a46b095279b0fff6935 to your computer and use it in GitHub Desktop.
ds18b20.lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-------------------------------------------------------------------------------- | |
-- DS18B20 one wire module for NODEMCU | |
-- NODEMCU TEAM | |
-- LICENCE: http://opensource.org/licenses/MIT | |
-- TerryE 26 Mar 2017 | |
-------------------------------------------------------------------------------- | |
-- Local variables | |
local modname = ... | |
-- DS18B20 dq and default pins | |
local defaultPin, pin, family = 9 | |
local DS18B20FAMILY = 0x28 | |
local DS1920FAMILY = 0x10 -- and DS18S20 series | |
local CONVERT_T | |
= 0x44 | |
local READ_SCRATCHPAD = 0xBE | |
local dev_addrs, dev_hash | |
-- Used modules and functions | |
local table, string, ow, tmr, print, type, tostring = | |
table, string, ow, tmr, print, type, tostring | |
-- Local functions | |
local ow_setup, ow_search, ow_select, ow_skip, ow_read_bytes, ow_write, ow_crc8, ow_reset = | |
ow.setup, ow.search, ow.select, ow.skip, ow.read_bytes, ow.write, ow.crc8, ow.reset | |
local now = tmr.now | |
local debugPrint = function() return end | |
local MODE = 0 | |
-------------------------------------------------------------------------------- | |
-- Implementation | |
-------------------------------------------------------------------------------- | |
local function init(dq, df) | |
pin = dq or pin or defaultPin | |
family = df or family or DS18B20FAMILY | |
end | |
local function enable_debug() | |
debugPrint = function (...) print(now(),' ', ...) end | |
end | |
local function to_string(addr,esc) | |
if type(addr) == 'string' and #addr == 8 then | |
return ( esc == true and | |
'"\\%u\\%u\\%u\\%u\\%u\\%u\\%u\\%u"' or | |
'%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8)) | |
else | |
return tostring(addr) | |
end | |
end | |
local function search_addrs() | |
if not dev_addrs then | |
debugPrint ("Reset Status = ", ow_reset(pin)) | |
ow_setup(pin) | |
debugPrint ('starting search') | |
ow.reset_search(pin) | |
ow.target_search(pin, family) | |
local addr = ow_search(pin) | |
dev_addrs, dev_hash = {}, {} | |
while addr do | |
debugPrint ('enter scan loop') | |
if addr:byte(8) == ow_crc8(addr:sub(1,7)) then | |
dev_hash[addr] = true | |
dev_addrs[#dev_addrs+1] = addr | |
end | |
debugPrint ("search returned ", to_string(addr), (dev_hash[addr] and 'found' or 'invalid CRC')) | |
addr = ow_search(pin) | |
tmr.wdclr() | |
end | |
debugPrint ('end of scan') | |
ow.depower(pin) | |
end | |
return dev_addrs | |
end | |
local function save_addrs() | |
if not dev_addrs then search_addrs() end | |
local addr_list = {} | |
for i =1, #dev_addrs do addr_list[i] = to_string(dev_addrs[i], true) end | |
local save_statement = 'return "ds18b20", {' .. table.concat(addr_list, ',') .. '}' | |
debugPrint (save_statement) | |
local save_file = file.open("ds18b20_save.lc","w") | |
save_file:write(string.dump(loadstring(save_statement))) | |
save_file:close() | |
end | |
local function get_addrs() | |
debugPrint ("Geting Addreses") | |
local s,check,a = pcall(dofile, "ds18b20_save.lc") | |
if s and check == "ds18b20" then | |
dev_addrs, dev_hash = a, {} | |
for i = 1, #a do dev_hash[a[i]] = true end | |
else | |
dev_addrs = nil | |
save_addrs() | |
end | |
debugPrint (#dev_addrs, "addreses found") | |
return dev_addrs | |
end | |
local function convert_T(addr) | |
if not dev_addrs then | |
get_addrs() | |
end | |
if addr ~= true and not dev_hash[addr] then | |
debugPrint ("Unknown address ", to_string(addr)) | |
return nil | |
end | |
ow_reset(pin) | |
ow_setup(pin) | |
if addr == true then | |
ow_skip(pin) | |
else | |
ow_select(pin, addr) | |
end | |
ow_write(pin, CONVERT_T, MODE) | |
debugPrint ("Convert issued to ", ((addr == true) and "*" or to_string(addr))) | |
return true | |
end | |
local function read(addr, unit) | |
if dev_addrs and dev_hash[addr] then | |
ow_reset(pin) | |
ow_setup(pin) | |
ow_select(pin, addr) | |
ow_write(pin, READ_SCRATCHPAD, MODE) | |
local data = ow_read_bytes(pin,9) | |
if ow_crc8(data:sub(1,8)) == data:byte(9) then | |
local t = (data:byte(1) + data:byte(2) * 256) | |
-- t is actually signed so process the sign bit and adjust for fractional bits | |
-- the DS18B20 family has 4 fractional bits and the DS18S20s, 1 fractional bit | |
t = ((t <= 32767) and t or t - 65536) * | |
((addr:byte(1) == DS18B20FAMILY) and 625 or 5000) | |
if(unit == nil or unit == 'C') then | |
t = t * 0.0001 | |
elseif(unit == 'F') then | |
t = t * 0.00018 + 32 | |
elseif(unit == 'K') then | |
t = t * 0.0001 + 273.15 | |
else | |
return nil | |
end | |
debugPrint(to_string(addr),"data read ",to_string(data:sub(1,8)), t) | |
return t | |
else | |
debugPrint(to_string(addr),"data read ",to_string(data:sub(1,8)), "CRC is not valid!") | |
end | |
else | |
debugPrint(to_string(addr),"unkown address") | |
end | |
return nil | |
end | |
-- Set module name as parameter of require and return module table | |
local M = { | |
C = 'C', F = 'F', K = 'K', | |
init = init, enable_debug = enable_debug, to_string = to_string, | |
search_addrs = search_addrs, save_addrs = save_addrs, get_addrs = get_addrs, | |
convert_T = convert_T, read = read, | |
} | |
_G[modname or 'ds18b20'] = M | |
return M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment