# **NodeMCU** # version 0.9.5 [![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) [![Download](https://img.shields.io/badge/download-~400k-orange.svg)](https://github.com/nodemcu/nodemcu-firmware/releases/latest) ###A lua based firmware for wifi-soc esp8266 Build on [ESP8266 sdk 0.9.5](http://bbs.espressif.com/viewtopic.php?f=5&t=154)
Lua core based on [eLua project](http://www.eluaproject.net/)
cjson based on [lua-cjson](https://github.com/mpx/lua-cjson)
File system based on [spiffs](https://github.com/pellepl/spiffs)
Open source development kit for NodeMCU [nodemcu-devkit](https://github.com/nodemcu/nodemcu-devkit)
Flash tool for NodeMCU [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher)
wiki: [NodeMCU wiki](https://github.com/nodemcu/nodemcu-firmware/wiki)
api: [NodeMCU api](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en)
home: [nodemcu.com](http://www.nodemcu.com)
bbs: [Chinese bbs](http://bbs.nodemcu.com)
docs: [NodeMCU docs](http://www.nodemcu.com/docs/)
Tencent QQ group: 309957875
# Summary - Easy to access wireless router - Based on Lua 5.1.4 (without *debug, os* module.) - Event-Drive programming preferred. - Build-in json, file, timer, pwm, i2c, spi, 1-wire, net, mqtt, coap, gpio, wifi, adc, uart and system api. - GPIO pin re-mapped, use the index to access gpio, i2c, pwm. - Both Integer(less memory usage) and Float version firmware provided. # To Do List (pull requests are very welcomed) - loadable c module - fix wifi smart connect - add spi module (done) - add mqtt module (done) - add coap module (done) - cross compiler (done) # Change log 2015-06-27
fixed ap/station-ap cannot connect to the device.
added wifi.ap.getconfig().
fixed net.dns.getdnsserver().
added new base64 lua example.
added node.bootreason() to inspect boot cause.
optimization of u8g.
# Change log 2015-06-25
move constants to ROM. Frees up 16k+ of RAM.
add dhtlib for DHT11/21/22/33/44, port from Arduino.
add 433MHz transmission.
add crypto library.
re-add ws2812.write().
add wifi.getchannel.
changed wifi_setip() to allow setting SoftAP gateway to 0.0.0.0.
added net.dns.setdnsserver and net.dns.getdnsserver.
add support for lm92 temperature sensor.
implement getStrWidth() and setFontLineSpacingFactor().
add -Os flag to release and debug builds.
changed output format of table that is output by wifi_scan_done.
added ability to set scan configuration to wifi.sta.getap.
added function wifi.sta.getconfig().
allow connecting to unsecured WiFi networks.
add setphymode and getphymode to wifi module.
add multicastJoin and multicastLeave to net module.
add Yeelink Modules.
2015-03-31
polish mqtt module, add queue for mqtt module.
add reconnect option to mqtt.connect api, :connect( host, port, secure, auto_reconnect, function(client) )
move node.readvdd33 to adc.readvdd33.
tools/esptool.py supported NodeMCU devkit automatic flash. [more change log](https://github.com/nodemcu/nodemcu-firmware/wiki)
##GPIO NEW TABLE ( Build 20141219 and later)
IO indexESP8266 pinIO indexESP8266 pin
0 [*]GPIO168GPIO15
1GPIO59GPIO3
2GPIO410GPIO1
3GPIO011GPIO9
4GPIO212GPIO10
5GPIO14
6GPIO12
7GPIO13
#### [*] D0(GPIO16) can only be used as gpio read/write. no interrupt supported. no pwm/i2c/ow supported. #Build option ####file ./app/include/user_modules.h ```c #define LUA_USE_BUILTIN_STRING // for string.xxx() #define LUA_USE_BUILTIN_TABLE // for table.xxx() #define LUA_USE_BUILTIN_COROUTINE // for coroutine.xxx() #define LUA_USE_BUILTIN_MATH // for math.xxx(), partially work // #define LUA_USE_BUILTIN_IO // for io.xxx(), partially work // #define LUA_USE_BUILTIN_OS // for os.xxx(), not work // #define LUA_USE_BUILTIN_DEBUG // for debug.xxx(), not work #define LUA_USE_MODULES #ifdef LUA_USE_MODULES #define LUA_USE_MODULES_NODE #define LUA_USE_MODULES_FILE #define LUA_USE_MODULES_GPIO #define LUA_USE_MODULES_WIFI #define LUA_USE_MODULES_NET #define LUA_USE_MODULES_PWM #define LUA_USE_MODULES_I2C #define LUA_USE_MODULES_SPI #define LUA_USE_MODULES_TMR #define LUA_USE_MODULES_ADC #define LUA_USE_MODULES_UART #define LUA_USE_MODULES_OW #define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_MQTT // #define LUA_USE_MODULES_COAP #define LUA_USE_MODULES_U8G #define LUA_USE_MODULES_WS2812 #define LUA_USE_MODULES_CJSON #endif /* LUA_USE_MODULES */ ``` #Online firmware custom build For many application, some modules are not used, remove them can free many memory.
Please try Marcel's [NodeMCU custom builds](http://frightanic.com/nodemcu-custom-build) cloud service and you can get your own firmware.
#Flash the firmware nodemcu_latest.bin: 0x00000
for most esp8266 modules, just pull GPIO0 down and restart.
You can use the [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) to burn the firmware. Or, if you build your own bin from source code.
0x00000.bin: 0x00000
0x10000.bin: 0x10000
*Better run file.format() after flash* #Connect the hardware in serial baudrate:9600 #Write Lua script to filesystem ####Esplorer Victor Brutskiy's [Esplorer](https://github.com/4refr0nt/ESPlorer) support most platforms such as Linux, Windows, Mac OS, etc. This software is opensource and can write lua/lc files to filesystem. ####NodeMCU Studio [NodeMCU Studio](https://github.com/nodemcu/nodemcu-studio-csharp) is written in C# and support Windows. This software is opensource and can write lua files to filesystem. #Start play ####Connect to your ap ```lua ip = wifi.sta.getip() print(ip) --nil wifi.setmode(wifi.STATION) wifi.sta.config("SSID","password") ip = wifi.sta.getip() print(ip) --192.168.18.110 ``` ####Manipulate hardware like a arduino ```lua pin = 1 gpio.mode(pin,gpio.OUTPUT) gpio.write(pin,gpio.HIGH) print(gpio.read(pin)) ``` ####Write network application in nodejs style ```lua -- A simple http client conn=net.createConnection(net.TCP, 0) conn:on("receive", function(conn, payload) print(payload) end ) conn:connect(80,"115.239.210.27") conn:send("GET / HTTP/1.1\r\nHost: www.baidu.com\r\n" .."Connection: keep-alive\r\nAccept: */*\r\n\r\n") ``` ####Or a simple http server ```lua -- A simple http server srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on("receive",function(conn,payload) print(payload) conn:send("

Hello, NodeMcu.

") end) conn:on("sent",function(conn) conn:close() end) end) ``` ####Connect to MQTT Broker ```lua -- init mqtt client with keepalive timer 120sec m = mqtt.Client("clientid", 120, "user", "password") -- setup Last Will and Testament (optional) -- Broker will publish a message with qos = 0, retain = 0, data = "offline" -- to topic "/lwt" if client don't send keepalive packet m:lwt("/lwt", "offline", 0, 0) m:on("connect", function(con) print ("connected") end) m:on("offline", function(con) print ("offline") end) -- on publish message receive event m:on("message", function(conn, topic, data) print(topic .. ":" ) if data ~= nil then print(data) end end) -- m:connect( host, port, secure, auto_reconnect, function(client) ) -- for secure: m:connect("192.168.11.118", 1880, 1, 0) -- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1) m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end) -- subscribe topic with qos = 0 m:subscribe("/topic",0, function(conn) print("subscribe success") end) -- or subscribe multiple topic (topic/0, qos = 0; topic/1, qos = 1; topic2 , qos = 2) -- m:subscribe({["topic/0"]=0,["topic/1"]=1,topic2=2}, function(conn) print("subscribe success") end) -- publish a message with data = hello, QoS = 0, retain = 0 m:publish("/topic","hello",0,0, function(conn) print("sent") end) m:close(); -- if auto-reconnect == 1, will disable auto-reconnect and then disconnect from host. -- you can call m:connect again ``` #### UDP client and server ```lua -- a udp server s=net.createServer(net.UDP) s:on("receive",function(s,c) print(c) end) s:listen(5683) -- a udp client cu=net.createConnection(net.UDP) cu:on("receive",function(cu,c) print(c) end) cu:connect(5683,"192.168.18.101") cu:send("hello") ``` ####Do something shining ```lua function led(r,g,b) pwm.setduty(1,r) pwm.setduty(2,g) pwm.setduty(3,b) end pwm.setup(1,500,512) pwm.setup(2,500,512) pwm.setup(3,500,512) pwm.start(1) pwm.start(2) pwm.start(3) led(512,0,0) -- red led(0,0,512) -- blue ``` ####And blink it ```lua lighton=0 tmr.alarm(1,1000,1,function() if lighton==0 then lighton=1 led(512,512,512) else lighton=0 led(0,0,0) end end) ``` ####If you want to run something when system started ```lua --init.lua will be excuted file.open("init.lua","w") file.writeline([[print("Hello, do this at the beginning.")]]) file.close() node.restart() -- this will restart the module. ``` ####With below code, you can telnet to your esp8266 now ```lua -- a simple telnet server s=net.createServer(net.TCP,180) s:listen(2323,function(c) function s_output(str) if(c~=nil) then c:send(str) end end node.output(s_output, 0) -- re-direct output to function s_ouput. c:on("receive",function(c,l) node.input(l) -- works like pcall(loadstring(l)) but support multiple separate line end) c:on("disconnection",function(c) node.output(nil) -- un-regist the redirect output function, output goes to serial end) print("Welcome to NodeMcu world.") end) ``` ####Use DS18B20 module extends your esp8266 ```lua -- read temperature with DS18B20 node.compile("ds18b20.lua") -- run this only once to compile and save to "ds18b20.lc" t=require("ds18b20") t.setup(9) addrs=t.addrs() -- Total DS18B20 numbers, assume it is 2 print(table.getn(addrs)) -- The first DS18B20 print(t.read(addrs[1],t.C)) print(t.read(addrs[1],t.F)) print(t.read(addrs[1],t.K)) -- The second DS18B20 print(t.read(addrs[2],t.C)) print(t.read(addrs[2],t.F)) print(t.read(addrs[2],t.K)) -- Just read print(t.read()) -- Just read as centigrade print(t.read(nil,t.C)) -- Don't forget to release it after use t = nil ds18b20 = nil package.loaded["ds18b20"]=nil ``` ####Operate a display via I2c with u8glib u8glib is a graphics library with support for many different displays. The integration in nodemcu is developed for SSD1306 based display attached via the I2C port. Further display types and SPI connectivity will be added in the future. U8glib v1.18.1 #####I2C connection Hook up SDA and SCL to any free GPIOs. Eg. `lua_examples/u8glib/graphics_test.lua` expects SDA=5 (GPIO14) and SCL=6 (GPIO12). They are used to set up nodemcu's I2C driver before accessing the display: ```lua sda = 5 scl = 6 i2c.setup(0, sda, scl, i2c.SLOW) ``` #####SPI connection The HSPI module is used, so certain pins are fixed: * HSPI CLK = GPIO14 * HSPI MOSI = GPIO13 * HSPI MISO = GPIO12 (not used) All other pins can be assigned to any available GPIO: * CS * D/C * RES (optional for some displays) Also refer to the initialization sequence eg in `lua_examples/u8glib/graphics_test.lua`: ```lua spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) ``` #####Library usage The Lua bindings for this library closely follow u8glib's object oriented C++ API. Based on the u8g class, you create an object for your display type. SSD1306 via I2C: ```lua sla = 0x3c disp = u8g.ssd1306_128x64_i2c(sla) ``` SSD1306 via SPI: ```lua cs = 8 -- GPIO15, pull-down 10k to GND dc = 4 -- GPIO2 res = 0 -- GPIO16, RES is optional YMMV disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res) ``` This object provides all of u8glib's methods to control the display. Again, refer to `lua_examples/u8glib/graphics_test.lua` to get an impression how this is achieved with Lua code. Visit the [u8glib homepage](https://github.com/olikraus/u8glib) for technical details. #####Fonts u8glib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in `app/include/u8g_config.h` and recompile. Simply add the desired fonts to the font table: ```c #define U8G_FONT_TABLE \ U8G_FONT_TABLE_ENTRY(font_6x10) \ U8G_FONT_TABLE_ENTRY(font_chikita) ``` They'll be available as `u8g.` in Lua. #####Bitmaps Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. See `lua_examples/u8glib/u8g_bitmaps.lua`. In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader). #####Unimplemented functions - [ ] Cursor handling - [ ] disableCursor() - [ ] enableCursor() - [ ] setCursorColor() - [ ] setCursorFont() - [ ] setCursorPos() - [ ] setCursorStyle() - [ ] General functions - [ ] setContrast() - [ ] setPrintPos() - [ ] setHardwareBackup() - [ ] setRGB() - [ ] setDefaultMidColor() ####Control a WS2812 based light strip ```lua -- set the color of one LED on GPIO2 to red ws2812.writergb(4, string.char(255, 0, 0)) -- set the color of 10 LEDs on GPIO0 to blue ws2812.writergb(3, string.char(0, 0, 255):rep(10)) -- first LED green, second LED white ws2812.writergb(4, string.char(0, 255, 0, 255, 255, 255)) ``` ####coap client and server ```lua -- use copper addon for firefox cs=coap.Server() cs:listen(5683) myvar=1 cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1 -- function should tack one string, return one string. function myfun(payload) print("myfun called") respond = "hello" return respond end cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun cc = coap.Client() cc:get(coap.CON, "coap://192.168.18.100:5683/.well-known/core") cc:post(coap.NON, "coap://192.168.18.100:5683/", "Hello") ``` ####cjson ```lua -- Translate Lua value to/from JSON -- text = cjson.encode(value) -- value = cjson.decode(text) json_text = '[ true, { "foo": "bar" } ]' value = cjson.decode(json_text) -- Returns: { true, { foo = "bar" } } value = { true, { foo = "bar" } } json_text = cjson.encode(value) -- Returns: '[true,{"foo":"bar"}]' ```