dht_lib.lua 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. -- ***************************************************************************
  2. -- DHTxx(11,21,22) module for ESP8266 with nodeMCU
  3. --
  4. -- Written by Javier Yanez mod by Martin
  5. -- but based on a script of Pigs Fly from ESP8266.com forum
  6. --
  7. -- MIT license, http://opensource.org/licenses/MIT
  8. -- ***************************************************************************
  9. --Support list:
  10. --DHT11 Tested
  11. --DHT21 Not Test yet
  12. --DHT22(AM2302) Tested
  13. --AM2320 Not Test yet
  14. --Output format-> Real temperature times 10(or DHT22 will miss it float part in Int Version)
  15. --==========================Module Part======================
  16. local moduleName = ...
  17. local M = {}
  18. _G[moduleName] = M
  19. --==========================Local the UMI and TEMP===========
  20. local humidity
  21. local temperature
  22. --==========================Local the bitStream==============
  23. local bitStream = {}
  24. ---------------------------Read bitStream from DHTXX--------------------------
  25. local function read(pin)
  26. local bitlength = 0
  27. humidity = 0
  28. temperature = 0
  29. -- Use Markus Gritsch trick to speed up read/write on GPIO
  30. local gpio_read = gpio.read
  31. for j = 1, 40, 1 do
  32. bitStream[j] = 0
  33. end
  34. -- Step 1: send out start signal to DHT22
  35. gpio.mode(pin, gpio.OUTPUT)
  36. gpio.write(pin, gpio.HIGH)
  37. tmr.delay(100)
  38. gpio.write(pin, gpio.LOW)
  39. tmr.delay(20000)
  40. gpio.write(pin, gpio.HIGH)
  41. gpio.mode(pin, gpio.INPUT)
  42. -- Step 2: Receive bitStream from DHT11/22
  43. -- bus will always let up eventually, don't bother with timeout
  44. while (gpio_read(pin) == 0 ) do end
  45. local c=0
  46. while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end
  47. -- bus will always let up eventually, don't bother with timeout
  48. while (gpio_read(pin) == 0 ) do end
  49. c=0
  50. while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end
  51. -- Step 3: DHT22 send data
  52. for j = 1, 40, 1 do
  53. while (gpio_read(pin) == 1 and bitlength < 10 ) do
  54. bitlength = bitlength + 1
  55. end
  56. bitStream[j] = bitlength
  57. bitlength = 0
  58. -- bus will always let up eventually, don't bother with timeout
  59. while (gpio_read(pin) == 0) do end
  60. end
  61. end
  62. ---------------------------Check out the data--------------------------
  63. ----Auto Select the DHT11/DHT22 By check the byte[1] && byte[3] -------
  64. ---------------Which is empty when using DHT11-------------------------
  65. function M.read(pin)
  66. read(pin)
  67. local byte_0 = 0
  68. local byte_1 = 0
  69. local byte_2 = 0
  70. local byte_3 = 0
  71. local byte_4 = 0
  72. for i = 1, 8, 1 do -- Byte[0]
  73. if (bitStream[i] > 3) then
  74. byte_0 = byte_0 + 2 ^ (8 - i)
  75. end
  76. end
  77. for i = 1, 8, 1 do -- Byte[1]
  78. if (bitStream[i+8] > 3) then
  79. byte_1 = byte_1 + 2 ^ (8 - i)
  80. end
  81. end
  82. for i = 1, 8, 1 do -- Byte[2]
  83. if (bitStream[i+16] > 3) then
  84. byte_2 = byte_2 + 2 ^ (8 - i)
  85. end
  86. end
  87. for i = 1, 8, 1 do -- Byte[3]
  88. if (bitStream[i+24] > 3) then
  89. byte_3 = byte_2 + 2 ^ (8 - i)
  90. end
  91. end
  92. for i = 1, 8, 1 do -- Byte[4]
  93. if (bitStream[i+32] > 3) then
  94. byte_4 = byte_4 + 2 ^ (8 - i)
  95. end
  96. end
  97. if byte_1==0 and byte_3 == 0 then
  98. ---------------------------Convert the bitStream into Number through DHT11's Way--------------------------
  99. --As for DHT11 40Bit is consisit of 5Bytes
  100. --First byte->Humidity Data's Int part
  101. --Sencond byte->Humidity Data's Float Part(Which should be empty)
  102. --Third byte->Temp Data;s Intpart
  103. --Forth byte->Temp Data's Float Part(Which should be empty)
  104. --Fifth byte->SUM Byte, Humi+Temp
  105. if(byte_4 ~= byte_0+byte_2) then
  106. humidity = nil
  107. temperature = nil
  108. else
  109. humidity = byte_0 *10 -- In order to universe with the DHT22
  110. temperature = byte_2 *10
  111. end
  112. else ---------------------------Convert the bitStream into Number through DHT22's Way--------------------------
  113. --As for DHT22 40Bit is consisit of 5Bytes
  114. --First byte->Humidity Data's High Bit
  115. --Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement)
  116. --Third byte->Temp Data's High Bit
  117. --Forth byte->Temp Data's Low Bit
  118. --Fifth byte->SUM Byte
  119. humidity = byte_0 * 256 + byte_1
  120. temperature = byte_2 * 256 + byte_3
  121. checksum = byte_4
  122. checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8))
  123. checksumTest = bit.band(checksumTest, 0xFF)
  124. if temperature > 0x8000 then
  125. -- convert to negative format
  126. temperature = -(temperature - 0x8000)
  127. end
  128. -- conditions compatible con float point and integer
  129. if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then
  130. humidity = nil
  131. end
  132. end
  133. byte_0 = nil
  134. byte_1 = nil
  135. byte_2 = nil
  136. byte_3 = nil
  137. byte_4 = nil
  138. end
  139. --------------API for geting the data out------------------
  140. function M.getTemperature()
  141. return temperature
  142. end
  143. function M.getHumidity()
  144. return humidity
  145. end
  146. -------------Return Index------------------------------------
  147. return M