ESP8266 Lua DHT11 Temperature and Humidity Sensor

After receiving my ESP8266 Development/breakout board I have been attempting to create a WiFi enabled thermostat to control my central heating from my mobile phone and give me a means of timer programming my central heating. To be a true thermostat requires a temperature sensor. The ESP8266 board came with a DHT11 sensor and already has pins directly compatible with one. I therefore just required the software to interface with it.


There are a number of discussions and versions of software over at ESP8266.com forums but not all of them worked for me as I was mostly getting Humidity readings of -1% due to the checksums not matching. In the end I found the following was the only code which worked (shared by jankop on the forum). I have commented out the debugging code which displays the actual timing data relating to the communication.

-- ***************************************************************************
-- for communication of DHT sensor only
-- DHT module for ESP8266 with nodeMCU floating point
-- Written by Javier Yanez
-- but based on a script of Pigs Fly from ESP8266.com forum
-- MIT license, http://opensource.org/licenses/MIT
-- ***************************************************************************

local moduleName = ...
local M = {}
_G[moduleName] = M

local humidity
local temperature

function M.read(pin)
  local checksum
  local checksumTest
  humidity = 0
  temperature = 0
  checksum = 0

  -- Use Markus Gritsch trick to speed up read/write on GPIO
  local gpio_read = gpio.read

  local bitStream = {}
   for j = 1, 40, 1 do
    bitStream[j] = 0
  end
  local bitlength = 0

  -- Step 1:  send out start signal to DHT22
  gpio.mode(pin, gpio.OUTPUT)
  gpio.write(pin, gpio.HIGH)
  tmr.delay(100)
  gpio.write(pin, gpio.LOW)
  tmr.delay(20000)
  gpio.write(pin, gpio.HIGH)
  gpio.mode(pin, gpio.INPUT)

  -- Step 2:  DHT22 send response signal
  -- bus will always let up eventually, don't bother with timeout
  while (gpio_read(pin) == 0 ) do end
  local c=0
  while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end
  -- bus will always let up eventually, don't bother with timeout
  while (gpio_read(pin) == 0 ) do end
  c=0
  while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end

  -- Step 3: DHT22 send data
  for j = 1, 40, 1 do
    while (gpio_read(pin) == 1 and bitlength < 10 ) do
      bitlength = bitlength + 1
    end
    bitStream[j] = bitlength
    bitlength = 0
    -- bus will always let up eventually, don't bother with timeout
    while (gpio_read(pin) == 0) do end
  end
   hum=" "
   tem=" "
   chk=" "
  --DHT data acquired, process.
  for i = 1, 16, 1 do
  hum=hum.." "..tostring(bitStream[i])
  tem=tem.." "..tostring(bitStream[i+16])
	if (bitStream[i] > 3) then
      humidity = humidity + 2 ^ (16 - i)
	end
    if (bitStream[i + 16] > 3) then
      temperature = temperature + 2 ^ (16 - i)
	end
  end
  for i = 1, 8, 1 do
  chk=chk.." "..tostring(bitStream[i+32])
	if (bitStream[i + 32] > 3) then
      checksum = checksum + 2 ^ (8 - i)
	end
  end
    checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8))
  checksumTest = bit.band(checksumTest, 0xFF)

  if temperature > 0x8000 then
    -- convert to negative format
    temperature = -(temperature - 0x8000)
  end

  -- conditions compatible con float point and integer
  if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then
    humidity = nil
  end
  --print("checksum ", checksum)
  --print("checksumTest ", checksumTest)
  --print("humidity - timing of bits ",hum)
  --print("temperat - timing of bits ",tem)
  --print("checksum - timing of bits ",chk)
end

function M.getTemperature()
  return temperature
end

function M.getHumidity()
  return humidity
end

return M

The differences seemed to be in the timings where the code waits for the data line to transition at before data reading begins, and also in the data processing section with slightly different bitStream processing. This file should be uploaded using the Lualoader to the ESP as ‘testdht.lua’

The proper usage of this code is as follows (upload as ‘wots.lua’).

--    Test communication of DHT sensor
--    Tested with Lua NodeMCU 0.9.5 build 20150127 floating point !!!
-- 1. Flash Lua NodeMCU to ESP module.
-- 2. Set in program wots.lua humidity sensor type. This is parameter typeSensor="dht11" or "dht22".
-- 3. Load program wots.lua and testdht.lua to ESP8266 with LuaLoader
-- 4. HW reset module
-- 5. Run program wots.lua - dofile(wots.lua)


sensorType="dht11" 			-- set sensor type dht11 or dht22

	PIN = 2 --  data pin, GPIO0
	humi=0
	temp=0
	--load DHT module for read sensor
function ReadDHT()
	dht=require("testdht")
	dht.read(PIN)
	chck=1
	h=dht.getHumidity()
	t=dht.getTemperature()
	if h==nil then h=0 chck=0 end
	if sensorType=="dht11"then
		humi=h/256
		temp=t/256
	else
		humi=h/10
		temp=t/10
	end
	fare=(temp*9/5+32)
	print("Humidity:    "..humi.."%")
	print("Temperature: "..temp.." deg C")
	-- release module
	dht=nil
	package.loaded["testdht"]=nil
end
ReadDHT()

I then get some sensible data out such as:

Humidity:    49%
Temperature: 21 deg C

9 thoughts on “ESP8266 Lua DHT11 Temperature and Humidity Sensor

  1. Pingback: Bezprzewodowe czujniki wilgotności DHT11 na ESP8266 - techfreak.pl

  2. Ashwini

    hello sir, I tried your code “wots.lua” in my lua Uploader v1.0.2.2. Its running properly but every time i am getting humidity 0% and Temperature: -128 deg C. Also my sensor dht11 is running properly . As before trying this I have tested it on my arduino. please help

    Reply
  3. Dean

    Hi, great work and very informative.. I have a query and have gotten a bit lost in the code.

    When i call dofile (“wots.lua”), it runs and returns both meaningful Temp & Humi, all good. If i then run the command dofile(“wots.lua”) again, the ESP hangs, then reboots. If i run the same command,once again I get meaningful answers.. I have looked t both lots of code and struggling to work out whats happening. Pretty much very new to Arduino’s and the ESP.

    Also how do i call and publish the results to a web browser?

    I appreciate any advice you may have

    Thank you

    Reply
  4. joni

    Hi, can you post circuit diagram for this?

    I want to develop a temperature and humidity sensor with esp8266 only with out any additional circut( arduino ) ..etc can you guide me. thanks 🙂

    Reply
  5. Peter

    I get strange values with my DHT11… as you can see below i doesn´t get the checksum to work. I tried to adjust the value “3” up and down in the code lines according to: (bitStream[i] > 3)
    Nothing seems to work and i tried to add a pullup resistor, a capacitor and still no success 🙁
    Maybe you can point me into the right direction? Do you have any idea?

    Greetz Peter

    checksum 215
    checksumTest 209
    humidity – timing of bits 0 1 1 1 5 1 1 1 1 1 1 1 1 1 1 1
    temperat – timing of bits 4 5 1 1 5 1 1 1 1 1 1 1 1 1 1 4
    checksum – timing of bits 5 5 1 5 1 10 10 10
    Humidity: 0%
    Temperature: -72.00390625 deg C

    Reply
    1. liuaihua

      i get the same error, reload the “nodemcu_integer_0.9.6-dev_20150406.bin” firmware, then rethy ,will be ok.

      if you use the “nodemcu_integer_0.9.6-dev_20150704.bin” , it has include the” dht lib”,read dht directly “pin = 3
      status, temp, humi, temp_dec, humi_dec = dht.read(pin)
      if status == dht.OK then
      — Integer firmware using this example
      print(string.format(“DHT Temperature:%d.%03d;Humidity:%d.%03d\r\n”,
      math.floor(temp),
      temp_dec,
      math.floor(humi),
      humi_dec
      ))

      — Float firmware using this example
      print(“DHT Temperature:”..temp..”;”..”Humidity:”..humi)

      elseif status == dht.ERROR_CHECKSUM then
      print( “DHT Checksum error.” )
      elseif status == dht.ERROR_TIMEOUT then
      print( “DHT timed out.” )
      end

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *