/ Follow the trail


Like all programming languages the first program you typically write is “Hello, World!” which illustrates the basic syntax of the language. In the world of IoT a similar phenomenon exists: “Blink!” Blink! is a basic set of instructions which toggles a LED light on or off. This post outlines the steps to toggle an LED using Lua on NodeMCU. [1]

This post assumes that you have a ESP8266 is flashed with the latest NodeMCU firmware. I have written an extensive post on that topic here.

"Lua" (pronounced LOO-ah) means "Moon" in Portuguese. As such, it is neither an acronym nor an abbreviation, but a noun. More specifically, "Lua" is a name, the name of the Earth's moon and the name of the language. Like most names, it should be written in lower case with an initial capital, that is, "Lua". Please do not write it as "LUA", which is both ugly and confusing, because then it becomes an acronym with different meanings for different people. So, please, write "Lua" right! -- Lua.org

Breadboard Wiring

With the NodeMCU all ready to go first step we must connect a LED. I've opted for a RGB controllable LED; three of the 4 legs control Red, Green and Blue while the fourth and longest is the common anode. The common anode RGB is connected to a 3V3 pin. In case of a common cathode RGB LED connect the leg to a GND pin instead.

Linking the RGB legs to ESP8266 requires a mapping between the NodeMCU IO index to the corresponding the GPIO pin(s). This index is used as the argument to the NodeMCU/Lua function for reading a GPIO pin. For the Blink! demo the RGB legs have been mapped in the following order:

R: ESP8266 Pin GPIO5 - IO Index 1
G: ESP8266 Pin GPIO4 - IO Index 2
B: ESP8266 Pin GPIO14 - IO Index 5


In order to show the basics of the Lua programming language I have created two separate scripts: init.lua and blink.lua to visualize how Lua calls different modules. I am not pretending to be a Lua development expert, so any comments regarding code improvements are most welcome.


NodeMCU uses init.lua as the auto executable which is invoked upon boot-up. In this example I have the Blink! code stored in a separate file which is called during the processing of init.lua to visualize the modular structure of Lua.

init.lua | Tiest van Gool

Init.lua is automatically executed on bootup of the NodeMCU. This launcher file loads the actual init_XYZ file only when everything has been tested and debugged. 
A 15 second delay has been added in case of error and enable abort.

-- Set local variable

-- Set timer to abort initialization of actual program
print("You have 15 second to enter file.remove('init.lua') to abort")
tmr.alarm(0, 15000, 0, function()
  print("Executing: ".. FileToExecute)


Small script which toggles the Red LED on and off in a 1 second interval.

blink.lua | Tiest van Gool

Little program which toggles a LED on and off in a 3 second interval.

-- Local Variables
local pin = 1
local value = gpio.LOW
local duration = 3000

-- Routine toggles LED state
function toggleLED ()
  if value == gpio.LOW then
     value = gpio.HIGH
     value = gpio.LOW
  gpio.write(pin, value)

-- Initialise the GPIO pin
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, value)

-- Create an interval
tmr.alarm(0, duration, 1, toggleLED)

Serial Comms with ESP

In order to communicate with the ESP9266 unit we need a serial communication program. My favorite is PuttY - a simple menu driven serial communication program. Next steps install the programs and establish connectivity with NodeMCU.

Install and Setup PuTTY

In order to interact with the NodeMCU we need an program which can interact with the serial port. I prefer the open source program PuTTY or Minicom.

sudo apt-get install putty
sudo putty

In the session tab select serial port, enter serial port and baud rate. Please have a look at this post on how to determine the correct serial port in Linux. End result should look something like the screenshot below.

Press 'Open' and an empty black terminal screen should open. To check connectivity we can run the command: print ("Hello World!"). If you are unable to enter any commands, hit enter a couple of times to have the command prompt come up. If all went as planned you should see Hello World! in the terminal window. Congratulations!

Next we should prepare the NodeMCU board by resetting and formatting the file system to write and save our Lua scripts.

Reset NodeMCU

Press the 'RST' button on the NodeMCU board or type node.restart() in the PuTTY interpreter window.

You should now get a bit of gibberish (communication at a different baudrate), a welcome message and a '>' prompt similar as below. This is the NodeMCU's Lua interpreter. The init.lua error is no surprise as this is a clean install and no script is available on the device.

Format file system

To write and save Lua scripts the file-system must be formatted: file.format()


Luatool is an open source tool that can upload Lua scripts from your computer to the NodeMCU Devkit and store them in the ESP8266 flash memory.
Note: ensure that you close PuTTY as it prevents the serial communications port from being used by the Luatool.

Clone Luatool

cd ~/opt
git clone https://github.com/4refr0nt/luatool.git
cd luatool

Upload Lua scripts

cd ~/opt/luatool/luatool/
python luatool.py --port /dev/ttyUSB4 --src blink.lua --dest blink.lua
python luatool.py --port /dev/ttyUSB4 --src init.lua --dest init.lua --restart

If all the steps described in this blow were executed properly you LED should be blinking on the bread board in the color as indicated by the pin in the blink.lua script. Welcome to the world of IoT!

Next post will introduce the usage of the ESP8266 build-in WiFi capabilities. Stay tuned!

  1. Republished from my original blog post created on January 2016. ↩︎

If you use Disqus comments, just uncomment this block. The only thing you need to change is "test-apkdzgmqhj" - which should be replaced with your own Disqus site-id.