Tutorial: Basics of IoT with a NodeMCU chip

Jani Saranpää
Junction
Published in
13 min readApr 13, 2018

--

This blog post was written for the purposes of a workshop at Stupid Hack, an annual event organised by Junction, where the goal is to create the stupidest and most useless projects imaginable.

Recently, the Internet of things (IoT) has has joined among the hot topics to discuss about. However, as a community of creators (at Junction) we are not only interested discuss about it, but we also want to create with it. That’s why I’m going to show you the basics, so you can get started with IoT stuff. So shall we start?

This tutorial was written for the annual event by Junction called Stupid Hack. The idea was to offer participants introductory workshops at the beginning of the event, so people can use this knowledge later while getting close to stupidity with their projects. Though the main idea for this tutorial was to serve as a workshop for the participants, anyone can do this with a proper resources anytime.

If you yet don’t have your own hardware, you can easily buy it from electronic stores specified at the bottom. If you luckily live near the capital region of Finland, you can also consider borrowing hardware from Junction. Instructions for renting are also located at the bottom of this post after the tutorial.

Topics covered in this tutorial:

Prerequisities

Resources

Arduino IDE Installation

  1. Introduction to hardware and Arduino IDE — How buttons and LEDs work?
  2. Connecting a sensor into the chip — DHT22 (Humidity and Temperature)
  3. HTTP Communication —GET & POST Requests, WebServer
  4. Post-tutorial — Additional functionalities and other material

Prerequisities

You should have a basic knowledge of programming. If you are a web developer, you definitely can manage to go through this tutorial. The code we are going to write in this tutorial is beginner friendly, so no worries.

Some understanding of understanding electricity is a also helpful for you, but is not mandatory for this tutorial.

Resources needed:

  • Development environment installed (Arduino IDE is recommended)
  • 1 NodeMCU ESP8266 WiFi microcontroller
  • 1 Breadboard
  • 1 LED & Resistor for LED
  • 1 Button
  • Few jumper wires
  • 1 DHT22 Temperature & Humidity sensor
  • 1 MicroUSB cable
  • A laptop

Arduino IDE installation

1. Install the Arduino IDE from https://www.arduino.cc/en/Main/Software

2. Open Arduino IDE and add the board manager link to the preferences

If you can’t see the additional board manager field, you may have wrong version installed. Make sure you have the latest version by reinstalling the software from www.arduino.cc.

3. Install the new board manager for ESP8266 chip

  • In the Arduino IDE Go to Tools -> Board (…) -> Boards manager…
  • Search for “ESP8266”, click the suggested result and press install

4. Confirm the installation and choose the NodeMCU board for the current board

  • Go to Tools -> Board (…) and select “NodeMCU 1.0 (ESP 12-E module)” from the list

5. You’re done configuring the IDE and ready to start developing with the chip!

  • If you’re using Linux, ensure that your user have permissions to use the ports. Instructions are available at www.arduino.cc.
  • MAC & Windows: If the chip is not working properly, check that you have proper USB-to-Serial connection drivers installed in your system. You can find your chip’s Serial type from the bottom of the chip. In most cases, it should be either CP210x or CH340(G). Here are links for CP210x drivers, and for CH340(G) drivers.

1. Introduction to hardware and Arduino IDE — How buttons and LEDs work?

This module is the introductory module for using hardware components. You are going to learn how to connect the components into the chip and how can you run simple programs inside the chip. We start out with connecting the chip to the computer and testing that it actually works. Then we continue with plugging simple components, like LED bulb and a button, into the chip.

Introducing a simple program

Each arduino program has two mandatory functions: setup() and loop(). The code inside the setup() function is executed once and the function is good for setting up your arduino program environment at the beginning. The loop() function is run constantly while the chip is powered and have already executed the initializing setup() function. You can support these two functions with other methods.

Basic operation of an arduino program

Useful commands in setup() function :

Declaring pins:

// Macros
#define LED D2
--or--// Variables
const int LED = 4;
// NOTE! You can use either 4 or D2 value for the same pin. Check
// the schematic picture for the right values.

Defining the type of the pin, or the pin mode:

pinMode(pin, mode);  // e.g. pinMode(LED, OUTPUT);/* Modes */
INPUT // e.g. buttons, switches, keyboards, ...
INPUT_PULLUP // inverted INPUT
OUTPUT // e.g. LEDs, screens, ...

Useful commands in loop():

Usage of the pins:

/* Digital pins (such as NodeMCU most of the pins) */digitalWrite(pin, value); // values are used to activate the pin
digitalRead(pin);
/* Values */
value == LOW // Off
value == HIGH // On

For a more comprehensive documentation of the functions, navigate to https://www.arduino.cc/reference/en/

Running our first program on the chip

Enough talking, let’s play!

Roger that! Open now the Arduino IDE and open an example project called “Blink”. You can find it by navigating File->Examples->1. Basics->Blink. Read the documentation of the file, so you understand how it works.

You can start to run the program in your chip by clicking the “Upload” button in your Arduino IDE. Sometimes uploading can fail unexpected, so you may want to try it for a few times if the first time is not working.

Uploading a program into the arduino device

If the uploading works, the led in the nodeMCU chip should start blinking. HOORAY! We have successfully uploaded the first program in our chip. Let’s continue with attaching bunch of components into the chip.

The CHIP —NodeMCU

NodeMCU is an inexpensive and powerful development chip (cost between 3–12$) that have good I/O capabilities with GPIO pins and can also communicate with other devices using WiFi. This makes it ideal for our use to prototype in small-scale IoT applications.

Here is a picture of pin mapping:

The title says NodeMCU ESP-12, but the same mapping is used also in ESP8266 based NodeMCU boards. Source: http://crufti.com/content/images/2015/11/nodemcudevkit_v1-0_io.jpg

There are some restrictions for how you can use pins, but for this tutorial it is easier for you to just use those pins labeled as “Dx” (e.g. D5, x= number). If you want to have a better explanation, check the pin definitions in here https://tttapa.github.io/ESP8266/Chap04%20-%20Microcontroller.html.

Attaching a LED into the chip

Next, we are going to add an external LED with a capacitor to the board and going to light it up with our code. Now, connect the LED and the resistor to the NodeMCU according to the picture below. LEDs bypasses the current only in one direction, so it’s important to plug it in a correct way. Look inside the LED or compare the length of the “legs” with the picture below for a proper installation.

If you are using a breadboard, you can use the picture as a reference for doing connections. Try to place the NodeMCU chip in the middle of the breadboard so the edges the wires will be open and, thus, allow you to manage the wiring easier (and keep the pins available for connections).

Caution! Make sure you are not connecting multiple pins to the same wire.

An example of leaving the wirings (columns ‘A’ and ‘J’) open for connections. Source: https://alexbloggt.com/wp-content/uploads/2016/07/button_nodemcu.png
Connecting a LED to the chip. Source: http://micropython-on-esp8266-workshop.readthedocs.io/en/latest/basics.html
Wirings on the breadboard. The right picture shows how the lines are connected inside. Use those lines to connect components to the chip. Source: https://learn.sparkfun.com/tutorials/how-to-use-a-breadboard

Okay, now that we have the LED connected, we need to change the code to recognize this change.

First, we have to redefine the pin mode in setup() function. I have attached the LED to pin D5:

pinMode(D5, OUTPUT);

Then change the pin value in the pin usage functions:

digitalWrite(D5, HIGH);
...
digitalWrite(D5, LOW);

Your code should look like this:

void setup() {
pinMode(D5, OUTPUT); // Defining LED pin
}
void loop() {
digitalWrite(D5, HIGH); // LED On
delay(1000);
digitalWrite(D5, LOW); // LED Off
delay(1000);
}

Now we should have the external LED blinking. Cooooooool. But we want to control it. So, let’s add a button into the chip.

Adding a button

Let’s leave the LED still connected into the chip and add the button to it. Plug one pin from the button to a digital pin, such as D2, and other pin to the gnd (Ground) pin. See the pic below for a proper installation.

Source: https://github.com/goliatone/wee-things-workshop/tree/master/tutorials/5-button

And then coding continues…

Open File->2. Digital-> Button. The sketch should work out of the box with updating pin values. If you can’t find the sketch from examples, navigate to http://www.arduino.cc/en/Tutorial/Button and copy the code.

When you have uploaded the code to the chip, the LED should be lighted already. When you press the button, the led turns off. As default, the input pin is in HIGH value, what means that there is current going through constantly. You can invert this by adjusting code a bit:

/* From */if (buttonState == HIGH) {
...
/* To */if (buttonState == LOW) {
...

And here we have a functioning button attached in the NodeMCU chip.

Nice little thing this button, but it would be cool if the LED stays On…

Okay, so what do we need? We need to save the state and toggle the state while pressing the button. I think you can manage that. :D

Wait a minute! My code looks fine, but it still isn’t working…

Yup, there is this one issue with buttons — they are mechanic and, thus, can cause unexpected behavior. This unexpected behavior usually is caused by the by the noise that can make fast undesired changes in the button state. To simplify the issue with the noise, imagine a situation where you drop a ball on the floor and it keeps bouncing for a while. Similarly, when you press the button, the button keeps bouncing for a while before it stabilizes to the desired state. In practice, bouncing changes the button’s state rapidly, that in this case also toggles your LED. Below is a picture showing the impact of bouncing.

Button Bouncing | Source: en.wikipedia.org/wiki/Switch

To avoid the noise we have to implement Debouncing. Try to think of ways how to identify and make distinction between intentional and unintentional presses and how to avoid latter. If you get stuck, use the good old arduino IDE examples library. There exists one solution for this particular issue as well (Hint: 02. Digital).

If you wish to have more comprehensive view of the debouncing, there are good videos in youtube, for instance, this one https://www.youtube.com/watch?v=pn8gGNyirhI. Also, you can read more about switches on Wikipedia.

I guess that’s it for the 1st section of this tutorial. Let’s continue with attaching a data measuring sensor into the chip and tracking data.

2. Connecting a Sensor and monitoring data (DHT + Serial Monitor)

After learning the basics of the hardware, it is time to add some sensors on it. In this module, we are going to plug a humidity and temperature tracking sensor into the microcontroller and read the data measurements through the serial port of the ESP8266 microcontroller.

Installing a library for using DHT sensors

Why bother to code your own functions, if someone have already made them for ya.

In arduino IDE, open Sketch->Include Library->Manage Libraries. Search with a keyword “DHT” and install the library into your arduino IDE. Install version 1.2.3. since version 1.3.0 have some issues with dependencies.

Attaching a DHT22 Sensor to the chip

Plug the DHT22 Sensor to the chip according to the pic below. DHT22 have three wires instead of two: one for power supply (positive), one for ground (negative), and one for digital output (O)pin.

Plugging DHT22 to the NodeMCU chip

Welcome Serial Monitor!

You may have guessed, that we are again using the awesome arduino IDE library of examples. Now, open File->Examples-> DHT sensor library -> DHTtester. Modify the pin value according to your connections and upload the program. It should work out of the box.

But how can we read the data from the sensor?

We have to open the Serial Monitor to catch the messages from the chip. Navigate Tools -> Serial Monitor. Now you have opened the Serial Monitor that is great tool for reading user input and printing the output. You can use Serial Monitor for printing and reading user input. To start using the Serial Monitor, you have to start it with a command:

Serial.begin(9600);

Note! When you open the Serial monitor, make sure you have set the baud rate same in the code and in the Serial Monitor.

Serial Monitor in Arduino IDE

After you have successfully uploaded the sketch to the NodeMCU, you should start receiving similar values as there are above. As you might see from the code, you can print data to Serial Monitor by using commands:

Serial.print("Printed stuff");  // Missing newline char from end
--or--
Serial.println("Printed stuff"); // Prints the newline char also

You can input data with a command:

Serial.read()

You can try to fool around with blowing lightly to DHT to validate that it actually works. As a result of blowing, the humidity rate should start increasing. Don’t be too rough on the DHT. These sensors are sensitive.

Okay guys, this section was a bit shorter than the previous one. Let’s continue with other interesting stuff. I bet you are here to learn the cool IoT stuff. In the next, section we look connect this little beast chip to the Internet and start to communicate with it by using HTTP protocol. So let’s goooo…

3. HTTP communication (Sending temp-data over Internet)

In this module, we are going to build a HTTP functionalities in our program. The goals include learning to make GET- and POST-requests with the microcontroller acting as a client and running a wireless webserver in our ESP8266 device. After these learnings you are able to control the microcontroller over the Internet.

GET-request

There are two ways to make GET-requests:

a. ) Using library ESP8266HTTPClient

Open File -> Examples -> ESP8266HTTPClient->BasicHttpClient

#include <ESP8266HTTPClient.h>...HTTPClient http;http.begin("http://jsonplaceholder.typicode.com/"); // Initialize connectionint statusCode = http.GET();  // Returns HTTP statuscode or error code...

b.) Write the request from scratch

This is not maybe so nice, but it’s also another option to make it work. For a reference project, open File -> ESP8266WiFi -> WiFiClient.


#include <ESP8266WiFi.h>
...String host = "http://jsonplaceholder.typicode.com";String url = "/";const int port = 80;...
WiFiClient client;
client.connect(host, port);client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
client.readStringUntil('\r'); // Read first line of response

POST-request

a) Using library ESP8266HTTPClient

Unfortunately, there are not an example sketch for POST-requests, but you can also use this tutorial: https://techtutorialsx.com/2016/07/21/esp8266-post-requests/

#include <ESP8266HTTPClient.h>...HTTPClient http;http.begin("http://jsonplaceholder.typicode.com/posts");      //Specify request destinationhttp.addHeader("Content-Type", "text/plain");  //Specify content-type headerint httpCode = http.POST("Message from ESP8266"); //Send the requestString responseData = http.getString();  //Get the response dataSerial.println(httpCode);   //Print HTTP return codeSerial.println(responseData);    //Print responseData

b) Write request from scratch

/* An example */...client.println("POST /posts HTTP/1.1");
client.println("Host: jsonplaceholder.typicode.com");
client.println("Accept: */*");
client.println("Content-Type: application/x-www-form-urlencoded"); // Key-value pairs
client.print("Content-Length: ");
client.println(data.length());
client.println();
client.print(data);...

WebServer

For hosting a web server, you just need to add the request handlers into your chip’s program.

Open File -> Examples -> ESP8266WiFi -> WiFiWebServer for a simple example. In this example, the code just builds a response in html telling the state of the pin (HIGH or LOW).

// Read the first line of the request
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();

// Handling requests
int val;
if (req.indexOf("/gpio/0") != -1) // if "/gpio/0" in req header?
state = 0;
else if (req.indexOf("/gpio/1") != -1)
state = 1;
else {
Serial.println("invalid request");
client.stop();
return;
}
...// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s += (val)?"high":"low";
s += "</html>\n";
// Send the response to the client
client.print(s);

There also may exist some example using a library. Can you find it ? :P

I think it’s time for the last task. Let’s build your own wireless HTTP server that can:

  • Control the LED from the browser with a toggle button
  • Log the data from the DHT Sensor

4. Continuing the journey

There are still many areas that we didn’t cover in this tutorial, such as:

  • Websockets (Connectivity)
  • HTTPS connections
  • Servos (Moving objects)
  • Deepsleep (Energy-efficiency)
  • More advanced I/O devices (screens, keyboards, etc…)

Good websites to continue with

Internet has quite a lot of materials to introduce you to new functionalities of these NodeMCU little beasts. Here is a list of bunch of sources, but there are many more you can look for with your search engine:

Buying your own gear

Here are just a few places you can buy your own hardware for a few bucks:

  • Global vendors: Aliexpress, Exp-tech,
  • Local vendors (These are in Finland): Ihmevekotin.fi, Partco, …

Renting your gear ???

Junction is going to launch the new hardware renting platform. Go ahead and navigate to hwlab.hackjunction.com, and browse through different hardware options that Junction can offer for your use. Junction’s hwlab is located at Aalto University’s campus in Espoo, Otaniemi (In Finland).

If you are interested, here is a cool documentary about hardware manufacturing in Shenzen:

--

--