yet-another-dht22.lua 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. ------------------------------------------------------------------------------
  2. -- DHT11/22 query module
  3. --
  4. -- LICENCE: http://opensource.org/licenses/MIT
  5. -- Vladimir Dronnikov <dronnikov@gmail.com>
  6. --
  7. -- Example:
  8. -- print("DHT11", dofile("dht22.lua").read(4))
  9. -- print("DHT22", dofile("dht22.lua").read(4, true))
  10. -- NB: the very first read sometimes fails
  11. ------------------------------------------------------------------------------
  12. local M
  13. do
  14. -- cache
  15. local gpio = gpio
  16. local val = gpio.read
  17. local waitus = tmr.delay
  18. --
  19. local read = function(pin, dht22)
  20. -- wait for pin value
  21. local w = function(v)
  22. local c = 255
  23. while c > 0 and val(pin) ~= v do c = c - 1 end
  24. return c
  25. end
  26. -- NB: we preallocate incoming data buffer
  27. -- or precise timing in reader gets broken
  28. local b = { 0, 0, 0, 0, 0 }
  29. -- kick the device
  30. gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
  31. gpio.write(pin, 1)
  32. waitus(10)
  33. gpio.mode(pin, gpio.OUTPUT)
  34. gpio.write(pin, 0)
  35. waitus(20000)
  36. gpio.write(pin, 1)
  37. gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
  38. -- wait for device presense
  39. if w(0) == 0 or w(1) == 0 or w(0) == 0 then
  40. return nil, 0
  41. end
  42. -- receive 5 octets of data, msb first
  43. for i = 1, 5 do
  44. local x = 0
  45. for j = 1, 8 do
  46. x = x + x
  47. if w(1) == 0 then return nil, 1 end
  48. -- 70us for 1, 27 us for 0
  49. waitus(30)
  50. if val(pin) == 1 then
  51. x = x + 1
  52. if w(0) == 0 then return nil, 2 end
  53. end
  54. end
  55. b[i] = x
  56. end
  57. -- check crc. NB: calculating in receiver loop breaks timings
  58. local crc = 0
  59. for i = 1, 4 do
  60. crc = (crc + b[i]) % 256
  61. end
  62. if crc ~= b[5] then return nil, 3 end
  63. -- convert
  64. local t, h
  65. -- DHT22: values in tenths of unit, temperature can be negative
  66. if dht22 then
  67. h = b[1] * 256 + b[2]
  68. t = b[3] * 256 + b[4]
  69. if t > 0x8000 then t = -(t - 0x8000) end
  70. -- DHT11: no negative temperatures, only integers
  71. -- NB: return in 0.1 Celsius
  72. else
  73. h = 10 * b[1]
  74. t = 10 * b[3]
  75. end
  76. return t, h
  77. end
  78. -- expose interface
  79. M = {
  80. read = read,
  81. }
  82. end
  83. return M