DS18B20 module - update (enhanced, optimized) (#1996)
This commit is contained in:
parent
d079b842a8
commit
55c368ac03
|
@ -10,31 +10,40 @@ package.loaded["ds18b20"]=nil
|
||||||
```
|
```
|
||||||
<a id="ds18b20_setup"></a>
|
<a id="ds18b20_setup"></a>
|
||||||
|
|
||||||
## readTemp()
|
# Methods
|
||||||
Scans the bus for DS18B20 sensors, starts a readout (conversion) for all sensors and calls a callback function when all temperatures are available. Powered sensors are read at once first. Parasite-powered sensors are read one by one. The first parasite-powered sensor is read together with all powered sensors.
|
|
||||||
|
## read_temp()
|
||||||
|
Scans the bus for DS18B20 sensors (optional), starts a readout (conversion) for all sensors and calls a callback function when all temperatures are available. Powered sensors are read at once first. Parasite-powered sensors are read one by one. The first parasite-powered sensor is read together with all powered sensors.
|
||||||
|
|
||||||
The module requires `ow` module.
|
The module requires `ow` module.
|
||||||
|
|
||||||
The also module uses `encoder` module for printing debug information with more readable representation of sensor address (`encoder.toHex()`).
|
|
||||||
|
|
||||||
#### Syntax
|
#### Syntax
|
||||||
`readTemp(callback, pin)`
|
`read_temp(callback, pin, unit, force_search, save_search)`
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
- `callback` function that receives all results when all conversions finish. The callback function has one parameter - an array addressed by sensor addresses and a value of the temperature (string for integer version).
|
- `callback` function that receives all results when all conversions finish. The callback function has one parameter - an array addressed by sensor addresses and a value of the temperature (string for integer version).
|
||||||
- `pin` pin of the one-wire bus. If nil, GPIO0 (3) is used.
|
- `pin` pin of the one-wire bus. If nil, GPIO0 (3) is used.
|
||||||
|
- `unit` unit can be Celsius ("C" or ds18b20.C), Kelvin ("K" or ds18b20.K) or Fahrenheit ("F" or ds18b20.F). If not specified (nil) latest used unit is used.
|
||||||
|
- `force_search` if not nil a bus search for devices is performed before readout. If nil the existing list of sensors in memory is used. If the bus has not been searched yet the search performed as well.
|
||||||
|
- `save_search` if not nil found sensors are saved to the file `ds18b20_save.lc`. When `read_temp` is called, list of sensors in memory is empty and file `ds18b20_save.lc` is present then sensor addresses are loaded from file - usefull when running from batteries & deepsleep - immediate readout is performed (no bus scan).
|
||||||
|
|
||||||
#### Returns
|
#### Returns
|
||||||
nil
|
nil
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
```lua
|
```lua
|
||||||
t = require("ds18b20")
|
local t = require("ds18b20")
|
||||||
pin = 3 -- gpio0 = 3, gpio2 = 4
|
local pin = 3 -- gpio0 = 3, gpio2 = 4
|
||||||
|
|
||||||
function readout(temp)
|
local function readout(temp)
|
||||||
|
if t.sens then
|
||||||
|
print("Total number of DS18B20 sensors: ".. #t.sens)
|
||||||
|
for i, s in ipairs(t.sens) do
|
||||||
|
print(string.format(" sensor #%d address: %s%s", i, ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)), s:byte(9) == 1 and " (parasite)" or ""))
|
||||||
|
end
|
||||||
|
end
|
||||||
for addr, temp in pairs(temp) do
|
for addr, temp in pairs(temp) do
|
||||||
print(string.format("Sensor %s: %s 'C", encoder.toHex(addr), temp))
|
print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Module can be released when it is no longer needed
|
-- Module can be released when it is no longer needed
|
||||||
|
@ -42,13 +51,15 @@ function readout(temp)
|
||||||
package.loaded["ds18b20"]=nil
|
package.loaded["ds18b20"]=nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- t:readTemp(readout) -- default pin value is 3
|
t:read_temp(readout, pin, t.C)```
|
||||||
t:readTemp(readout, pin)
|
|
||||||
if t.sens then
|
## enable_debug()
|
||||||
print("Total number of DS18B20 sensors: "..table.getn(t.sens))
|
Enables debug output of the module.
|
||||||
for i, s in ipairs(t.sens) do
|
|
||||||
-- print(string.format(" sensor #%d address: %s%s", i, s.addr, s.parasite == 1 and " (parasite)" or ""))
|
# Properties
|
||||||
print(string.format(" sensor #%d address: %s%s", i, encoder.toHex(s.addr), s.parasite == 1 and " (parasite)" or "")) -- readable address with Hex encoding is preferred when encoder module is available
|
|
||||||
end
|
## sens
|
||||||
end
|
A table with sensors present on the bus. It includes its address (8 bytes) and information whether the sensor is parasite-powered (9-th byte, 0 or 1).
|
||||||
```
|
|
||||||
|
## temp
|
||||||
|
A table with readout values (also passed as a parameter to callback function). It is addressed by sensor addresses.
|
|
@ -1,26 +1,52 @@
|
||||||
-- encoder module is needed only for debug output; lines can be removed if no
|
|
||||||
-- debug output is needed and/or encoder module is missing
|
|
||||||
|
|
||||||
t = require("ds18b20")
|
t = require("ds18b20")
|
||||||
pin = 3 -- gpio0 = 3, gpio2 = 4
|
pin = 3 -- gpio0 = 3, gpio2 = 4
|
||||||
|
|
||||||
function readout(temp)
|
local function readout(temp)
|
||||||
|
if t.sens then
|
||||||
|
print("Total number of DS18B20 sensors: ".. #t.sens)
|
||||||
|
for i, s in ipairs(t.sens) do
|
||||||
|
print(string.format(" sensor #%d address: %s%s", i, ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)), s:byte(9) == 1 and " (parasite)" or ""))
|
||||||
|
end
|
||||||
|
end
|
||||||
for addr, temp in pairs(temp) do
|
for addr, temp in pairs(temp) do
|
||||||
-- print(string.format("Sensor %s: %s 'C", addr, temp))
|
print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp))
|
||||||
print(string.format("Sensor %s: %s °C", encoder.toHex(addr), temp)) -- readable address with base64 encoding is preferred when encoder module is available
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Module can be released when it is no longer needed
|
-- Module can be released when it is no longer needed
|
||||||
t = nil
|
--t = nil
|
||||||
package.loaded["ds18b20"]=nil
|
--package.loaded["ds18b20"]=nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- t:readTemp(readout) -- default pin value is 3
|
t:enable_debug()
|
||||||
t:readTemp(readout, pin)
|
file.remove("ds18b20_save.lc") -- remove saved addresses
|
||||||
if t.sens then
|
print("=============================================", node.heap())
|
||||||
print("Total number of DS18B20 sensors: "..table.getn(t.sens))
|
print("first call, no addresses in flash, search is performed")
|
||||||
for i, s in ipairs(t.sens) do
|
t:read_temp(readout, pin, t.C)
|
||||||
-- print(string.format(" sensor #%d address: %s%s", i, s.addr, s.parasite == 1 and " (parasite)" or ""))
|
|
||||||
print(string.format(" sensor #%d address: %s%s", i, encoder.toHex(s.addr), s.parasite == 1 and " (parasite)" or "")) -- readable address with base64 encoding is preferred when encoder module is available
|
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||||
end
|
print("=============================================", node.heap())
|
||||||
end
|
print("second readout, no new search, found addresses are used")
|
||||||
|
t:read_temp(readout, pin)
|
||||||
|
|
||||||
|
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||||
|
print("=============================================", node.heap())
|
||||||
|
print("force search again")
|
||||||
|
t:read_temp(readout, pin, nil, true)
|
||||||
|
|
||||||
|
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||||
|
print("=============================================", node.heap())
|
||||||
|
print("save search results")
|
||||||
|
t:read_temp(readout, pin, nil, false, true)
|
||||||
|
|
||||||
|
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||||
|
print("=============================================", node.heap())
|
||||||
|
print("use saved addresses")
|
||||||
|
t.sens={}
|
||||||
|
t:read_temp(readout, pin)
|
||||||
|
end)
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
|
@ -11,8 +11,7 @@ function readout(temp)
|
||||||
"<b>ESP8266</b></br>"
|
"<b>ESP8266</b></br>"
|
||||||
|
|
||||||
for addr, temp in pairs(temp) do
|
for addr, temp in pairs(temp) do
|
||||||
-- resp = resp .. string.format("Sensor %s: %s ℃</br>", addr, temp)
|
resp = resp .. string.format("Sensor %s: %s ℃</br>", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8)), temp)
|
||||||
resp = resp .. string.format("Sensor %s: %s ℃</br>", encoder.toHex(addr), temp) -- readable address with base64 encoding is preferred when encoder module is available
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resp = resp ..
|
resp = resp ..
|
||||||
|
@ -30,7 +29,7 @@ srv=net.createServer(net.TCP)
|
||||||
srv:listen(port,
|
srv:listen(port,
|
||||||
function(conn)
|
function(conn)
|
||||||
gconn = conn
|
gconn = conn
|
||||||
-- t:readTemp(readout) -- default pin value is 3
|
-- t:read_temp(readout) -- default pin value is 3
|
||||||
t:readTemp(readout, pin)
|
t:read_temp(readout, pin)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,121 +1,223 @@
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- DS18B20 one wire module for NODEMCU
|
-- DS18B20 one wire module for NODEMCU
|
||||||
-- by @voborsky, @devsaurus
|
-- NODEMCU TEAM
|
||||||
-- encoder module is needed only for debug output; lines can be removed if no
|
-- LICENCE: http://opensource.org/licenses/MIT
|
||||||
-- debug output is needed and/or encoder module is missing
|
-- @voborsky, @devsaurus, TerryE 26 Mar 2017
|
||||||
--
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- by default the module is for integer version, comment integer version and
|
local modname = ...
|
||||||
-- uncomment float version part for float version
|
|
||||||
|
-- Used modules and functions
|
||||||
|
local table, string, ow, tmr, print, type, tostring, pcall, ipairs =
|
||||||
|
table, string, ow, tmr, print, type, tostring, pcall, ipairs
|
||||||
|
-- Local functions
|
||||||
|
local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8, ow_reset, ow_reset_search, ow_skip, ow_depower =
|
||||||
|
ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8, ow.reset, ow.reset_search, ow.skip, ow.depower
|
||||||
|
local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY
|
||||||
|
local string_char, string_dump = string.char, string.dump
|
||||||
|
local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE
|
||||||
|
local table_sort, table_concat = table.sort, table.concat
|
||||||
|
local math_floor = math.floor
|
||||||
|
local file_open = file.open
|
||||||
|
|
||||||
|
table, string, tmr, ow = nil, nil, nil, nil
|
||||||
|
|
||||||
|
local DS18B20FAMILY = 0x28
|
||||||
|
local DS1920FAMILY = 0x10 -- and DS18S20 series
|
||||||
|
local CONVERT_T = 0x44
|
||||||
|
local READ_SCRATCHPAD = 0xBE
|
||||||
|
local READ_POWERSUPPLY= 0xB4
|
||||||
|
local MODE = 1
|
||||||
|
|
||||||
|
local pin, cb, unit = 3
|
||||||
|
local status = {}
|
||||||
|
|
||||||
|
local debugPrint = function() return end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
-- Implementation
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
local function enable_debug()
|
||||||
|
debugPrint = function (...) print(now(),' ', ...) end
|
||||||
|
end
|
||||||
|
|
||||||
return({
|
local function to_string(addr, esc)
|
||||||
pin=3,
|
if type(addr) == 'string' and #addr == 8 then
|
||||||
sens={},
|
return ( esc == true and
|
||||||
temp={},
|
'"\\%u\\%u\\%u\\%u\\%u\\%u\\%u\\%u"' or
|
||||||
|
'%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8))
|
||||||
conversion = function(self)
|
else
|
||||||
local pin = self.pin
|
return tostring(addr)
|
||||||
for i,s in ipairs(self.sens) do
|
|
||||||
if s.status == 0 then
|
|
||||||
print("starting conversion:", encoder.toHex(s.addr), s.parasite == 1 and "parasite" or " ")
|
|
||||||
ow.reset(pin)
|
|
||||||
ow.select(pin, s.addr) -- select the sensor
|
|
||||||
ow.write(pin, 0x44, 1) -- and start conversion
|
|
||||||
s.status = 1
|
|
||||||
if s.parasite == 1 then break end -- parasite sensor blocks bus during conversion
|
|
||||||
end
|
|
||||||
end
|
|
||||||
tmr.create():alarm(750, tmr.ALARM_SINGLE, function() self:readout() end)
|
|
||||||
end,
|
|
||||||
|
|
||||||
readTemp = function(self, cb, lpin)
|
|
||||||
if lpin then self.pin = lpin end
|
|
||||||
local pin = self.pin
|
|
||||||
self.cb = cb
|
|
||||||
self.temp={}
|
|
||||||
ow.setup(pin)
|
|
||||||
|
|
||||||
self.sens={}
|
|
||||||
ow.reset_search(pin)
|
|
||||||
-- ow.target_search(pin,0x28)
|
|
||||||
-- search the first device
|
|
||||||
local addr = ow.search(pin)
|
|
||||||
-- and loop through all devices
|
|
||||||
while addr do
|
|
||||||
-- search next device
|
|
||||||
local crc=ow.crc8(string.sub(addr,1,7))
|
|
||||||
if (crc==addr:byte(8)) and ((addr:byte(1)==0x10) or (addr:byte(1)==0x28)) then
|
|
||||||
ow.reset(pin)
|
|
||||||
ow.select(pin, addr) -- select the found sensor
|
|
||||||
ow.write(pin, 0xB4, 1) -- Read Power Supply [B4h]
|
|
||||||
local parasite = (ow.read(pin)==0 and 1 or 0)
|
|
||||||
table.insert(self.sens,{addr=addr, parasite=parasite, status=0})
|
|
||||||
print("contact: ", encoder.toHex(addr), parasite == 1 and "parasite" or " ")
|
|
||||||
end
|
|
||||||
|
|
||||||
addr = ow.search(pin)
|
|
||||||
tmr.wdclr()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- place powered sensors first
|
|
||||||
table.sort(self.sens, function(a,b) return a.parasite<b.parasite end)
|
|
||||||
|
|
||||||
node.task.post(node.task.MEDIUM_PRIORITY, function() self:conversion() end)
|
|
||||||
end,
|
|
||||||
|
|
||||||
readout=function(self)
|
|
||||||
local pin = self.pin
|
|
||||||
local next = false
|
|
||||||
if not self.sens then return 0 end
|
|
||||||
for i,s in ipairs(self.sens) do
|
|
||||||
-- print(encoder.toHex(s.addr), s.status)
|
|
||||||
if s.status == 1 then
|
|
||||||
ow.reset(pin)
|
|
||||||
ow.select(pin, s.addr) -- select the sensor
|
|
||||||
ow.write(pin, 0xBE, 0) -- READ_SCRATCHPAD
|
|
||||||
data = ow.read_bytes(pin, 9)
|
|
||||||
|
|
||||||
local t=(data:byte(1)+data:byte(2)*256)
|
|
||||||
if (t > 0x7fff) then t = t - 0x10000 end
|
|
||||||
if (s.addr:byte(1) == 0x28) then
|
|
||||||
t = t * 625 -- DS18B20, 4 fractional bits
|
|
||||||
else
|
|
||||||
t = t * 5000 -- DS18S20, 1 fractional bit
|
|
||||||
end
|
|
||||||
|
|
||||||
if 1/2 == 0 then
|
|
||||||
-- integer version
|
|
||||||
local sgn = t<0 and -1 or 1
|
|
||||||
local tA = sgn*t
|
|
||||||
local tH=tA/10000
|
|
||||||
local tL=(tA%10000)/1000 + ((tA%1000)/100 >= 5 and 1 or 0)
|
|
||||||
|
|
||||||
if tH and (tH~=85) then
|
|
||||||
self.temp[s.addr]=(sgn<0 and "-" or "")..tH.."."..tL
|
|
||||||
print(encoder.toHex(s.addr),(sgn<0 and "-" or "")..tH.."."..tL)
|
|
||||||
s.status = 2
|
|
||||||
end
|
|
||||||
-- end integer version
|
|
||||||
else
|
|
||||||
-- float version
|
|
||||||
if t and (math.floor(t/10000)~=85) then
|
|
||||||
self.temp[s.addr]=t/10000
|
|
||||||
print(encoder.toHex(s.addr), t)
|
|
||||||
s.status = 2
|
|
||||||
end
|
|
||||||
-- end float version
|
|
||||||
end
|
|
||||||
end
|
|
||||||
next = next or s.status == 0
|
|
||||||
end
|
|
||||||
if next then
|
|
||||||
node.task.post(node.task.MEDIUM_PRIORITY, function() self:conversion() end)
|
|
||||||
else
|
|
||||||
self.sens = nil
|
|
||||||
if self.cb then
|
|
||||||
node.task.post(node.task.MEDIUM_PRIORITY, function() self.cb(self.temp) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
})
|
end
|
||||||
|
|
||||||
|
local function readout(self)
|
||||||
|
local next = false
|
||||||
|
local sens = self.sens
|
||||||
|
local temp = self.temp
|
||||||
|
for i, s in ipairs(sens) do
|
||||||
|
if status[i] == 1 then
|
||||||
|
ow_reset(pin)
|
||||||
|
local addr = s:sub(1,8)
|
||||||
|
ow_select(pin, addr) -- select the sensor
|
||||||
|
ow_write(pin, READ_SCRATCHPAD, MODE)
|
||||||
|
data = ow_read_bytes(pin, 9)
|
||||||
|
|
||||||
|
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 1/2 == 0 then
|
||||||
|
-- integer version
|
||||||
|
if unit == 'F' then
|
||||||
|
t = (t * 18)/10 + 320000
|
||||||
|
elseif unit == 'K' then
|
||||||
|
t = t + 2731500
|
||||||
|
end
|
||||||
|
local sgn = t<0 and -1 or 1
|
||||||
|
local tA = sgn*t
|
||||||
|
local tH=tA/10000
|
||||||
|
local tL=(tA%10000)/1000 + ((tA%1000)/100 >= 5 and 1 or 0)
|
||||||
|
|
||||||
|
if tH and (t~=850000) then
|
||||||
|
temp[addr]=(sgn<0 and "-" or "")..tH.."."..tL
|
||||||
|
debugPrint(to_string(addr),(sgn<0 and "-" or "")..tH.."."..tL)
|
||||||
|
status[i] = 2
|
||||||
|
end
|
||||||
|
-- end integer version
|
||||||
|
else
|
||||||
|
-- float version
|
||||||
|
if t and (math_floor(t/10000)~=85) then
|
||||||
|
t = t / 10000
|
||||||
|
if unit == 'F' then
|
||||||
|
t = t * 18/10 + 32
|
||||||
|
elseif unit == 'K' then
|
||||||
|
t = t + 27315/100
|
||||||
|
end
|
||||||
|
self.temp[addr]=t
|
||||||
|
debugPrint(to_string(addr), t)
|
||||||
|
status[i] = 2
|
||||||
|
end
|
||||||
|
-- end float version
|
||||||
|
end
|
||||||
|
end
|
||||||
|
next = next or status[i] == 0
|
||||||
|
end
|
||||||
|
if next then
|
||||||
|
node_task_post(node_task_LOW_PRIORITY, function() return conversion(self) end)
|
||||||
|
else
|
||||||
|
--sens = {}
|
||||||
|
if cb then
|
||||||
|
node_task_post(node_task_LOW_PRIORITY, function() return cb(temp) end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function conversion(self)
|
||||||
|
local sens = self.sens
|
||||||
|
local powered_only = true
|
||||||
|
for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end
|
||||||
|
if powered_only then
|
||||||
|
debugPrint("starting conversion: all sensors")
|
||||||
|
ow_reset(pin)
|
||||||
|
ow_skip(pin) -- select the sensor
|
||||||
|
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||||
|
for i, s in ipairs(sens) do status[i] = 1 end
|
||||||
|
else
|
||||||
|
for i, s in ipairs(sens) do
|
||||||
|
if status[i] == 0 then
|
||||||
|
local addr, parasite = s:sub(1,8), s:byte(9)
|
||||||
|
debugPrint("starting conversion:", to_string(addr), parasite == 1 and "parasite" or " ")
|
||||||
|
ow_reset(pin)
|
||||||
|
ow_select(pin, addr) -- select the sensor
|
||||||
|
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||||
|
status[i] = 1
|
||||||
|
if parasite == 1 then break end -- parasite sensor blocks bus during conversion
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _search(self, lcb, lpin, search, save)
|
||||||
|
self.temp = {}
|
||||||
|
if search then self.sens = {}; status = {} end
|
||||||
|
local temp = self.temp
|
||||||
|
local sens = self.sens
|
||||||
|
pin = lpin or pin
|
||||||
|
|
||||||
|
local addr
|
||||||
|
if not search and #sens == 0 then
|
||||||
|
-- load addreses if available
|
||||||
|
debugPrint ("geting addreses from flash")
|
||||||
|
local s,check,a = pcall(dofile, "ds18b20_save.lc")
|
||||||
|
if s and check == "ds18b20" then
|
||||||
|
for i = 1, #a do sens[i] = a[i] end
|
||||||
|
end
|
||||||
|
debugPrint (#sens, "addreses found")
|
||||||
|
end
|
||||||
|
|
||||||
|
ow_setup(pin)
|
||||||
|
if search or #sens == 0 then
|
||||||
|
ow_reset_search(pin)
|
||||||
|
-- ow_target_search(pin,0x28)
|
||||||
|
-- search the first device
|
||||||
|
addr = ow_search(pin)
|
||||||
|
else
|
||||||
|
for i, s in ipairs(sens) do status[i] = 0 end
|
||||||
|
end
|
||||||
|
local function cycle()
|
||||||
|
debugPrint("cycle")
|
||||||
|
if addr then
|
||||||
|
local crc=ow_crc8(addr:sub(1,7))
|
||||||
|
if (crc==addr:byte(8)) and ((addr:byte(1)==DS1920FAMILY) or (addr:byte(1)==DS18B20FAMILY)) then
|
||||||
|
ow_reset(pin)
|
||||||
|
ow_select(pin, addr)
|
||||||
|
ow_write(pin, READ_POWERSUPPLY, MODE)
|
||||||
|
local parasite = (ow_read(pin)==0 and 1 or 0)
|
||||||
|
sens[#sens+1]= addr..string_char(parasite) -- {addr=addr, parasite=parasite, status=0}
|
||||||
|
debugPrint("contact: ", to_string(addr), parasite == 1 and "parasite" or " ")
|
||||||
|
end
|
||||||
|
addr = ow_search(pin)
|
||||||
|
node_task_post(node_task_LOW_PRIORITY, cycle)
|
||||||
|
else
|
||||||
|
ow_depower(pin)
|
||||||
|
-- place powered sensors first
|
||||||
|
table_sort(sens, function(a, b) return a:byte(9)<b:byte(9) end) -- parasite
|
||||||
|
-- save sensor addreses
|
||||||
|
if save then
|
||||||
|
debugPrint ("saving addreses to flash")
|
||||||
|
|
||||||
|
local addr_list = {}
|
||||||
|
for i =1, #sens do
|
||||||
|
local s = sens[i]
|
||||||
|
addr_list[i] = to_string(s:sub(1,8), true)..('.."\\%u"'):format(s:byte(9))
|
||||||
|
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
|
||||||
|
-- end save sensor addreses
|
||||||
|
if lcb then node_task_post(node_task_LOW_PRIORITY, lcb) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
cycle()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_temp(self, lcb, lpin, lunit, force_search, save_search)
|
||||||
|
cb, unit = lcb, lunit or unit
|
||||||
|
_search(self, function() return conversion(self) end, lpin, force_search, save_search)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set module name as parameter of require and return module table
|
||||||
|
local M = {
|
||||||
|
sens = {},
|
||||||
|
temp = {},
|
||||||
|
C = 'C', F = 'F', K = 'K',
|
||||||
|
read_temp = read_temp, enable_debug = enable_debug
|
||||||
|
}
|
||||||
|
_G[modname or 'ds18b20'] = M
|
||||||
|
return M
|
||||||
|
|
Loading…
Reference in New Issue