Arduino ile Webserver-ESP8266
Spark Core Energy Monitor
NodeMCU - DHT11 Webserver
Connecting Raspberry
Error Message
Serial Communication
Interfacing LCD

Simple Temperature and Humidity Webserver with NodeMCU




In this article, NodeMCU (ESP8266 with USB Connection) is used with DHT11 (with a shield) temperature and humidity sensor to implement a webserver that broadcasts ambient temperature and humidity. A simple Lua program to achieve the web server is also attached to the end of this article.

Barış Sanlı ,


Simple Temperature and Humidity Webserver with NodeMCU.. 1

Summary. 1

Introduction. 1

NodeMCU.. 1

NodeMCU from Online Stores. 2

Installing the Driver. 3

Installing the Flasher and Flashing Firmware. 4

Micropython Firmware. 6

Installing ESPlorer. 6

ESPlorer Interface. 6

Hardware. 9

DHT11 Library. 10

First Program – sicaklik.lua. 14

To the Next Level – Wifi AP. 15

The Code. 16

Result. 18

One Final Touch. 20

Appendix- wifidht.lua. 21








NodeMCU is a low cost, wifi enabled microcontroller. It lets you design and implement low-cost Internet of Things (IoT) projects rapidly but with a dent on performance. It is like the Commodore 64 of Internet of Things.

In this page, I will try to explain how to implement a simple webserver project that displays temperature and humidity.



NodeMCU is basically ESP8266+USB-TTL bridge. All the microcontroller stuff is carried out on the ESP8266 part, including WiFi.

NodeMCU webpage has all the advertorial things about this simple board. You can run Lua and MicroPython codes on it. You can do most of these things with a ESP8266 Wifi board only, if you have a USB-TTL converter.


Before using your NodeMCU you need to go through the following steps.

1.      Install driver for CH340 (USB to Serial chip)

2.      Download ESP Flasher

3.      Download the firmware you choose

a.       Latest Lua (We will use that one)

b.      Experimental Micropython

4.      Flash the NodeMCU with the firmware you choose

5.      Install the programming interface – ESPlorer

6.      Try to connect with Baudrate 9600


NodeMCU from Online Stores


NodeMCU is a ESP8266 with USB2TTL chips, as far as I understand. You can buy a ESP-201, or any ESP8266 and carry on with it. For example is ESP-201 is quite similar to NodeMCU but the USB to TTL part is missing.

NodeMCU is around 7$ as of July 2015. You can buy from Aliexpress, Banggood and other sites. For Turkey, my NodeMCU arrived around 21 days.

When you first get your NodeMCU you may get surprise that only one ADC is available, although there are enough digital pins for remote control projects. If you plug the device to your PC, your pc may not recognize the device and you can run in to trouble. So you have to install driver.

Installing the Driver


All the software you need to use NodeMCU is available at:

For driver you have to look for “nodemcu-devkit” folder. In it there is a folder called “Drivers”

If you are using windows download file. CH341 is the USB to Serial chip’s tag. Therefore you are not installing NodeMCU drivers but the interface ones. Since operating system just needs to know there is a USB to Serial chip, the rest will be assured by software.

Click on the relevant drive and press “View Raw” in the next screen to download zip file. The contents of the zip file contains a single exe file

You may need to run it as an administrator. The following screen will appear and hit install


Installing the Flasher and Flashing Firmware


This time we will move to the

address and download Win32 or Win64 release from the page. Again “view raw” to download.

ESP8266 Flasher comes with the Lua firmware and when you run it burns the Lua firmware to your NodeMCU.


If not try the following link to get the latest firmware

When you run the ESPFlasher, it comes with a default firmware. You can always access to this firmware from the tab “Advanced”>> “Restore default”


If you want to flash another firmware, for ex: Micropython, save the firmware in the same directory with ESPFlasher. Then write the name of file in the top row starting from 0x00000. This is the memory position that writing will start. However consult the web pages for the firmware installation procedures.


Micropython Firmware


Adafruit web page has an extensive discussion on MicroPython and ESP8266. You should better consult their web page:

For example MicroPython usage:

Anyway, we will continue with Lua firmware. Now the next step is to install programming interface.

Installing ESPlorer


You do not need any specific interface to connect with you NodeMCU. Putty can simply do the work. However I found ESPlorer quite useful.

To download ESPlorer:

ESPlorer run with Java, so you may need to install JDK as well. ESPlorer is only one of the options.

ESPlorer Interface


ESPlorer interface is quite crowded but useful. On the left hand side, you can write you code. On the right hand side, you can see the communication exchanges.

My advice is to start with baud rate 9600.

From the top of right hand side select Com port and press connect.


Make sure you selected the Com port, baud rate correctly and press Open

For MicroPython use 115200 baud rate.

For Lua firmware baud rate 9600 is enough. After connection you will see the following screen.

The command “=node.heap()” gives some kind of available memory. My chip is not empty. I have written some hand programs to ease my job. One of them is “dir.lua” .

This program displays the programs at the ESP’s flash memory. Until you delete them, they survive. I have 4 programs.

To view the programs in your kit, check the next screenshot. Write the codes to you editor screen and then press “Send to ESP”.

You can alternatively Save to ESP, save as init file etc.

When you “Send to ESP”, the program transmits the code to the serial port of NodeMCU and you can see the response immediately.



Ok, since we are ready to implement our web server, lets start by hardware design… If you are familiar with my Arduino example (, the only important thing here is whether you have a shielded DHT 11 or not. DHT 11 with a shield has 3 pins, a bare DHT11 has 4 pins.

What you need to know for connection is the pins for VCC, GND, Data(In our case D1 pin)

Your connection should look like the picture below.


DHT11 Library


To use DHT11, you need the necessary library to use it from Lua.

These libraries are available at:


In the dht_lib directory, you will find the relevant example in the file. But first we need to save “dht_lib.lua” file to NodeMCU

Click dht_lib.lua file and when the page opens, press “Raw” to get the raw version of the file .

Raw format is the original text file “dht_lib.lua”:

Select all and copy. Then paste into ESPlorer, preferably in a new tab

Now we will save the file in to NodeMCU by clicking “Save to ESP” from the left hand side. A new window will pop up and request the files name. type “dht_lib.lua”, then press save.


PROBLEM: I have experienced some problems while saving the dht_lib.lua file. The comments are causing some problems, so delete the comment lines (starting with “—“) and try again

The other problem while saving “dht_lib.lua” is the inline comments with brackets (“—Byte[0]” ). So if you have the same problem of error screens during writing operation remove the inline comments at the end of “for” lines.

Also you may want to remove the empty spaces at the very end of file. Such that your code ends with “return M” and no spaces follow it.

If no errors your screen will look like this: (do not worry about table nil).

First Program – sicaklik.lua


Now we are ready to run our first program. We will write a program to test DHT library. I changed the following code to make sure that the data is available  (while do loop).

The problem is the data from DHT may not be available instantly, therefore I check both t and h is ready then print the value.

PIN = 1 --  data pin, GPIO1

DHT= require("dht_lib")


t = DHT.getTemperature()

h = DHT.getHumidity()


while ((t == nil) or (h==nil)) do



  t = DHT.getTemperature()

  h = DHT.getHumidity()



-- temperature in degrees Celsius  and Farenheit

print("Temperature: "..((t-(t % 10)) / 10).."."..(t % 10).." deg C")

-- humidity

print("Humidity: "..((h - (h % 10)) / 10).."."..(h % 10).."%")


-- release module

DHT = nil



Lua code is straight forward. It just loads the library, then receives the temperature and stores is in “t” value, and reads humidity and saves it in “h”. Waits until both t and h is not “nil”. Then removes the fractional part and prints the integer part  as a string followed by  a “.”(dot) and then the fractional part. At the end it recycles the DHT to bin to save memory. Again let’s save the program:

“Save to ESP” -> “sicaklik.lua”

After saving the program we are ready to run the program “sicaklik.lua”

Type dofile(“sicaklik.lua”) and wait for the result.

To the Next Level – Wifi AP


There are several Wifi modes

-          Either you connect to a modem/router

-          Or work as a standalone access point

o   With password

o   Without password

All these three modes of connection is given below:

Access point without Pass

Access Point with Pass

Station Mode

-- Wifi Connection Settings

-- Access Point Without Password

-- AP name will be either ESP8266 or ESF_XXXX






-- End of Wifi Connection Settings

-- Wifi Connection Settings

-- Access Point With Password






-- End of Wifi Connection Settings

-- Wifi Connection Settings

-- Connecting to a Wifi Router




while wifi.sta.getip()==nil do

 -- 7 seconds before exit



 if i==8 then break; end




-- End of Wifi Connection Settings


From now on our code is simplified. I will implement the (2) Access point with Pass. If you implement the (1) first one without password, ESP8266 does not consider your SSID settings. So if you want to name your SSID you should give a password with minimum 8 characters

The Code


Our code has 4 parts

1.      Setting the initial variable and library

2.      Configuring wireless settings

3.      Creating a server & listenin port 80 (www requests)

a.       When request comes

                                                               i.      Read from DHT

                                                             ii.      If value is nil, wait until a value is received

                                                            iii.      Create a string that prints these values

                                                           iv.      Send the string

                                                             v.      Close the request

                                                           vi.      Close the connection

4.      Unload DHT library


1.      Setting the initial variable and library

2.      Configuring wireless settings – Remember, this is AP with a Password “12345678”

3.      Creating a server & listening port 80 (www requests)

a.       When request comes

                                                               i.      Read from DHT

                                                             ii.      If value is nil, wait until a value is received

                                                            iii.      Create a string that prints these values (calculation is inside). In Lua “..” merges two strings

                                                           iv.      Send the string

                                                             v.      Close the request & connection and listen function

4.      Unload DHT library




So when you save and run the program, it doesn’t print much. Just makes sure that you are at the right WiFi mode.

But when you open your mobile device and search for Wifi networks. Within the list you will see “BARIS-SUNUCU” or whatever name you used.

As you try to connect BARIS-SUNUCU, it will ask for password. We used 12345678 as the password in the program. So just typing it will do the trick and you will connect.

Now, open your browser and enter the address

The web page will include temperature value as “Sicaklik”, and humidity as “Nem”

One Final Touch


As our program runs well, it still needs a user to initiate it from the serial port. When power is gone, or cable is disconnected, the program will be halted and will not run until someone runs it again.

Therefore, we will use “init.lua” as our initializer (like boot manager) and whenever our device boots, it will re run our program.

For “init.lua” never directly put the programs name because you may end up setting an infinite loop at ESP8266. The device may not respond to your connection attempts and you may need to reflash it.

Therefore use timer commands (tmr) to automatically run and wait sometime. So if anything goes wrong, you can interfere from the command line during that delay time.

Therefore edit a new file with the following code:

tmr.alarm(0, 5000, 0, function()



Then save it as “init.lua” .

That is it. Now yourprogram will run everytime the power is resupplied.




Barış Sanlı


12 July 2015



Appendix- wifidht.lua



PIN = 1 --  data pin, GPIO2

DHT= require("dht_lib")



-- Wifi Connection Settings

-- Access Point With Password






-- End of Wifi Connection Settings



print("ESP8266 mode is: " .. wifi.getmode())




    conn:on("receive", function(client,request);

        t = DHT.getTemperature();

        h = DHT.getHumidity();

        while ((t == nil) or (h==nil)) do




           t = DHT.getTemperature()

           h = DHT.getHumidity()


        buf="<font size=80>Sicaklik: "..((t-(t % 10)) / 10).."."..(t % 10).." deg C </br>";

        buf=buf .. "Nem: "..((h - (h % 10)) / 10).."."..(h % 10).."%</font>";