85 lines
2.1 KiB
Lua
85 lines
2.1 KiB
Lua
|
------------------------------------------------------------------------------
|
||
|
-- DHT11/22 query module
|
||
|
--
|
||
|
-- LICENCE: http://opensource.org/licenses/MIT
|
||
|
-- Vladimir Dronnikov <dronnikov@gmail.com>
|
||
|
--
|
||
|
-- Example:
|
||
|
-- print("DHT11", require("dht22").read(4))
|
||
|
-- print("DHT22", require("dht22").read(4, true))
|
||
|
-- NB: the very first read sometimes fails
|
||
|
------------------------------------------------------------------------------
|
||
|
local M
|
||
|
do
|
||
|
-- cache
|
||
|
local gpio = gpio
|
||
|
local val = gpio.read
|
||
|
local waitus = tmr.delay
|
||
|
--
|
||
|
local read = function(pin, dht22)
|
||
|
-- wait for pin value
|
||
|
local w = function(v)
|
||
|
local c = 255
|
||
|
while c > 0 and val(pin) ~= v do c = c - 1 end
|
||
|
return c
|
||
|
end
|
||
|
-- NB: we preallocate incoming data buffer
|
||
|
-- or precise timing in reader gets broken
|
||
|
local b = { 0, 0, 0, 0, 0 }
|
||
|
|
||
|
-- kick the device
|
||
|
gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
|
||
|
gpio.write(pin, 1)
|
||
|
waitus(10)
|
||
|
gpio.mode(pin, gpio.OUTPUT)
|
||
|
gpio.write(pin, 0)
|
||
|
waitus(20000)
|
||
|
gpio.write(pin, 1)
|
||
|
gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
|
||
|
-- wait for device presense
|
||
|
if w(0) == 0 or w(1) == 0 or w(0) == 0 then
|
||
|
return nil, 0
|
||
|
end
|
||
|
-- receive 5 octets of data, msb first
|
||
|
for i = 1, 5 do
|
||
|
local x = 0
|
||
|
for j = 1, 8 do
|
||
|
x = x + x
|
||
|
if w(1) == 0 then return nil, 1 end
|
||
|
-- 70us for 1, 27 us for 0
|
||
|
waitus(30)
|
||
|
if val(pin) == 1 then
|
||
|
x = x + 1
|
||
|
if w(0) == 0 then return nil, 2 end
|
||
|
end
|
||
|
end
|
||
|
b[i] = x
|
||
|
end
|
||
|
-- check crc. NB: calculating in receiver loop breaks timings
|
||
|
local crc = 0
|
||
|
for i = 1, 4 do
|
||
|
crc = (crc + b[i]) % 256
|
||
|
end
|
||
|
if crc ~= b[5] then return nil, 3 end
|
||
|
-- convert
|
||
|
local t, h
|
||
|
-- DHT22: values in tenths of unit, temperature can be negative
|
||
|
if dht22 then
|
||
|
h = b[1] * 256 + b[2]
|
||
|
t = b[3] * 256 + b[4]
|
||
|
if t > 0x8000 then t = -(t - 0x8000) end
|
||
|
-- DHT11: no negative temperatures, only integers
|
||
|
-- NB: return in 0.1 Celsius
|
||
|
else
|
||
|
h = 10 * b[1]
|
||
|
t = 10 * b[3]
|
||
|
end
|
||
|
return t, h
|
||
|
end
|
||
|
-- expose interface
|
||
|
M = {
|
||
|
read = read,
|
||
|
}
|
||
|
end
|
||
|
return M
|