An Introduction to the ESP8266
Disclaimer: Commands may vary for Windows, Lixux, and Mac machines.
Toolbox
esptool - Needed for uploading the initial firmware
NodeMCU-Tool - Needed for uploading source code
Firmware - Self-explanatory, the link points to the recommended cloud firmware builder for ease of use.
These were chosen because they work cross-platform for the most part. However, additional tools/options can be found here here.
Serial Port
If you already know what serial port the module is connected to, skip this step. Otherwise, after connecting the device to your machine, run the following command in a terminal window to find your serial port:
nodemcu-tool devices
Based on the results, the serial port my device is connected to will be COM3 (possibly ttyUSB0 or something similar on linux machines).
Firmware Upload
Assuming you have downloaded your firmware with any additional modules, run the code below to upload it to your microcontroller:
esptool.py --port COM3 write_flash -fm qio 0x00000 <nodemcu-firmware>.bin
Esptool, depending on your version, will enumerate all available serial ports until it finds a connected device. As such, specifying the serial port should not be necessary in later releases- in theory.
Testing the ESP8266
Lastly, copy and paste the following sample lua code into ESPlorer as a new file. Replace mySSID and myPassword with your own network credentials.
local SSID = "mySSID"
local PASSWORD = "myPassword"
function startup()
if file.open("init.lua") == nil then
print("init.lua deleted or renamed")
else
print("Running")
file.close("init.lua")
end
end
-- Define WiFi station event callbacks
wifi_connect_event = function(T)
print("Connection to AP("..T.SSID..") established!")
print("Waiting for IP address...")
if disconnect_ct ~= nil then disconnect_ct = nil end
end
wifi_got_ip_event = function(T)
-- Note: Having an IP address does not mean there is internet access!
-- Internet connectivity can be determined with net.dns.resolve().
print("Wifi connection is ready! IP address is: "..T.IP)
-- a simple http server
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
local response = {
"HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n",
"<html><body>Hello world, come here often?</body></html"
}
print(payload)
-- sends and removes the first element from the 'response' table
local function send(localSocket)
if #response > 0 then
localSocket:send(table.remove(response, 1))
else
localSocket:close()
response = nil
end
end
-- triggers the send() function again once the first chunk of data was sent
conn:on("sent", send)
send(conn)
-- conn:send(response)
end)
end)
-- print("Startup will resume momentarily, you have 3 seconds to abort.")
-- print("Waiting...")
tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
end
wifi_disconnect_event = function(T)
if T.reason == wifi.eventmon.reason.ASSOC_LEAVE then
--the station has disassociated from a previously connected AP
return
end
-- total_tries: how many times the station will attempt to connect to the AP. Should consider AP reboot duration.
local total_tries = 75
print("\nWiFi connection to AP("..T.SSID..") has failed!")
--There are many possible disconnect reasons, the following iterates through
--the list and returns the string corresponding to the disconnect reason.
for key,val in pairs(wifi.eventmon.reason) do
if val == T.reason then
print("Disconnect reason: "..val.."("..key..")")
break
end
end
if disconnect_ct == nil then
disconnect_ct = 1
else
disconnect_ct = disconnect_ct + 1
end
if disconnect_ct < total_tries then
print("Retrying connection...(attempt "..(disconnect_ct+1).." of "..total_tries..")")
else
wifi.sta.disconnect()
print("Aborting connection to AP!")
disconnect_ct = nil
end
end
-- Register WiFi Station event callbacks
wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, wifi_disconnect_event)
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config({ssid=SSID, pwd=PASSWORD})
If you aren't familiar with lua or nodecmu's devkit, don't worry, I wasn't either- a lot of it is still trial and error. But experience is the best teacher so don't let that stop you!
In short, the code above sets up a wifi station with our own custom event callbacks for when the device connects to the network specified, when it receives an ip address, and when it disconnects for whatever reason.
Once it receives an ip address, it sets up an http server where it will listen for any inbound connections on port 80 and return a simple message
Uploading Code
With our file saved as init.lua we can upload our code to the connected device by executing the following command:
nodemcu-tool upload --port=COM3 init.lua
We can also run the file with a terminal connected to the device with the following command:
nodemcu-tool terminal --port=COM3 --run init.lua
Note: You may have to hit the little reset button on the actual device if nodemcu-tool is unable to establish a connection.
Now, once it connects and gets and ip address go to http://ipaddress from a device on the same network to see if we can successfully connect to the device.

Success! :)
Conclusion
We did it team! From here can play with the code and use it as a baseline for your next project.
For example, I’m using it to interact with GPIO pins and communicate with other devices on the same network. I fried my first microcontroller trying to connect it to stepper motors so that may be the next guide to save someone else the frustration. Regardless, the possibilities are near endless with the available firmware modules. What are you building with yours?
