Some nodeMCU connection troubles

For a work project, I’m using a nodeMCU, which is an ESP8266 module flashed with a Lua interpreter (and put on a nice PCB with USB serial and stuff). By the way, ESPlorer is a really nice interface to the nodeMCU.

I started by following an Adafruit tutorial to get WiFi working, which was easy enough. Then I hit an issue where it would silently fail to complete HTTP requests. No obvious errors – it just wouldn’t work. The callback function to print the response wasn’t being called.

Here’s Adafruit’s code:

sk=net.createConnection(net.TCP, 0)
sk:on("receive", function(sck, c) print(c) end )
sk:connect(80,"207.58.139.247")
sk:send("GET /testwifi/index.html HTTP/1.1\r\nHost: www.adafruit.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")

Pretty simple – create a connection, set a receive callback, connect to an IP address and set a GET request.

The Adafruit tutorial also say that you can just use a domain name and let the module do a DNS lookup:

sk=net.createConnection(net.TCP, 0)
sk:on("receive", function(sck, c) print(c) end )
sk:connect(80,"www.adafruit.com")
sk:send("GET /testwifi/index.html HTTP/1.1\r\nHost: www.adafruit.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")

This worked for me with the Adafruit website, but when I tried to do the same thing with a different domain name, nothing came back.

After tearing my hair out for a while, the following concept finally struck a chord:

API calls are asynchronous. There is no waiting for them to complete. Application programming must wait for callbacks, not assume completion.

The connect() function is an API call. The Adafruit code shouldn’t just call send() straight afterwards – it has no gurantee that a connection has been made.

I added a seperate callback for the “connection” event and called send inside that:

to_send ="GET /testwifi/index.html HTTP/1.1\r\nHost: www.adafruit.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n"

sk=net.createConnection(net.TCP, 0)
sk:on("receive", function(sck, c) print(c) end )
sk:on("connection", function(sck, c)
    sck:send(to_send)
end)
sk:connect(80,"www.adafruit.com")

This worked just fine!

The actual issue is because when given a domain name, the ESP8266 has to do a DNS lookup. This takes time. If the send() method is called before the connection is made, it just fails.

So, this is a lesson. Wait for the callback from every API call with one attached, no matter how trivial.

Advertisements
This entry was posted in Computing, Electronics and tagged . Bookmark the permalink.

2 Responses to Some nodeMCU connection troubles

  1. Pingback: HTTP GET on the NodeMCU – PI and more

  2. Jofo says:

    I ran into a similar problem of not connecting to a local host because I left out sk:send(“GET..””) altogether. Your lesson to “wait for the callback from every API call with one attached, no matter how trivial” was well learned!
    When added in it worked. I just took the nHost http://www.adafruit bit out.

    sk=net.createConnection(net.TCP, 0)
    sk:on(“receive”, function(sck, c) print(c) end )
    sk:connect(8080,”xxx.xxx.x.xxx”)
    sk:send(“GET /testwifi/index.html HTTP/1.1\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n”)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s