This guide goes over basic input and output using the GPIO pins on the ESP8266 NodeMCU.


Prerequisite Guides


Supplemental Guides


You Will Need

  • ESP8266 NodeMCU
  • MicroUSB Cable
  • Computer running Windows, Linux, or MacOSX
  • Breadboard
  • LED
  • 1kΩ - 10kΩ resistor
  • 46Ω - 100Ω resistor
  • 6mm push button
  • 22 AWG solid core hook up wire or jumper wires


Setup

If you do not have a NodeMCU flashed with MicroPython, or do not know how to upload programs to the NodeMCU. I recommend reading our Hello MicroPython guide before continuing further with this guide.


NodeMCU or ESP8266?

At this point you may have heard us refer to the microcontroller as an “ESP8266” or a “NodeMCU”, or even a “ESP8266 NodeMCU”. So which is it? Below is an image of a NodeMCU development board next to a ESP8266 microcontroller by itself.

Left: NodeMCU development board. Right: ESP8266 microcontroller on its own.
Left: NodeMCU development board. Right: ESP8266 microcontroller on its own.

The NodeMCU is a development board built around the ESP8266 microcontroller. Along with the ESP8266 it has a CP2102 USB to UART chip connected to a micoUSB port. It also has a regulator to lower the input voltage from 5V to 3.3V. This allows for the microcontroller to be safely powered and programmed through USB.


NodeMCU Pinmap

The image below is an important quick reference to have when working with a NodeMCU development board. For now the only thing you need to pay attention to is the pins that are labeled GPIOX, with X being an integer. With some exceptions, these pins are generally available for use. When referencing GPIO pins in MicroPython code the GPIO number is always how to indicate a pin. Disregard the text written on the development board that says “DX”.

Quick reference for pin identifiers and functions.[1]
Quick reference for pin identifiers and functions.

We will get into more detail in future guides about what the other abbreviations in the diagram mean.


Blinking a LED

Carefully plug your NodeMCU into the breadboard. Line it up with the holes such that there is a single row of holes on both sides of the board. Then, push the NodeMCU straight down into the breadboard until you can no longer see the metal pins.

Center the NodeMCU in the breadboard as seen here.
Center the NodeMCU in the breadboard as seen here.

There are several pins on the NodeMCU labeled “GND” connect one of these pins to a nearby rail on the outside edge of the breadboard using a jumper wire. This rail is now your ground rail.

Create a ground rail by connecting GND to a nearby breadboard rail.
Create a ground rail by connecting GND to a nearby breadboard rail.

Plug the long end of your LED into the pin labeled as “D1” (GPIO5) and the short end of the LED to an empty breadboard row. Next, take a resistor in the range of 46Ω - 100Ω and connect the row containing the short end of the LED to the ground rail on your breadboard.

Complete the circuit by adding the LED and resistor as shown.
Complete the circuit by adding the LED and resistor as shown.

Plug in the NodeMCU to your computer using a microUSB cable. Launch Thonny, make sure the interpreter and port is set, and press the stop button until you have a REPL available in the shell tab. Enter the following code into the editor and save to “Micropython Device” as “main.py”. After saving, press the small button labeled “RST” on your NodeMCU. This will reset the NodeMCU and run main.py. Your LED should blink ten times.

from machine import Pin
from time import sleep

led = Pin(5, Pin.OUT)

for _ in range(10):
    led.value(1)
    sleep(1)
    led.value(0)
    sleep(1)


Reading Button Input

Before moving on in this section, make sure that the microUSB cable is unplugged from the NodeMCU. It is good practice to power down your projects when modifying them. Leave everything currently on the breadboard where it is, we will return to it in the next section.


6mm Push Button Background

There are four leads on a pushbutton of this type, but there are only two nodes. Each node contains two leads. The image below indicates how the leads are paired. When the push button is pressed, the two nodes connect which may complete a circuit.

When the pushbutton is pressed, the two nodes that make up the button are connected, allowing current to travel.
When the pushbutton is pressed, the two nodes that make up the button are connected, allowing current to travel.


Connecting the Button

Place your button so that it is near the end of your breadboard and bridges the gap between the two halves. Also, place connect a wire from any of the pins labeled “3V3” on the NodeMCU to the other rail next to the ground rail. This rail will now be powered with 3.3V.

6mm push buttons fit perfectly across the gap in the center of the breadboard.
6mm push buttons fit perfectly across the gap in the center of the breadboard.

Connect one side of the button to “D2” (GPIO4) and the other side of the button to the ground rail. These connections allow for the pin to be set for 3.3V when the button is pressed, otherwise it will be 0 volts…right?

When the pushbutton is pressed, the two nodes that make up the button are connected, allowing current to travel.
When the pushbutton is pressed, the two nodes that make up the button are connected, allowing current to travel.

Plug in the NodeMCU and acquire a REPL in the shell tab. Then edit and save a main.py file to the NodeMCU (overwriting the previous one) that resembles the code below. After it is saved, press the “RST” button on the NodeMCU to run your new program.

from machine import Pin
from time import sleep_ms

button = Pin(4, Pin.IN)

while(True):
    print(button.value())
    sleep_ms(100)

You will see that this program continuously prints the value of the button pin (GPIO4) to the REPL. This is resembled as either a “1” or a “0” with a “1” indicating that the pin is high (3.3V), and a “0” indicating the pin is low (OV or ground).

Try pressing the button. You will notice that the output is not what is expected. This is because the circuit is missing a critical component called a “pull-up resistor”. This will be added next.


External Pull-Up Resistor

The circuit before did not give the desired output because D2 (GPIO4) is never set directly to 3.3V when the button is not pressed. A pin in this state is referred to as “floating” because it is floating somewhere between 0V and 3.3V. To fix this, a high value resistor can be used to connect the pin directly to 3.3V.

Unplug your NodeMCU. Then, use a resistor in the range of 1kΩ - 10kΩ to connect the side of the button that is connected to D2 to the 3.3V rail as shown in the image below.

The pull-up resistor sets the pin to 3.3V when the button is not pressed.
The pull-up resistor sets the pin to 3.3V when the button is not pressed.

Plug in your NodeMCU again and acquire a REPL. Press the RST button to run the same program on the NodeMCU as before. Observe the REPL. You should now see that that the REPL is continuously outputting 1’s. While the button is pressed the output will change to 0’s.


Internal Pull-Up Resistor

There is another way to implement a pull-up resistor. ESP8266 microcontroller contains pull-up resistors that can be enabled through your program.

Remove the pull-up resistor that you just added from your breadboard. Then, edit your main.py to resemble the code below.

from machine import Pin
from time import sleep_ms

button = Pin(4, Pin.IN, Pin.PULL_UP)

while(True):
    print(button.value())

You should see that your program displays the same output and behavior as with the external pull-up resistor.


Putting it All Together

Now take everything you have learned in this section and write and upload a program to your NodeMCU that turns on the LED whenever the push button is pressed. Do not change the components on the breadboard while you do this. Good luck!


Click here to view a solution.
from machine import Pin
from time import sleep_ms

led = Pin(5, Pin.OUT)
button = Pin(4, Pin.IN, Pin.PULL_UP)

while(True):
    if not button.value():
        led.value(1)
    else:
        led.value(0)


Now that you have completed this guide, you should be familiar with the basics of programming a ESP8266 NodeMCU with MicroPython. I encourage you to try experimenting with writing your own programs.


Next guide: Timers and Interrupts with a NodeMCU and MicroPython


1 “ESP8266 NodeMcu Pinout.” ESP8266 Shop, esp8266-shop.com/esp8266-guide/esp8266-nodemcu-pinout/. Link