I recently bought a NodeMCU. This is a small ESP8266 based card with built in WiFi, MicroUSB, and a Lua interpreter that can be used for developing IoT (Internet of Things) devices.
I had trouble getting it working initially, so I wanted to share how I fixed this on a Mac.
Install Mac drivers
If you’re not using a Mac, you can skip this part.
You plug the NodeMCU into the Mac via USB. The Mac won’t support this by default, and you need to install a driver. The driver you need to install is the Silcon Labs CP210x USB to UART Bridge.
Once installed, plug in the NodeMCU and check that the device /dev/tty.SLAB_USBtoUART
exists.
To connect to the NodeMCU, you’ll need some tools. To test, download CoolTerm. In Options, for Port select SLAB_USBtoUART, and for Baudrate select 115200.
If you are lucky you’ll get a prompt, if not you may need to build and install some new firmware.
If you do get a prompt type…
print "Hello";
… and Lua should echo “Hello” back to you.
Build and install the NodeMCU firmware
If you need to build new firmware, there is a very useful online site called NodeMCU-Build.com that I used to build the firmware with the right modules I wanted for my project.
Once you’ve build the firmware, you’ll need to install the Python esptool.py to flash the firmware to the NodeMCU.
git clone https://github.com/themadinventor/esptool.git cd esptool sudo python ./setup.py install
Check the flash size of your NodeMCU.
To flash the firmware hold down “FLASH” and press “RST” on the NodeMCU, then use the following command (remembering to disconnect CoolTerm first if connected)…
esptool.py --port /dev/tty.SLAB_USBtoUART write_flash -fm dio 0x00000 ~/Downloads/nodemcu-master-12-modules-2017-07-07-21-24-03-float.bin
As esptool.py runs, you should see something like this…
esptool.py v2.0.1 Connecting........_ Detecting chip type... ESP8266 Chip is ESP8266 Uploading stub... Running stub... Stub running... Configuring flash size... Auto-detected Flash size: 4MB Flash params set to 0x0240 Compressed 754992 bytes to 505060... Wrote 754992 bytes (505060 compressed) at 0x00000000 in 44.5 seconds (effective 135.6 kbit/s)... Hash of data verified. Leaving... Hard resetting...
Connect to it using CoolTerm, then press the “RST” button. You should see some messy characters, then something like following (depending on what you built into your firmware)…
NodeMCU custom build by frightanic.com .branch: master .commit: c8ac5cfb912ff206b03dd7c60ffbb2dafb83fe5e .SSL: true .modules: adc,bit,cron,crypto,encoder,file,gpio,http,i2c,net,node,ow,pcm,sjson,sntp,spi,struct,tmr,u8g,uart,websocket,wifi,tls build .built on: 2017-07-12 09:30 powered by Lua 5.1.4 on SDK 2.1.0(116b762) lua: cannot open init.lua >
Upload Lua code to the NodeMCU
The best way to get Lua code onto the NodeMCU is to use the Python luatool.
git clone https://github.com/4refr0nt/luatool cd luatool
To test we’ll upload a simple Lua script that will blink the NodeMCU’s onboard LED, save this as “blink.lua”.
LED_PIN = 0 gpio.mode(LED_PIN, gpio.OUTPUT) value = true tmr.alarm(0, 500, 1, function () gpio.write(LED_PIN, value and gpio.HIGH or gpio.LOW) value = not value end)
Upload it to the NodeMCU using the following command (making sure Coolterm is disconnected first)…
python luatool/luatool.py --port /dev/tty.SLAB_USBtoUART --src blink.lua --dest init.lua --dofile
You should see the following…
->file.open("init.lua", "w") -> ok ->file.close() -> ok ->file.remove("init.lua") -> ok ->file.open("init.lua", "w+") -> ok ->file.writeline([==[LED_PIN = 0]==]) -> ok ->file.writeline([==[]==]) -> ok ->file.writeline([==[gpio.mode(LED_PIN, gpio.OUTPUT)]==]) -> ok ->file.writeline([==[value = true]==]) -> ok ->file.writeline([==[]==]) -> ok ->file.writeline([==[tmr.alarm(0, 500, 1, function ()]==]) -> ok ->file.writeline([==[gpio.write(LED_PIN, value and gpio.HIGH or gpio.LOW)]==]) -> ok ->file.writeline([==[value = not value]==]) -> ok ->file.writeline([==[end)]==]) -> ok ->file.flush() -> ok ->file.close() -> ok ->dofile("init.lua") -> send without check --->>> All done <<<--
The onboard LED on the NodeMCU should now be blinking.
The NodeMCU executes the init.lua script by default, so when we upload we tell luatool to upload our blink.lua script as init.lua.