Introduction to Networking and ntptime with a NodeMCU and MicroPython

Carlo Supina

March 31, 2020

0 Comment

Prerequisite Guides


Supplemental Guides


You Will Need

ESP8266 NodeMCU
MicroUSB Cable
Computer running Windows, Linux, or MacOSX

Setup

For this guide all you need to do is connect the NodeMCU to your computer with a microUSB cable.

The breadboard is not required for this guide.

The breadboard is not required for this guide.


Connect to Wifi

In this section will go over how to connect your ESP8266 NodeMCU to a wifi network.


WLAN and Station Mode

The first thing we need to do is initialize a WLAN (wireless local area network) object. This object is what will allow us to easily perform networking actions. To create this object we need to specify one parameter, the interface. There are two available options for the interface parameter explained below:

  • Station STA_IF: This interface mode means that the ESP8266 will try to connect to a wireless router just like you would on your phone, laptop, desktop computer, etc.
  • Access Point AP_IF: This interface mode means that the ESP8266 is the wireless router and other devices can connect to it just like you may connect them to a wifi network in your home.

In this guide we are accessing data over the internet, so we will need to connect our ESP8266 to a wifi router. This means that we need to create our WLAN object using the STA_IF interface.

If you haven't already, connect your NodeMCU to your computer. Then, open Thonny and acquire a REPL. One at a time, enter the following three lines of code into the REPL to create the WLAN object and activate it.

import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

Scan Networks and Connect

To see what networks are available WLAN.scan() can be called to get a list of tuples containing information on the scanned networks. Enter the following line of code into the REPL to see what networks your ESP8266 is detecting.

wlan.scan()

This function takes a few seconds to run, but after it finishes you will get a list of tuples containing network information with elements in the following order:

(ssid, bssid, channel, RSSI, authmode, hidden)

In this guide we only care about the first parameter, the ssid. This is the name name of the wifi network.

You can connect to the network by using the WLAN.connect function. This function requires two parameters, the name of the network (or ssid) and the password for the network. Below is an example of this function call to connect to a network called "ssid" with password "password".

wlan.connect("ssid", "password")

This function does not provide feedback as to whether it worked or not. To check if your ESP8266 is connected to a wifi network, the WLAN.isconnected function can be called as shown below.

wlan.isconnected()

If this function returns True then your ESP8266 is connected to the internet!

Below is a function called connect_to_wifi that you can put in your code to do all of the steps of connecting to a wifi network at once.

def connect_to_wifi(wlan, ssid, password):
    if not wlan.isconnected():
        print("Connecting to network...")
        wlan.connect(ssid, password)
        while not wlan.isconnected():
            pass

Setting the RTC time with ntptime

Now that we have connected to the internet, let's set the RTC on the ESP8266 to the current time through the use of the ntptime module which uses a time server.

To start off let's put what we have done so far into a main.py file in Thonny. Enter the following code into the Thonny editor.

import network

def connect_to_wifi(wlan, ssid, password):
    if not wlan.isconnected():
        print("Connecting to network...")
        wlan.connect(ssid, password)
        while not wlan.isconnected():
            pass

wlan = network.WLAN(network.STA_IF)
wlan.active(True)

connect_to_wifi(wlan, "ssid", "password") # make sure to replace "ssid" and "password"!

To use ntptime to set the RTC on the NodeMCU, we need to import the ntptime and RTC modules. After they are imported an RTC must be initialized. Then, ntptime can be called to set the the NodeMCU's RTC to the same time as the time server. Change the contents of the Thonny editor to the code below (added lines are marked with comments). Then save the script to your NodeMCU as "main.py".

import network, ntptime # changed to also import ntptime
from machine import RTC # import RTC from machine

def connect_to_wifi(wlan, ssid, password):
    if not wlan.isconnected():
        print("Connecting to network...")
        wlan.connect(ssid, password)
        while not wlan.isconnected():
            pass

wlan = network.WLAN(network.STA_IF)
wlan.active(True)

connect_to_wifi(wlan, "ssid", "password")

rtc = RTC() # initialize the RTC
ntptime.settime() # set the RTC's time using ntptime
print(rtc.datetime()) # print the current time from the RTC

Press the "RST" button on the NodeMCU to run your code. You should see that this successfully sets the RTC to a time, but not necessarily the right time for your location. This is due to the ntptime.settime function setting the RTC to UTC (coordinated universal) time. This is Greenwich Mean Time. If you do not live in the Greenwich Mean Time timezone then the RTC is off by a number of hours depending on your timezone.

To fix this we can create a function that:

  1. Saves the current datetime tuple (immutable) to a variable and casts the tuple into a list (mutable).
  2. Sets the appropriate element of the datetime list to the correct value.
  3. Sets the RTC's datetime to the new datetime stored in the variable.

The code below adds a new function called set_datetime_element which does the criteria listed above. I also added a dictionary called DATETIME_ELEMENTS which is used in the script to allow for human readable strings to be used when referring to the different indexes in the datetime tuple. Edit your main.py script to resemble the code below, changing the function call to suit your timezone.

import network, ntptime
from machine import RTC

# dictionary that maps string date names to indexes in the RTC's datetime tuple
DATETIME_ELEMENTS = {
    "year": 0,
    "month": 1,
    "day": 2,
    "day_of_week": 3,
    "hour": 4,
    "minute": 5,
    "second": 6,
    "millisecond": 7
}

def connect_to_wifi(wlan, ssid, password):
    if not wlan.isconnected():
        print("Connecting to network...")
        wlan.connect(ssid, password)
        while not wlan.isconnected():
            pass

# set an element of the RTC's datetime to a different value
def set_datetime_element(rtc, datetime_element, value):
    date = list(rtc.datetime())
    date[DATETIME_ELEMENTS[datetime_element]] = value
    rtc.datetime(date)


wlan = network.WLAN(network.STA_IF)
wlan.active(True)

connect_to_wifi(wlan, "ssid", "password")

rtc = RTC()
ntptime.settime()
print(rtc.datetime())

set_datetime_element(rtc, "hour", 8) # I call this to change the hour to 8am for me
print(rtc.datetime()) # print the updated RTC time

Save this updated main.py script to your NodeMCU and press the reset button to run it. You should see that the last printed datetime is now corrected to your timezone as you specified.


Conclusion

The ESP8266 NodeMCU's networking capabilities far exceed setting the RTC's time from a time server. In future guides we will get into more advanced networking.


Next guide: Introduction to API Calls with a NodeMCU and MicroPython

Comments (0)

Page 1 of 0

Go back to top

You need to be logged in to comment