Sei sulla pagina 1di 117

Copyright

NodeMCU Development Workshop


Agus Kurniawan
1st Edition, 2015
Copyright 2015 Agus Kurniawan
Table of Contents
Copyright
Preface
1. Preparing Development Environment
1.1 NodeMCU
1.2 Electronics Components
1.2.1 Arduino Starter Kit
1.2.2 Fritzing
1.2.3 Cooking-Hacks: Arduino Starter Kit
1.2.4 Arduino Sidekick Basic kit v2
1.2.5 Grove - Starter Kit for Arduino
1.2.6 DFRobot - Arduino Kit for Beginner v3
1.3 Development Tools
1.4 Testing
2. Setting Up NodeMCU
2.1 Getting Started
2.2 Connecting NodeMCU board to Computer
2.3 Flashing The Latest NodeMCU Firmware
2.3.1 Windows Platform
2.3.2 Linux and OS X Platforms
2.4 Development Tools
2.4.1 Serial/UART Tool
2.4.2 Arduino IDE
2.4.3 NodeMCU Studio
2.5 Hello NodeMCU: Blinking LED
2.5.1 Wiring
2.5.2 Writing Program Using Serial/UART Tool
2.5.3 Uploading Lua Script File to NodeMCU Board
3. Lua Programming Language
3.1 Preparing Development Environment
3.2 Common Rule
3.3 Variables
3.3.1 Declaring Variable
3.3.2 Assigning Variables
3.3.3 Demo
3.4 Comment
3.5 Arithmetic Operations
3.6 Mathematical Functions
3.7 Increment and Decrement
3.8 Comparison Operators
3.9 Logical Operators
3.10 Decision - if..then
3.11 Iteration - for
3.12 Iteration - while
3.13 Iteration - repeat
3.14 break and do
3.15 Array
3.16 Functions
3.17 Lua Modules
4. GPIO Programming
4.1 Getting Started
4.2 Wiring
4.3 Writing a Program
4.4 Testing
5. PWM and Analog Input
5.1 Getting Started
5.2 Demo Analog Output (PWM) : RGB LED
5.2.1 Wiring
5.2.2 Writing Program
5.2.3 Testing
5.3 Demo Analog Input: Working with Potentiometer
5.3.1 Wiring
5.3.2 Writing Program
5.3.3 Testing
6. Working with I2C
6.1 Getting Started
6.2 Writing Program
6.3 Writing Program
6.4 Testing
7. UART
7.1 Getting Started
7.2 Wiring
7.3 Writing a Program
7.4 Testing
8. SPI
8.1 Getting Started
8.2 Wiring
8.3 Writing a Program
8.4 Testing
9. Working with OLED Display
9.1 Getting Started
9.2 Wiring
9.3 Writing a Program
9.4 Testing
10. Connecting to a Network
10.1 Connecting to a WiFi Hotspot
10.2 Building a Simple Web Server
Source Code
Contact
Preface


This book was written to help anyone want to get started with NodeMCU v2 board development. It describes the
basic elements of NodeMCU development starting with Lua programming.


Agus Kurniawan
Depok, July 2015
1. Preparing Development Environment
1.1 NodeMCU
NodeMCU is an open source IoT platform. It uses the Lua scripting language. NodeMCU
was created shortly after the ESP8266 came out. Further information, you can read it
on http://nodemcu.com/index_en.html . The following is a form of NodeMCU v2.

You can buy this product on your local electronic store. The following is the list of
Arduino store you can buy

SeeedStudio, http://www.seeedstudio.com/
Amazon, http://www.amazon.com
eBay, http://www.ebay.com
Banggood, http://www.banggood.com/
DX, http://www.dx.com/
1.2 Electronics Components
We need electronic components to build our testing, for instance, Resistor, LED, sensor
devices and etc. I recommend you can buy electronic component kit. We can use
electronics kit from Arduino to be developed on NodeMCU. The following is a list of
electronics kit which can be used in our case.

1.2.1 Arduino Starter Kit


Store website: http://arduino.cc/en/Main/ArduinoStarterKit

1.2.2 Fritzing
Store website: http://shop.fritzing.org/ .
You can buy Fritzing Starter Kit with Arduino UNO or Fritzing Starter Kit with Arduino
Mega.
1.2.3 Cooking-Hacks: Arduino Starter Kit
Store website: http://www.cooking-hacks.com/index.php/shop/arduino/starter-
kits/arduino-starter-kit.html
1.2.4 Arduino Sidekick Basic kit v2
Store website: http://www.seeedstudio.com/depot/Sidekick-Basic-Kit-for-Arduino-V2-p-
1858.html
You also can find this kit on this online store.
http://www.exp-tech.de/seeed-studio-sidekick-basic-kit-for-arduino-v2
1.2.5 Grove - Starter Kit for Arduino
Another option, you can buy this kit on Seeedstudio,
http://www.seeedstudio.com/depot/Grove-Starter-Kit-for-Arduino-p-1855.html .

1.2.6 DFRobot - Arduino Kit for Beginner v3


DFRobot provides Arduino kit too. You can buy it on the following website.
http://www.dfrobot.com/index.php?route=product/product&path=35_49&product_id=345
1.3 Development Tools
To develop app with NodeMCU target, we can use any editor. In this book, I use Arduino
IDE for text editor. You can learn how to install it on chapter 2.
1.4 Testing
For testing, I used NodeMCU v2 on Windows 8.1.

I also used Arduino Sidekick Basic kit for electronic components.


2. Setting Up NodeMCU

This chapter explains how to work on setting up NodeMCU board.


2.1 Getting Started
In this chapter, we learn how to get started with NodeMCU board. We try to reflash the
latest NodeMCU firmware and then test some basic scripts.
2.2 Connecting NodeMCU board to Computer
Firstly, you connect NodeMCU board to PC via microUSB cable. After connected, you
may get lighting on blue LED.

If you are working on Windows platform, open Device Manager, you should see
NodeMCU board detected on Ports (COM & LPT).
However, if you get a problem about NodeMCU hardware driver, you update that driver.
You also can install a driver from Silicon Labs because NodeMCU v2 uses this chip,
from https://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx .
Please download it based on your platform.
For instance, you download the driver for mac. Just follow instructions.
After installed, you verify it. For instance, on my OS X it has detected. Type this
command.
ls /dev/cu*

For Linux, you can use ls /dev/tty* .


Then, you see a list of driver. This board is recognized as /dev/cu.SLAB_USBtoUART .
Next up, on your computer, use a serial console program such as CoolTerm (Mac) or Putty
(Windows) or screen (linux) to connect to NodeMCU board. For instance, I used PuTTY
on Windows.
If success, you should get NodeMCU shell in Lua script. You may get a problem, shown
in Figure below.

In this case, we must flash the latest NodeMCU firmware. I will explain it on the next
section.
2.3 Flashing The Latest NodeMCU Firmware
In this section, we try to flash the latest NodeMCU firmware. You can get the latest
NodeMCU firmware on https://github.com/nodemcu/nodemcu-firmware . Download *.bin
file.
In this scenario, I try to flash NodeMCU firmware on Windows, OSX and Linux.

2.3.1 Windows Platform


In this section, I show you how to flash it on Windows platform.
To flash firmware, you can use NodeMCU flasher. Please download NodeMCU Flasher
on https://github.com/nodemcu/nodemcu-flasher . There are two binary platforms, x86
and x64. Open the program so you get the dialog as below.

Select COM Port where NodeMCU was attached.


Then, click Advanced tab. Select Baudrate 5700 and SPI Mode is DIO.
Click Config tab and select firmware file.

On Operation tab, you start by clicking Flash button.


If done, you will get a notification.

To test, you can use serial/UART tool and connect to NodeMCU board. Set NodeMCU
serial port and set baudrate 9600.
Then, connect to the board. If success, you should see NodeMCU shell.
Try to write a simple script print(Hello NodeMCU) so you will get a response.

2.3.2 Linux and OS X Platforms


If youre working on Linux or Mac, you can use esptool.py tool
from https://github.com/nodemcu/nodemcu-firmware/tree/master/tools . Just follow the
instruction.
In this section, I show you how to flash NodeMCU using Flasher, Flash Download tool,
from http://bbs.espressif.com/viewtopic.php?f=5&t=433 . This tool actually runs
Windows platform. In this case, you need to install wine tool, https://www.winehq.org , to
emulate for running on Linux or OS X.
Firstly, install wine tool. You can type this command on Linux platform, for instance,
Ubuntu Linux.
$ sudo add-apt-repository ppa:ubuntu-wine/ppa
$ sudo apt-get update
$ sudo apt-get install wine1.7

If youre working with OS X, you can install it via brew


$ brew install wine

Then, download the latest Flashing tool from Espressif


on http://bbs.espressif.com/viewtopic.php?f=5&t=433 . To extract this file, you need
unrar. For instance, you can install it via brew on OS X platform.
$ brew install unrar

After extracted, navigate to flashing too. Then, run it via wine.


$ wine flash_download_tool_v1.2_150512.exe

After running, wine directory has created. Navigate to dosdevices folder and create a
symlink to your NodeMCU tty device. For instance, on OS X my NodeMCU has detected
on /dev/tty.SLAB_USBtoUART so I map it to com1 .
$ cd ~/.wine/dosdevices
$ ln -s /dev/tty.SLAB_USBtoUART com1

You can close and run this tool.


Now you can flash NodeMCU firmware for NodeMCU v2 with the following parameters;
see green highlight. Set CrystalFreq 26M, FlASH SIZE 32Mbit, SPI SPEED 40MHz and
SPI MODE DIO. Select COM Port to com1
If done, click START button. It will flash firmware to the board.
If done, you can test it using Serial/UART tool.
Select serial port of NodeMCU and set baudrate 9600. Then, try to connect. If success,
you should see Lua shell.
You can write simple program using print().
> print("Hello NodeMCU")

Shell will response this script.


2.4 Development Tools
In this case, I show you several development tools you can use it in NodeMCU
development.

2.4.1 Serial/UART Tool


By default, you can use Serial/UART tools such as CoolTerm (Mac) or Putty (Windows)
or screen (linux) .

You also can use Realterm, http://realterm.sourceforge.net/ and Tera


Term, http://ttssh2.osdn.jp/index.html.en .

2.4.2 Arduino IDE


If you have experience in Arduino development, you can use Arduino IDE to develop
NodeMCU board too. You can use add-on on your Arduino using this
library, https://github.com/esp8266/Arduino .
Open Arduino IDE.
Then, click menu File -> Prefernces (Windows/Linux) or Arduino -> Preferences (OS X)
so you should see Preferences dialog.
Add http://arduino.esp8266.com/package_esp8266com_index.json on Additional Boards
Manager URLs . If you have the list on there, just add ; for new list item,
If done, click OK button.
Click menu Tools -> Board -> Boards Managers.
Then, you should see Boards Manager dialog. Find esp8266 board and install it.

After installed, you can see a list of ESP8266 Modules target on Arduino IDE.
Now you can write the program for NodeMCU.

2.4.3 NodeMCU Studio


This tool is still development tool and written in C#. You may get problems while you are
developing a program. You can download this tool
on https://github.com/nodemcu/nodemcu-studio-csharp . We can wait the released version
of this tool.
2.5 Hello NodeMCU: Blinking LED
In this section, we build a blinking LED program via Lua shell. We use serial tool to write
a program.
Firstly, you must know NodeMCU GPIO. The following is NodeMCU v2 GPIO.

2.5.1 Wiring
Connect LED on NodeMCU D1. Other LED pin is be connected to NodeMCU GND.
Now you connect NodeMCU board to Computer via USB cable.
2.5.2 Writing Program Using Serial/UART Tool
The first demo is to blink a LED. Type this script per lin on Serial/UART tool.
-- hello.lua
pin = 1
gpio.mode(pin,gpio.OUTPUT)
gpio.write(pin,gpio.HIGH)
print(gpio.read(pin))
gpio.write(pin,gpio.LOW)

This script will turn on a LED on D1 and then turn off it.
If you should see lighting LED after executed gpio.write(pin, gpio.HIGH).

Now we try to build a blinking LED. Type this script.


-- blinking_led.lua
pin = 1
gpio.mode(pin,gpio.OUTPUT)
while 1 do
gpio.write(pin,gpio.HIGH)
tmr.delay(1000000)
gpio.write(pin,gpio.LOW)
tmr.delay(1000000)
end

You should see a blinking LED. If you want to stop, you can press RST button on
NodeMCU board.

2.5.3 Uploading Lua Script File to NodeMCU Board


In this section, I show you how to upload our Lua file to NodeMCU board and then
execute it. We can use luatool from https://github.com/4refr0nt/luatool . This program uses
Python to run the Lua file.
Please install Python on your platform. luatool needs pyserial library to access UART on
NodeMCU. You can install it via pip or easy_install
sudo easy_install -U pyserial

Remove sudo if youre working on Windows platform. Just run Command Prompt with
Administrator level.
Now you can download this tool using wget or download it directly on Github website.
$ wget https://raw.githubusercontent.com/4refr0nt/luatool/master/luatool/luato
$ wget https://raw.githubusercontent.com/4refr0nt/luatool/master/luatool/init.
$ wget https://raw.githubusercontent.com/4refr0nt/luatool/master/luatool/main.

If your installed Python is python, then change code on the top of script, from this script.
#!/usr/bin/env python2

to be the following script.


#!/usr/bin/env python

Save this code.


Now you can set access right on this file so you can execute it.
$ sudo chmod a+x luatool.py

For testing, I use blinking led from section 2.5.2. Save that script into a file, called
blinking_led.lua.
Type this command to upload to NodeMCU board.
$ ./luatool.py --port /dev/cu.SLAB_USBtoUART --src blinking_led.lua --dest bli

Change port parameter based on your attached NodeMCU board, for instance, COM5,
/dev/ttyAM0.
If done, this file will be available on NodeMCU.
To execute this file, connect to NodeMCU via serial tool and type this command.
> dofile("blinking_led.lua")
If you want to upload and execute Lua script file, you can add dofile parameter on your
command.
Type this command.
$ ./luatool.py --port /dev/cu.SLAB_USBtoUART --src blinking_led.lua --dest bli

This command will upload Lua file and then execute it.
If you modified codes and upload the file again, you must press RST to make sure
NodeMCU doesnt keep your file.
Sometimes you want your program run after NodeMCU restarts, you can write Lua file
with named main.lua. This file will be executed by NodeMCU. Warning!! if your main.lua
is error, you will get problem on NodeMCU.
3. Lua Programming Language

This chapter explains the basic of Lua programming language. If you already know about
Lua programming, you can skip this chapter.
3.1 Preparing Development Environment
To work with Lua development, we must install Lua compiler and its runtime. You can
download it on http://www.lua.org based your platform. For OS X user, you can install it
via brew.
$ brew install lua

After installed, you can execute Lua and run some Lua syntax.
$ lua
> print("Hello Lua")
> a = 5 + 8
> print(a)

If you want to quit from Lua shell, you can press CTRL+D keys.
3.2 Common Rule
You can write Lua script without ending ; at the end of syntax. Here is the syntax rule:
syntax_code1
syntax_code2
syntax_code3
3.3 Variables
In this section, we explore how to define a variable and assign its value.

3.3.1 Declaring Variable


To declare a variable called city, m, and n you can write the following script:
local city
local m, n

Once declared, these variables can be used to store any type data.

3.3.2 Assigning Variables


Variable that you already declare can be assigned by a value. It can done using the equals
sign (=). For example, variable city will assign a string value Berlin, you would write
this:
city = "Berlin"
m = 2
n = 5

We also can declare a variable and assign its value.

3.3.3 Demo
For illustration for declaring variables using Lua, create a file, called basic.lua.
Write the following script for basic.lua.
-- this a simple script for Lua
-- declare variables
local city
local m, n

-- assignment
city = "Berlin"
m = 2
n = 5

-- declare and assign variables


a = 6
str = "Hello world"
local p,q = 10, 12

print(city)
print(m)
print(n)
print(a)
print(str)
print(p)
print(q)

Save this file.


Then, try to build and run it.
$ lua basic.lua

A sample output can be seen in Figure below.


3.4 Comment
You may explain how to work on your code with writing comments. To do it, you can use
syntax. Here is sample code:
-- this a simple script for Lua
-- declare variables
local city
local m, n
3.5 Arithmetic Operations
Lua supports the same four basic arithmetic operations such as addition, subtraction,
multiplication, and division. For testing, create a folder arithdemo. Then, create a file,
called arithdemo.lua.
The following is the code illustration for basic arithmetic in arithdemo.lua:
-- basic arithmetic

a = 3
b = 2.4

c = a + b
d = a - b
e = a / b
f = a * b

print(c)
print(d)
print(e)
print(f)

Then, try to build and run it.


The following is a sample output.
3.6 Mathematical Functions
We try to work with math library. Create a file, called mathdemo.lua, and write this
script.
-- math demo

a = 2.5
b = 1.6

c = math.pow(a,2)
d = math.sin(a)
e = math.cos(b)
f = math.sqrt(a * b)
g = math.pi

print(c)
print(d)
print(e)
print(f)
print(g)

Then, try to build and run it.


The following is a sample output.
3.7 Increment and Decrement
We can write a script for increment and decrement using Lua.

increment a = a + 1
decrement. a = a - 1

Create a file, called incdec.lua and write this script.


-- increment and decrement

a = 4
print(a)

-- increment
a = a + 1
print(a)

-- decrement
a = a - 3
print(a)

Then, try to build and run it.


3.8 Comparison Operators
You may determine equality or difference among variables or values. Here is the list of
comparison operators:
== is equal to
~= is not equal
> is greater than
< is less than
>= is greater than or equal to
<= is less than or equal to

This is sample code for comparison usage.


-- comparison

a = 3
b = 10

print(a < b)
print(a > b)
print(a <= b)
print(a >= b)
print(a == b)
print(a ~= b)

Build and run it.


A sample output of the program can be seen in Figure below.
3.9 Logical Operators
These operators can be used to determine the logic between variables or values.
and and
or or
not not

Sample code:
-- logical operators

a = 3
b = 4

print(a<b and a>1)


print(a>b or a>4)
print(a<b and not (a>4))

Save this script into a file, called logical.lua. Build and run it.
A sample output of the program can be seen in Figure below.
3.10 Decision - if..then
Syntax model for if..then can be formulated as below:
if conditional then
-- do something
else
-- do something
end

conditional can be obtained by logical or/and comparison operations.


-- ifthen demo

a = 3

if a>1 then
print("a>1")
b = 3
print(b)
else
print("a<1")
b = 10
print(b)

end

Now you can run it.


A sample output of the program can be seen in Figure below.
3.11 Iteration - for
Iteration operation is useful when we do repetitive activities. The following is for syntax.
for initialization,end number,step do

end

For testing, write this script into a file, fordemo.lua.


for i=1,10,1 do
print(i)
end

Save this file and run it.


A sample output of the program can be seen in Figure below.
3.12 Iteration - while
Lua provides while syntax to do a looping.
Write this script for testing.
i = 1
while i < 10 do
print(i)
i = i + 1
end

Save this code into a file, called whiledemo.lua. Build and run it.
A sample output of the program can be seen in Figure below.
3.13 Iteration - repeat
Lua also provides repeat syntax to do looping. For a sample demo, type these scripts.
n = 5
repeat
print(n)
n = n + 1

until n > 12

Save these scripts into a file, called repeatdemo.lua.


Then, run this demo.
3.14 break and do
break can be used to stop on the code point. We can use do break end to stop our
looping.
Write these scripts for testing.
print("--break demo---")
n = 1
while n < 10 do
print(n)
n = n + 1
if n == 7 then
do break end
end
end

Save them into a file, called breakdo.lua and run it.


A sample output of the program can be seen in Figure below.
3.15 Array
Like other programming language, Lua provides array called Tables. We can define an
array using {}. To get a length of array, we can use #variable_name.
For testing, type these scripts.
cities = {"tokyo", "new york", "london", "berlin"}
numbers = {2, 4, 6, 8, 10,12}

print(cities)
print("length:",#cities)
print(cities[3])
print("length numbers:",#numbers)
print(numbers[5])

-- display all content of array


print("--display array")
for i=1, #cities do
print(cities[i])
end

Save them into a file, called array.lua.


Then, run it.
3.16 Functions
A function can be used to save your redundant activities. We can define a function using
(). It can attach parameters and return a value.
Lets write these scripts for testing.
function foo()
print("calling from foo()")
end

function add(a,b)
return a + b
end

print("---function demo---")
foo()
c = add(10, 5)
print(c)

Save into a file, called functiondemo.lua. Then, run it.


3.17 Lua Modules
A module may consists of functions. It can save your development time due to reusable
API. To build a module in Lua, we just create a Lua file and called it.
For illustration, create a file, called simplemodule.lua and write these scripts.
function add(a, b)
return a + b
end

function compute(a, b, c)
return a + b - c
end

Then, we call simplemodule.lua on our code. Create a file, called loadmodule.lua and
write these scripts.
require("simplemodule")

print("--load module--")
res = add(10, 4)
print(res)
c = compute(5, 6, 8)
print(c)

Save all files. Run our program on loadmodule.lua.


4. GPIO Programming

In this chapter Im going to explain how to work with GPIO on NodeMCU and write a
program.
4.1 Getting Started
In general, GPIO can be used to control digital I/O on NodeMCU. We can use gpio.read()
to read GPIO value and gpio.write() to write HIGH/LOW to GPIO pins. Firstly, we define
our GPIO mode using gpio.mode(). It can be either GPIO output or GPIO input. A list of
NodeMCU API can be read on this site, https://github.com/nodemcu/nodemcu-
firmware/wiki/nodemcu_api_en .

In this chapter, we build a program to illustrate how NodeMCU GPIO work. We need a
LED and a pushbutton.
Lets start!.
4.2 Wiring
Connect LED to D1 on Arduino and pushbutton to D2. The following is a sample of
wiring.
4.3 Writing a Program
To create a program, we just create a new Lua file, called gpiodemo.lua. Then, write these
scripts.
led = 1
pushbutton = 2
gpio.mode(led,gpio.OUTPUT)
gpio.mode(pushbutton,gpio.INPUT)
while 1 do
state = gpio.read(pushbutton)
if state==0 then
gpio.write(led,gpio.LOW)
else
gpio.write(led,gpio.HIGH)
end
print(state)
tmr.delay(1000000)
end

Save these scripts.


4.4 Testing
Now you can upload and run this program to NodeMCU board. For testing, try to press
pushbutton. You should see a lighting LED.

You also see the program output if you connect to NodeMCU board via Serial app.
5. PWM and Analog Input

This chapter explains how to work with NodeMCU Analog I/O.


5.1 Getting Started
NodeMCU board provides Analog I/O which can be connected to sensor or actuator
devices. See the following of NodeMCU GPIO.

In this chapter, we try to access NodeMCU Analog I/O using Lua program. There are two
scenarios for our cases:

Controlling RGB LED


Reading Analog input using Potentiometer

Lets start.
5.2 Demo Analog Output (PWM) : RGB LED
In this scenario we build a Lua program to control RGB LED color using NodeMCU
Analog output (PWM). RGB LED has 4 pins that you can see it on Figure below.

To understand these pins, you can see the following Figure.

Note:

Pin 1: Red
Pin 2: Common pin
Pin 3: Green
Pin 4: Blue

Now we can start to build a Lua application and hardware implementation.

5.2.1 Wiring
For our testing, we configure the following PWM pins.

RGB LED pin 1 (red) is connected to NodeMCU D1


RGB LED pin 2 is connected to NodeMCU 3V3 (VCC +3.3V)
RGB LED pin 3 (green) is connected to NodeMCU D2
RGB LED pin 4 (blue) is connected to NodeMCU D3

Here is a sample implementation with NodeMCU and RGB Led

5.2.2 Writing Program


To display a certain color, we must combine colors from red, green, blue. NodeMCU
provides API for PWM which can set a value from 0 to 1023 using pwm.setup(). Based on
NodeMCU Lua API, we only work with PWM maximum 3 PWM simultaneously.
Lets start to build a program. Firstly, create a file, called rgbdemo.lua. Then, write these
scripts.
red = 1
green = 2
blue = 3

function set_rgb(r, g, b)
print(r,g,b)
pwm.setup(red, 100, r)
pwm.setup(green, 100, g)
pwm.setup(blue, 100, b)

pwm.start(red)
pwm.start(green)
pwm.start(blue)

end
function stop_all_pwm()
pwm.stop(red)
pwm.stop(green)
pwm.stop(blue)
end

while 1 do
print("red")
set_rgb(0, 1023, 1023)
tmr.delay(1000000)
stop_all_pwm()
print("green")
set_rgb(1023, 0, 1023)
tmr.delay(1000000)
print("blue")
set_rgb(1023, 1023, 0)
tmr.delay(1000000)
print("yellow")
set_rgb(0, 0, 1023)
tmr.delay(1000000)
print("purple")
set_rgb(700, 1023, 700)
tmr.delay(1000000)
print("aqua")
set_rgb(1023, 0, 0)
tmr.delay(1000000)
end

This program will generate six colors: red, green, blue, yellow, purple, and aqua.
Save this file.

5.2.3 Testing
Upload and run the program. You should see several color on RGB LED.
The following is a sample demo on RGB LED.

If you connect to NodeMCU board via Serial app, you should get program output, shown
in Figure below.
5.3 Demo Analog Input: Working with Potentiometer
In this section, we learn how to read analog input on NodeMCU board. For illustration, I
use Potentiometer as analog input source. Our scenario is to read analog value from
Potentiometer. Then, display it on Lua shell.
NodeMCU v2 only has one ADC on A0. If you want to work with many analog input, you
must expand it using ICs based ADC. In this section, we are working on NodeMCU ADC
on A0.
Lets start!.

5.3.1 Wiring
To understand Potentiometer, you see its scheme in Figure below.

You can connect VCC to NodeMCU board on 3V3 pin (VCC +3.3V). Vout to NodeMCU
board Analog input A0. In addition, GND to NodeMCU board GND. The following is
hardware implementation. I use slide potentiometer.
5.3.2 Writing Program
Firstly, create a file, called adcdemo.lua. To read analog input, we can use adc.read()
function. Ok, Lets write these scripts.
print("ADC demo")
while 1 do
print("reading")
val = adc.read(0)
print("Analog: ",val)
tmr.delay(1000000)
end

Save this code.

5.3.3 Testing
Upload and run this program. If success, you can see analog value on Serial app.
6. Working with I2C

In this chapter we learn how to work with I2C on NodeMCU board using Lua script.
6.1 Getting Started
The I2C (Inter-Integrated Circuit) bus was designed by Philips in the early 80s to allow
easy communication between components which reside on the same circuit board. TWI
stands for Two Wire Interface and for most marts this bus is identical to IC. The name
TWI was introduced by Atmel and other companies to avoid conflicts with trademark
issues related to IC.
I2C bus consists of two wires, SDA (Serial Data Line) and SCL (Serial Clock Line).
NodeMCU v2 has I2C/TWI on SD0 (SDA), SD1 (SDA), SD2 (SDA), SD3 (SDA) and
CLK (SCL).

For testing, I used PCF8591 AD/DA Converter module with sensor and actuator devices.
You can find it on the following online store:

Amazon, http://www.amazon.com/PCF8591-Converter-Module-Digital-
Conversion/dp/B00BXX4UWC/
eBay, http://www.ebay.com
Dealextreme, http://www.dx.com/p/pcf8591-ad-da-analog-to-digital-digital-to-
analog-converter-module-w-dupont-cable-deep-blue-336384
Aliexpress, http://www.aliexpress.com/
In addition, you can find this device on your local electronics store/online store.

This module has mini form model too, for instance, you can find it on Amazon,
http://www.amazon.com/WaveShare-PCF8591T-Converter-Evaluation-
Development/dp/B00KM6X2OI/ .

This module use PCF8591 IC and you can read the datasheet on the following URLs.

http://www.electrodragon.com/w/images/e/ed/PCF8591.pdf
http://www.nxp.com/documents/data_sheet/PCF8591.pdf
I usually use this module to test I2C but NodeMCU v2 firmware doesnt support with I2C
address 0x90. Basically you can modify firmware code and then built it.
In this chapter, we build a program to access sensor via I2C using Lua script and use
Arduino as I2C slave. We can use any pin on NodeMCU GPIO for I2C using I2c library
from NodeMCU firmware.
6.2 Writing Program
We use Arduino Uno as I2C source. You can connect Arduino Uno to NodeMCU board
directly.
The following is our wiring lab:

Arduino Uno SDA (A4) > NodeMCU SDA (D1)


Arduino Uno SCL (A5) > NodeMCU CLK (D2)
Arduino Uno GND > NodeMCU GND

Hardware implementation can be shown in Figure below.


6.3 Writing Program
The first step is to write Arduino program. We can use Wire library to interact with I2C. In
this case, our Arduino acts as I2C slave and sends random byte.
Open Arduino IDE and write this code.
#include <Wire.h>

const byte SLAVE_ADDRESS = 0x15;


int led = 13;
byte x;

// source:
// http://forum.arduino.cc/index.php?topic=197633.0
byte randomDigit() {
unsigned long t = micros();
byte r = (t % 10) + 1;
for (byte i = 1; i <= 4; i++) {
t /= 10;
r *= ((t % 10) + 1);
r %= 11;
}
return (r - 1);
}

void sendData(){
byte data = randomDigit();
data = data + 30;
Wire.write(data);
Serial.println(data);
}

void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
Wire.begin(SLAVE_ADDRESS);
TWBR = 152; // 50 kHz speed
Wire.onRequest(sendData);
}

void loop() {
delay(500);
}
Save this code. Compile and upload this program to Arduino board.
Now you can start to write a Lua program for NodeMCU. Create a file, called i2cdemo.lua
and write these scripts.
id=0
sda=1
scl=2
ARDUINO_I2C = 0x15

i2c.setup(id,sda,scl,i2c.SLOW)

function read_data(id,dev_addr)
i2c.start(id)
i2c.address(id, dev_addr,i2c.RECEIVER)
c = i2c.read(id,1)
c = i2c.read(id,1)
i2c.stop(id)

return c
end

print("I2C demo")
while 1 do
val = read_data(id, ARDUINO_I2C)
print("RCV: ",string.byte(val))

tmr.delay(1000000)
end

Save this code.


6.4 Testing
Now you can upload and run the Lua program to NodeMCU board.
If success, open Serial app and connect to NodeMCU to see the program output from Lua
shell. The following is a sample output.

You also can see the Arduino output using Serial Monitor.
7. UART

In this chapter Im going to explain how to access UART on NodeMCU board.


7.1 Getting Started
NodeMCU v2 provides two UART but we only able to use one UART.

You can read Lua API to access NodeMCU UART


on https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en . The following
is Lua API for UART:

uart.setup() . To setup UART such as baud, databits, parity, stopbits, echo.


uart.on(). To listen incoming messages from UART
uart.write(). To write data into UART

In this chapter, I use Arduino board as UART source. We read incoming message from
UART.
Lets start!.
7.2 Wiring
In this scenario, I use Arduino Uno which is connected to NodeMCU board. The
following is our wiring.

NodeMCU D10 (TXD0) is connected to Arduino Digital 10


NodeMCU D9 (RCD0) is connected to Arduino Digital 11
NodeMCU GND is connected to Arduino GND

My wiring implementation can be seen in Figure below.


7.3 Writing a Program
Firstly, we write a program for Arduino using Arduino IDE. We use SoftwareSerial to
access Serial on Digital 10 and 11. This program will wait incoming UART data and then
send to Arduino UART on 0 and 1 pins.
Write this program.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
}

void loop()
{
if (mySerial.available() > 0) {
Serial.write(mySerial.read());
}
}
Save this program. Then, upload it to Arduino board. Before uploading, please make sure
Arduino UART (digital 0, 1, 10, and 11 pins) doesnt connect to any board.
The next step is to write a program for NodeMCU board. Create a file, called
uartdemo.lua. Write these scripts.
uart.setup(0, 9600, 8, 0, 1, 0)
val = 65
-- looping
while 1 do
uart.write(0,string.char(val),"\r\n")
val = val + 1
if val>90 then
val = 65
end
tmr.delay(1000000)
end

Save this file.


7.4 Testing
Now you can upload and run Lua program. Dont connect NodeMCU UART to Arduino
while uploading a program. If done, connect NodeMCU UART to Arduino UART (Digital
pins: 10 and 11).
To see the UART output, open Serial Monitor tool from Arduino IDE. Set baud 9600 and
No line ending. You should see the UART output.
8. SPI

In this chapter Im going to explain how to work with SPI on NodeMCU board.
8.1 Getting Started
The Serial Peripheral Interface (SPI) is a communication bus that is used to interface one
or more slave peripheral integrated circuits (ICs) to a single master SPI device; usually a
microcontroller or microprocessor of some sort.
SPI in NodeMCU board can be defined on the following pins:

MOSI
MISO
SCK

You can see these pins on S NodeMCU board, shown in Figure below.

We can only use one SPI on NodeMCU board with SPI master mode. If were working on
SPI, we cant access UART on the board. In this chapter, I use Arduino board as SPI slave.
Lets start!.
8.2 Wiring
To work both SPI and UART/USB, we dont connect MISO pin. For testing, I use Arduino
board. Do wiring as follows.

NodeMCU MOSI (SD1) pin is connected to Arduino MOSI (Digital 11) pin
NodeMCU SCLK (CLK) pin is connected to Arduino SCK (Digital 13) pin
NodeMCU GND pin is connected to Arduino GND pin
NodeMCU CS (CMD) pin is connected to Arduino SS (Digital 10) pin

The following is a sample of wiring.


8.3 Writing a Program
Firstly, we write a program for Arduino. Write these codes on Arduino IDE.
#include <SPI.h>

char buf;
volatile byte pos;
volatile boolean isAvailable;

void setup() {
Serial.begin (9600); // for debugging
// SPI slave mode
SPCR |= bit (SPE);
SPCR |= _BV(SPIE);
isAvailable = false;
pos = 0;
pinMode(MISO, OUTPUT);
SPI.attachInterrupt();

}
ISR (SPI_STC_vect)
{
byte c = SPDR;
if(c>64 && c<91){
buf = c;
isAvailable = true;
}

}

void loop() {
if(isAvailable){
Serial.println (buf);
isAvailable = false;
}
}

This program does wait incoming data from SPI master and then display the received data
to Arduino Serial so we can see it on Serial Monitor.
Save this program as Arduino_spi. Build and upload the program to Arduino board.
The next step is to write a program for NodeMCU. Create a file, called spidemo.lua, and
write these scripts.
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
val = 65
while 1 do
spi.send(1,string.char(val))
print(string.char(val))
val = val + 1
if val>90 then
val = 65
end
tmr.delay(1000000)
end

This program will send data ASCII from 65 to 90.


Save this code.
8.4 Testing
Now you can upload Lua program to NodeMCU board. If done, open Serial Monitor tool
from Arduino. You should see received data from SPI.

If you connect to NodeMCU board via Serial tool, you should see the program output too.
9. Working with OLED Display

In this chapter Im going to explain how to work with OLED display


9.1 Getting Started
We can display characters, numbers or symbols using an OLED graphic display module.
An organic light-emitting diode (OLED) is a light-emitting diode (LED) in which the
emissive electroluminescent layer is a film of organic compound which emits light in
response to an electric current [source: http://en.wikipedia.org/wiki/OLED].
In this chapter, we work with OLED display 128x64 with I2C interface which display
characters.

Lets start!.
9.2 Wiring
The following is our wiring:

NodeMCU SDA (D1) to OLED SDA


NodeMCU SCL (D2) to OLED SCL
NodeMCU VCC +3.3V to OLED VCC
NodeMCU GND to OLED GND

The following is a sample of wiring.


9.3 Writing a Program
For testing, we use a sample program from https://github.com/nodemcu/nodemcu-
firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua . With activating OLED
with I2C interface.
Create a file, called oleddemo.lua, and write this code.
function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs
local sda = 1 -- GPIO05 (D1)
local scl = 2 -- GPIO04 (D2)
local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
end

-- graphic test components


function prepare()
disp:setFont(u8g.font_6x10)
disp:setFontRefHeightExtendedText()
disp:setDefaultForegroundColor()
disp:setFontPosTop()
end

function box_frame(a)
disp:drawStr(0, 0, "drawBox")
disp:drawBox(5, 10, 20, 10)
disp:drawBox(10+a, 15, 30, 7)
disp:drawStr(0, 30, "drawFrame")
disp:drawFrame(5, 10+30, 20, 10)
disp:drawFrame(10+a, 15+30, 30, 7)
end

function disc_circle(a)
disp:drawStr(0, 0, "drawDisc")
disp:drawDisc(10, 18, 9)
disp:drawDisc(24+a, 16, 7)
disp:drawStr(0, 30, "drawCircle")
disp:drawCircle(10, 18+30, 9)
disp:drawCircle(24+a, 16+30, 7)
end

function r_frame(a)
disp:drawStr(0, 0, "drawRFrame/Box")
disp:drawRFrame(5, 10, 40, 30, a+1)
disp:drawRBox(50, 10, 25, 40, a+1)
end

function stringtest(a)
disp:drawStr(30+a, 31, " 0")
disp:drawStr90(30, 31+a, " 90")
disp:drawStr180(30-a, 31, " 180")
disp:drawStr270(30, 31-a, " 270")
end

function line(a)
disp:drawStr(0, 0, "drawLine")
disp:drawLine(7+a, 10, 40, 55)
disp:drawLine(7+a*2, 10, 60, 55)
disp:drawLine(7+a*3, 10, 80, 55)
disp:drawLine(7+a*4, 10, 100, 55)
end

function triangle(a)
local offset = a
disp:drawStr(0, 0, "drawTriangle")
disp:drawTriangle(14,7, 45,30, 10,40)
disp:drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,
disp:drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53)
disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,
end

function ascii_1()
local x, y, s
disp:drawStr(0, 0, "ASCII page 1")
for y = 0, 5, 1 do
for x = 0, 15, 1 do
s = y*16 + x + 32
disp:drawStr(x*7, y*10+10, string.char(s))
end
end
end

function extra_page(a)
disp:drawStr(0, 12, "setScale2x2")
disp:setScale2x2()
disp:drawStr(0, 6+a, "setScale2x2")
disp:undoScale()
end

-- the draw() routine


function draw(draw_state)
local component = bit.rshift(draw_state, 3)

prepare()

if (component == 0) then
box_frame(bit.band(draw_state, 7))
elseif (component == 1) then
disc_circle(bit.band(draw_state, 7))
elseif (component == 2) then
r_frame(bit.band(draw_state, 7))
elseif (component == 3) then
stringtest(bit.band(draw_state, 7))
elseif (component == 4) then
line(bit.band(draw_state, 7))
elseif (component == 5) then
triangle(bit.band(draw_state, 7))
elseif (component == 6) then
ascii_1()
elseif (component == 7) then
extra_page(bit.band(draw_state, 7))
end
end

function graphics_test(delay)
print("--- Starting Graphics Test ---")

-- cycle through all components


local draw_state
for draw_state = 0, 7 + 8*8, 1 do
disp:firstPage()
repeat
draw(draw_state)
until disp:nextPage() == false
--print(node.heap())
tmr.delay(delay)
-- re-trigger Watchdog!
tmr.wdclr()
end

print("--- Graphics Test done ---")


end

init_i2c_display()
graphics_test(50000)

Save this code.


9.4 Testing
Now you can compile and run this program into NodeMCU board. You should see OLED
displays some characters, symbols and graphics.
10. Connecting to a Network

In this chapter Im going to explain how to connect a network from NodeMCU.


10.1 Connecting to a WiFi Hotspot
We can wifi object to work with WiFi module on NodeMCU. For instance, we connect a
SSID with a pin password.
Write this code.
-- connect a WIFI network

wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")
print("connecting")
wifi.sta.connect()
ip = wifi.sta.getip()
print("IP: ",ip)

Change SSID and password values. Save this code into a file called network.lua.
Upload this program. Then, run it via Serial program so you can see NodeMCUs IP
Address.
10.2 Building a Simple Web Server
The second demo is to build a simple web server. Write this code.
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")
print("connecting")
wifi.sta.connect()
ip = wifi.sta.getip()
print("IP: ",ip)

srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on("receive",function(conn,payload)
print(payload)
conn:send("HTTP/1.1 200/OK\r\nServer: NodeMCU\r\nContent-Type: text/html
conn:send("<html><head><title>NodeMCU</title></head><body><p>Hello, NodeMc
end)
conn:on("sent",function(conn) conn:close() end)
end)

Change SSID and password values. Save this code into a file called webserver.lua.
Upload this program. Then, run it via Serial program so you can see NodeMCUs IP
Address.
Open a browser and navigate to IP address of NodeMCU.

The following is the program output on Serial app.


Source Code

You can download source code on


http://www.aguskurniawan.net/book/nodemcu_11301082015.zip .
Contact

If you have question related to this book, please contact me at aguskur@hotmail.com . My


blog: http://blog.aguskurniawan.net