MicroPython and the NodeMCU ESP8266

In a previous post, I looked briefly at MicroPython and it’s place and role in the Internet of Things (IoT) arena. In this post, I’d like to walk through the process of getting a NodeMCU ESP8266 device flashed and up and running with MicroPython. Then we’ll do the, almost required, IoT version of “Hello World”… a blinking LED light.

There are multiple micro-controller options available for using MicroPython so why, you may ask, have I decided on the NodeMCU? First and foremost they are inexpensive. You can find the NodeMCU ESP8266 development boards on eBay for under $5.00. Granted that is from a factory overseas, but for under $10.00 you can get one on Amazon. The second reason I like this board, in particular, is that it has LED lights built into the board so I don’t necessarily need to break out LED bulbs and resistors. Another big plus is that it is WiFi ready and with MicroPython that means that one can set up a web interface with the board and also readily make truly connected projects without additional hardware.

All that said and done I’ll be using a basic NodeMCU ESP8266 device for this tutorial. Feel free to use a different physical device with the same chip, just know that some settings may be different based on the physical device configuration. The board has a USB interface which, when connected to a PC provides power.


We obviously need to get a copy of the MicroPython firmware. It comes in a .bin file format that can be loaded directly to the ESP8266 device and can be downloaded from the MicroPython site here. For this tutorial, I will be using the esp8266-20170108-v1.8.7.bin version of firmware. You will want to download that to your computer and remember where it is saved.

Now we need to deploy the firmware to our device. If you are using the above-mentioned board, deploying the firmware should be relatively straight forward. If you are using a different ESP8266 board, check with the manufacturer of your board for the proper flashing technique. For the rest of us, we will want to start with the esptool and use it to move the firmware over to our device. The tool can either be downloaded from GitHub directly or can be installed using pip with:

python -m pip install esptool

This version of esptool supports Python version 3.4 or newer.

Serial Ports

Once we have that installed on our system and the device connected via the USB port, we should, for best practice, clear the device by erasing its current state. Assuming that the port name of the device is COM4, we can accomplish that with the following command:

esptool.py --port COM4 erase_flash

Just substitute COM4 for whichever communication port your particular device is using. It may be something similar to /dev/ttyUSB1 on a non Windows machine and from a terminal port, you can use the command ls /dev/tty.* to detect the port. Also, depending on your ESP8266 device you might need to install the USB to UART Bridge VCP Drivers the be able to detect the device via a serial connection. Once the device has been flashed (it takes less than 10 seconds on my machine) we upload the firmware to the device with the following command:

esptool.py --port COM4 --baud 460800 write_flash --flash_size=detect 0 esp8266-20170108-v1.8.7.bin

The filename of the firmware should match the downloaded firmware. Assuming you don’t get any errors during the flashing process, you now have a NodeMCU ESP8266 device running MicroPython. Pretty slick, eh?

Serial Terminal

We can now connect to the device using a serial terminal tool, like PuTTY for Windows, the screen program on Mac, or something like picocom for Linux. I’ll be using PuTTY since I’m currently on a Windows 10 machine.

We’ll want to select our serial port again, in my case it is COM4 and set the speed, or baud rate, to 115200. Then we can open the connection and we should be prompted with a Python read-evaluate-print-loop (REPL) interface as shown:

We can start entering in Python commands on the device itself. Let’s have our device do the IoT version of “Hello World” and turn on one of the on-board LED lights. These lights are controlled through General-Purpose Input/Output (GPIO) pins and there are two of them on board. GPIO 2 controls a small blue LED on the board.

In the REPL then, we want to be able to turn the light on and off. That can be done by altering the state (electrical charge) provided to the GPIO pins, typically by changing the state from low to high and back to low.

Here is something that I discovered when working with this particular LED and GPIO setting and board. On this board, the LED on GPIO 2 (and 16 for that matter) is wired between the pin and the power, so when we set the pin state to low, the light is activated, and when set to high, it is off. There is active development on this issue and firmware updates may have already addressed the issue. However, if one connects an external LED light to, say GPIO 5 along with the required resistor (~300+ ohms), we get the expected light on with a high state, and off with a low state.

MicroPython code – Try it Out!

Okay, so technical issues aside, let’s look at the code necessary to turn on our LED. First, we’ll need access to the board’s hardware. We can import a package called machine which provides the necessary software interface. Then we can change the state of a given GPIO pin…

>>> import machine
>>> pin = machine.Pin(2, machine.Pin.OUT)
>>> pin.high()  # light off
>>> pin.low()  # light on
>>> pin.high() # light off again

There we have it! We have taken a NodeMCU 8266 device, flashed it with MicroPython, accessed it through the serial port, and with minimal code, turned the on-board LED lights on and off.

Congratulations on your first venture into IoT and Python! There is a lot more that can be done with this $5.00 board and I think I will spend some time experimenting with it a bit. I’ll post my results and findings here as I work through the process.

Follow me on Twitter @kenwalger to get the latest updates on my postings.


An Overview of MicroPython

There are a lot of options available when one starts exploring the exciting field of the Internet of Things, or IoT. Not only are there many choices of micro-controllers, there are also a variety of languages in which to program these devices. Many times the micro-controllers are sold as being dependent on C or C++ as a language. That’s great, but I don’t know either of those. There is some great and amazing working being led by Andrew Chalkley around using the JavaScript language for micro-controllers over at thingsSDK. If JavaScript is your language, I’d highly recommend checking out their work. There are also lots of resources for using Java for IoT, Nathan Tippy, for example, is an excellent resource.

All those are great languages. What if you are a beginning developer just interested in playing around in IoT? Or what if you are a Pythonista and don’t want to pick up another programming language? Well, for many micro-controllers there is a Python option which is, arguably easier to learn in many ways than Java, JavaScript, C or C++. That option being MicroPython. You can see that project’s website here.

Overview of MicroPython

MicroPython is a tiny, open source Python programming language interpreter that runs on embedded boards. It was originally developed in 2013 and released in 2014 by Dr. Damian P. George of Cambridge University. It implements Python 3 and is designed specifically to run on devices with limited resources.

As with many things in the IoT world, the use of a particular language is greatly influenced by the tools, libraries, and packages one has available. MicroPython comes with an interactive read-evaluate-print-loop (REPL) for quick prototyping. It also fully supports loading MicroPython scripts onto a device to run as well. It supports an extensive Python based library and for lower level operations can be extended with C/C++ functions as needed.

Many of the tasks that beginning IoT folks start off with, such as blinking lights, reading switches, driving servos, etc. are all easy to do in MicroPython. Further, it is often incredibly easy to read as well, as it is all Python based. For example, if one has MicroPython installed on a NodeMCU ESP8266 board, a popular and inexpensive board to start working in IoT, with a basic LED light connected to GPIO Pin 5 it is pretty simple to get the light to turn on (high state) and off (low state).

import machine

led = machine.Pin(5, machine.Pin.OUT)
# Turn on LED
# Turn off LED

The machine module is included with MicroPython and handles many of the hardware connections from software.  It allows access to things like GPIO pins, CPU frequency, I2C busses, etc. If it is low-level on the hardware, the machine module is the way to go!

Platform Support

There are many devices that support MicroPython. The NodeMCU is one of them. But several other options are available such as the LoPy or similar PyCom devices, the PyBoard, and many others.

Differences from Python 3

As one can imagine, cramming everything from Python 3 into a micro-controller isn’t possible. But, core data types and modules which make sense for embedded systems are included. Another limitation is that since Python is a high-level programming language it isn’t as fast or lean as C or C++. Many operations aren’t impacted by this. However, if your application requires tight timing or performance is of utmost importance, using MicroPython can be an issue. However, as stated earlier, one can extend MicroPython to use C/C++ in these circumstances.

Since MicroPython is open source, check it out on GitHub, one can further extend or adapt it specific use case scenarios. For example, if you need something specific to run at boot time you can include it in the package that is flashed to the device. Pretty handy and convenient.


Hopefully I have at least sparked your interest enough in using MicroPython for IoT to take a further look at it. The development site actually has a live, interactive device where you can try out some code and see it run on a real world device. Give it a try and leave a comment below to share with others what you’ve done and built!

Follow me on Twitter @kenwalger to get the latest updates on my postings.